在下面的问题中,我试图编写一个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
答案 0 :(得分: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
,不仅不必嵌套循环,而且由于不需要查找数字的每个排列,因此速度也要快得多。
优化点#2:in a
是数组时,a
可能会非常慢,因为它必须扫描整个列表。如果您将a
设为一组,则成员资格测试几乎是即时的。)
答案 1 :(得分:1)
最重要的是,如果您想拥有该限制,则需要将其编码到循环范围内。只需将前一个循环的变量用作起始值,即可获得所需的限制。
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分钟以上。