В-третьих, нахождение 23 наборов значений x y z удовлетворяет условию x ^ 3 + y ^ 3 = 1 + z ^ 3 - PullRequest
3 голосов
/ 02 августа 2011

Теперь я завершил поиск 23 наборов значений x y z, удовлетворяющих условию x ^ 3 + y ^ 3 = 1 + z ^ 3 & x

int setsFound = 0;
System.out.println("The first 23 sets ordered by increasing x.");
for (long x = 1; setsFound < 23; x++) {
  for (long z = x + 1; z<x*x; z++) {
    long y = (long) Math.pow((1 + z*z*z - x*x*x), 1f/3f);
    if (x * x * x == 1 + z * z * z - y * y *y && x<y && y<z) {
      setsFound++;
      System.out.println("X: " + x + ", Y: " + y + ", Z: " + z);
    }
  }
}

Но код, который я имею, очень неэффективен, может кто-нибудь помочь мне исправить это, пожалуйста?

Ответы [ 2 ]

2 голосов
/ 02 августа 2011

Если вы начнете другим путем, с X X ^ 3 + Y ^ 3 + 1, вы можете перейти к следующему значению Y из-за вогнутости кубической функции.

Эта реализация в C # работает довольно быстро на ноутбуке:

        UInt64 setsFound = 0;
        UInt64 xlim = 10000;
        UInt64 ylim = 1000000;
        UInt64 zlim = 10000000;

        //int ctr = 0;
        Console.WriteLine("The first 23 sets ordered by increasing x.");

        Parallel.For(1, (long)xlim, new ParallelOptions { MaxDegreeOfParallelism = 4 }, i =>
        //for (UInt64 i = 0; i < xlim; i++)
        {
            UInt64 x = (UInt64)i;
            UInt64 xCu = x * x * x;
            int zFails = 0;
            for (UInt64 y = x + 1; y < ylim; y++)
            {
                UInt64 yCu = y * y * y;
                zFails = 0;
                for (UInt64 z = y + 1; z < zlim & zFails < 1; z++)
                {
                    UInt64 zCu = z * z * z;
                    if (xCu + yCu - zCu == 1)
                    {
                        Console.WriteLine(String.Format("{0}: {1}^3 + {2}^3 - {3}^3 = 1", setsFound, x, y, z));
                        setsFound++;
                    }
                    else if (zCu > xCu + yCu - 1)
                    {
                        zFails++;
                    }
                }
            }
        }
        );

Очевидно, вы можете убрать распараллеливание. Кроме того, вот первые 19 элементов в этом наборе (компьютер все еще работает, последние 4 я постараюсь опубликовать позже):

выход http://desmond.yfrog.com/Himg640/scaled.php?tn=0&server=640&filename=8qzi.png&xsize=640&ysize=640

2 голосов
/ 02 августа 2011

Вот рабочий код:

  int setsFound = 0;
  System.out.println("The first 23 sets ordered by increasing x.");
  for (long z = 1; setsFound < 23; z++) {
     for (long y = z - 1; y > 0; y--) {
        long x = (long) Math.pow((1 + z * z * z - y * y * y), 1f/3f);
        if(y <= x) break;
        if (x * x * x == 1 + z * z * z - y * y *y) {
           setsFound++;
           System.out.println("X: " + x + ", Y: " + y + ", Z: " + z);
        }
     }
  }

Пара проблем в старом:

  1. 1/3 == 0 (потому что это целочисленное деление) // использовать 1f / 3f
  2. x и z поменялись местами - вы хотите z> x, а не наоборот
  3. (длинный) Math.pow (4 * 4 * 4, 1.0 / 3) == (длинный) 3.9999999999999996 == 3 // использовать раунд
...