python脚本,对四个五次方进行暴力搜索,四个五次方的总和为五分之一p

2024-09-30 22:16:36 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的问题中,我试图编写一个python脚本,对四个五次方进行暴力搜索,四个五次方的总和等于五次方。因此,我试图找到数字a1,a2,a3,a4,a5,这样a1^5+a2^5+a3^5+a4^5=a5^5

此搜索的范围是Nmin=20和Nmax=200。另外,Nmin<;=a1<;a2<;a3<;a4<;a5<;=Nmax。所以每个数都必须小于之前的数,并且必须在20到200之间。你知道吗

import numpy as np

b  = np.arange(20,201)
a = b**5

for x in b:
    for y in b:
        for z in b:
            for w in b:

                lambdas=[x,y,z,w]

                if sum(np.array(lambdas)**5) in a:
                    print((x,y,z,w))

其输出如下:

(20, 64, 128, 192)
(20, 64, 192, 128)
(20, 128, 64, 192)
(20, 128, 128, 128)
(20, 128, 192, 64)
(20, 192, 64, 128)
(20, 192, 128, 64)

所以这是错误的输出,我应该得到以下结果:

(27, 84, 110, 133)

似乎没有考虑a1<;a2<;a3<;a4<;a5。我正在寻找一些帮助修复此代码!不是为了提高效率,跑得更快,只是为了得到正确的答案


Tags: inlt脚本a2fora1npa3
2条回答

你看过a吗?可能你看到的是这样的情况:

In [3]: a
Out[3]: 
array([    3200000,     4084101,     5153632,     6436343,     7962624,
           9765625,    11881376,    14348907,    17210368,    20511149,
          24300000,    28629151,    33554432,    39135393,    45435424,
          52521875,    60466176,    69343957,    79235168,    90224199,
         102400000,   115856201,   130691232,   147008443,   164916224,
         184528125,   205962976,   229345007,   254803968,   282475249,
         312500000,   345025251,   380204032,   418195493,   459165024,
         503284375,   550731776,   601692057,   656356768,   714924299,
         777600000,   844596301,   916132832,   992436543,  1073741824,
        1160290625,  1252332576,  1350125107,  1453933568,  1564031349,
        1680700000,  1804229351,  1934917632,  2073071593, -2075960672,
       -1921920421, -1759441920, -1588183139, -1407792928, -1217910897,
       -1018167296,  -808182895,  -587568864,  -355926653,  -112847872,
         142085829,   409302880,   689241911,   982351872,  1289092153,
        1609932704,  1945354155, -1999119360, -1633050899, -1250894368,
        -852125217,  -436207616,    -2594335,   449273376,   919965907,
        1410065408,  1920165909, -1844093856, -1292161145,  -718372864,
        -122086263,   497353888,  1140615419,  1808378880, -1793629635,
       -1074769184,  -329287633,   443547648,  1244482609,  2074276640,
       -1361264605,  -471419904,   449643877,  1402741088, -1906267177,
        -886603776,   167620825,  1257277856, -1911714229,  -748520448,
         452807053,  1693198304, -1321368961,           0,  1363313281,
       -1525405664,   -75216013,  1419936768, -1333877067,   254330464,
        1890661415,  -718766080,  1017084201, -1490604384,   349237147,
       -2052174848,  -103738147,  1900764384,  -332433201,  1787822080,
        -327168815,  1913781536,   -77991229, -2006232064,   425331717,
       -1371911328,  1193314423,  -467566592, -2058209927,   717747104,
        -728216341, -2099700736,   899712045,  -318443040, -1457710305,
        1778384896,   801434401,   -92048864,  -900499949, -1622334464,
        2039018837,  1495248992,  1042966727,   683835392,   419538377,
         251779232,   182281787,   212790272,   345069437,   580904672,
         922102127,  1370488832,  1927912817, -1698724064,  -917596829,
         -21761024,   990716581,  2121790816,  -921529065,   452689920,
        1951500825,  -718021216,  1036123019, -1373914112,   643911373,
       -1498203168,   791831487, -1073741824,  1497211841,   -83018720,
       -1517219661,  1491846144,   356537333,  -625862048, -1453011609,
       -2122547200], dtype=int32)

这里可以看到负数,这是因为int32的类型不够大,无法处理所有数字的五次方:

In [4]: np.iinfo(np.int32)
Out[4]: iinfo(min=-2147483648, max=2147483647, dtype=int32)

但是

In [104]: np.iinfo(np.int64)
Out[104]: iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64)

这就足够了。你知道吗

所以,如果我换成

b = np.arange(20,201, dtype=np.int64)

以及

np.array(lambdas, dtype=np.int64)

然后我得到

(27, 84, 110, 133)

一如预期。你知道吗

(优化点#1:如果使用itertools.combinations,不仅不必嵌套循环,而且速度会快得多,因为不会查找数字的每个排列。你知道吗

a是数组时,优化点#2:in a可能非常慢,因为它必须扫描整个列表。如果您将a设为一个集合,那么成员资格测试几乎是即时的。)

最重要的是,如果您想拥有这个限制,您需要将它编码到您的循环范围中。只需使用前一个循环的变量作为起始值,就可以得到所需的限制。你知道吗

import numpy as np

lower = 20
upper = 201
b = np.arange(lower, upper)

a = b**5

for x in b:
    for y in np.arange(x, upper):
        for z in np.arange(y, upper):
            for w in np.arange(z, upper):

                lambdas=[x,y,z,w]
                if sum(np.array(lambdas)**5) in a:

                    print((x,y,z,w))

输出:

(27, 84, 110, 133)

我不知道你是怎么运行上一个循环来得到你发布的答案的。你知道吗

你为什么要用numpy作为你的控件?这似乎增加了一层只会减慢处理速度的软件。相反,只需将其编码为“普通”Python数学。另外,使用set检查总和,而不是列表。对集合进行散列也会加快您多次执行的一次检查。你知道吗

lower = 20
upper = 201
b = range(lower, upper)

a = {i**5 for i in b}

for x in b:
    for y in np.arange(x, upper):
        for z in np.arange(y, upper):
            for w in np.arange(z, upper):
                if x**5 + y**5 + z**5 + w**5 in a:
                    print((x,y,z,w))

这得到了正确的答案,并在20秒内完成;您的原始版本(一旦我更正了缩进)花了3分钟。你知道吗

相关问题 更多 >