这不如我预期的好,但我花了太多时间在这上面,不能不分享一下
我的想法是通过将大小为10的子集分成2个来将问题从O(n^10)降至O(n^5)
首先,计算所有大小为5的子集,然后按它们的模1余数(使得总和在0到1之间)对它们进行排序
然后一个答案包括添加两个大小为5的子集,使得:
- 这些子集不相交
- 总和要么是
<e
,要么是>1-e且<1+e
,要么是>2-e
,其中e
在您的情况下为10^-12
如果您聪明地迭代大小为5的子集,则这3个检查中的每个都非常便宜(实际上,这就是将O(n^10)变为O(n^5)的部分)
所以是的,这个解决方案是O(n^5)。问题在于我的解决方案:
- 这是用Python编写的,但Python并不是最快的语言
- 仍然需要计算所有大小为5的组合,“从600个中选择5个”是无法处理的(共有637262850120种组合)
编辑:我只是随机抽取大小为40的大列表的子集,并测试所有组合。如果不起作用,我会再次随机抽取一个新的子集并重复此过程。这可以通过多线程来改进。
在20分钟后找到了step==44
的输出结果:
l = [0.06225774829854913, 0.21267040355189515, 0.21954445729288707, 0.21954445729288707, 0.24621125123532117, 0.24621125123532117, 0.36931687685298087, 0.4017542509913792, 0.41421356237309515, 0.41640786499873883, 0.6619037896906015]
>>> sum(l) + 0.529964086141668
3.999999999955324
注意那个跳过前43步的黑客攻击,如果你想进行真正的计算,请将其注释掉。
from math import pow
from itertools import combinations
import itertools
import random
import time
random.seed(1)
listLength = 40
halfsize = 5
halfsize2 = 6
x = 0.529964086141668
epsilon = pow(10,-10)
items = [0.9705627484771391, 0.2788205960997061, 0.620499351813308, 0.0, 0.4222051018559565, 0.892443989449804, 0.41640786499873883, 0.0, 0.6491106406735181, 0.36931687685298087, 0.16552506059643868, 0.04159457879229578, 0.0, 0.04159457879229578, 0.16552506059643868, 0.36931687685298087, 0.6491106406735181, 0.0, 0.41640786499873883, 0.892443989449804, 0.4222051018559565, 0.0, 0.620499351813308, 0.2788205960997061, 0.9705627484771391, 0.2788205960997061, 0.556349186104045, 0.866068747318506, 0.21267040355189515, 0.6014705087354439, 0.038404810405298306, 0.5299640861416677, 0.08304597359457233, 0.7046999107196257, 0.4017542509913792, 0.18033988749894903, 0.045361017187261155, 0.0, 0.045361017187261155, 0.18033988749894903, 0.4017542509913792, 0.7046999107196257, 0.08304597359457233, 0.5299640861416677, 0.038404810405298306, 0.6014705087354439, 0.21267040355189515, 0.866068747318506, 0.556349186104045, 0.2788205960997061, 0.620499351813308, 0.866068747318506, 0.142135623730951, 0.45362404707370985, 0.8062484748656971, 0.20655561573370207, 0.6619037896906015, 0.18033988749894903, 0.7703296142690075, 0.4403065089105507, 0.19803902718556898, 0.049875621120889946, 0.0, 0.049875621120889946, 0.19803902718556898, 0.4403065089105507, 0.7703296142690075, 0.18033988749894903, 0.6619037896906015, 0.20655561573370207, 0.8062484748656971, 0.45362404707370985, 0.142135623730951, 0.866068747318506, 0.620499351813308, 0.0, 0.21267040355189515, 0.45362404707370985, 0.7279220613578552, 0.04159457879229578, 0.4017542509913792, 0.8166538263919687, 0.2956301409870008, 0.8488578017961039, 0.4868329805051381, 0.21954445729288707, 0.0553851381374173, 0.0, 0.0553851381374173, 0.21954445729288707, 0.4868329805051381, 0.8488578017961039, 0.2956301409870008, 0.8166538263919687, 0.4017542509913792, 0.04159457879229578, 0.7279220613578552, 0.45362404707370985, 0.21267040355189515, 0.0, 0.4222051018559565, 0.6014705087354439, 0.8062484748656971, 0.04159457879229578, 0.31370849898476116, 0.63014581273465, 0.0, 0.43398113205660316, 0.9442719099991592, 0.5440037453175304, 0.24621125123532117, 0.06225774829854913, 0.0, 0.06225774829854913, 0.24621125123532117, 0.5440037453175304, 0.9442719099991592, 0.43398113205660316, 0.0, 0.63014581273465, 0.31370849898476116, 0.04159457879229578, 0.8062484748656971, 0.6014705087354439, 0.4222051018559565, 0.892443989449804, 0.038404810405298306, 0.20655561573370207, 0.4017542509913792, 0.63014581273465, 0.8994949366116654, 0.21954445729288707, 0.6023252670426267, 0.06225774829854913, 0.6157731058639087, 0.28010988928051805, 0.0710678118654755, 0.0, 0.0710678118654755, 0.28010988928051805, 0.6157731058639087, 0.06225774829854913, 0.6023252670426267, 0.21954445729288707, 0.8994949366116654, 0.63014581273465, 0.4017542509913792, 0.20655561573370207, 0.038404810405298306, 0.892443989449804, 0.41640786499873883, 0.5299640861416677, 0.6619037896906015, 0.8166538263919687, 0.0, 0.21954445729288707, 0.48528137423856954, 0.810249675906654, 0.21110255092797825, 0.7082039324993694, 0.32455532033675905, 0.08276253029821934, 0.0, 0.08276253029821934, 0.32455532033675905, 0.7082039324993694, 0.21110255092797825, 0.810249675906654, 0.48528137423856954, 0.21954445729288707, 0.0, 0.8166538263919687, 0.6619037896906015, 0.5299640861416677, 0.41640786499873883, 0.0, 0.08304597359457233, 0.18033988749894903, 0.2956301409870008, 0.43398113205660316, 0.6023252670426267, 0.810249675906654, 0.0710678118654755, 0.40312423743284853, 0.8309518948453007, 0.38516480713450374, 0.09901951359278449, 0.0, 0.09901951359278449, 0.38516480713450374, 0.8309518948453007, 0.40312423743284853, 0.0710678118654755, 0.810249675906654, 0.6023252670426267, 0.43398113205660316, 0.2956301409870008, 0.18033988749894903, 0.08304597359457233, 0.0, 0.6491106406735181, 0.7046999107196257, 0.7703296142690075, 0.8488578017961039, 0.9442719099991592, 0.06225774829854913, 0.21110255092797825, 0.40312423743284853, 0.6568542494923806, 0.0, 0.4721359549995796, 0.12310562561766059, 0.0, 0.12310562561766059, 0.4721359549995796, 0.0, 0.6568542494923806, 0.40312423743284853, 0.21110255092797825, 0.06225774829854913, 0.9442719099991592, 0.8488578017961039, 0.7703296142690075, 0.7046999107196257, 0.6491106406735181, 0.36931687685298087, 0.4017542509913792, 0.4403065089105507, 0.4868329805051381, 0.5440037453175304, 0.6157731058639087, 0.7082039324993694, 0.8309518948453007, 0.0, 0.24264068711928477, 0.6055512754639891, 0.16227766016837952, 0.0, 0.16227766016837952, 0.6055512754639891, 0.24264068711928477, 0.0, 0.8309518948453007, 0.7082039324993694, 0.6157731058639087, 0.5440037453175304, 0.4868329805051381, 0.4403065089105507, 0.4017542509913792, 0.36931687685298087, 0.16552506059643868, 0.18033988749894903, 0.19803902718556898, 0.21954445729288707, 0.24621125123532117, 0.28010988928051805, 0.32455532033675905, 0.38516480713450374, 0.4721359549995796, 0.6055512754639891, 0.8284271247461903, 0.2360679774997898, 0.0, 0.2360679774997898, 0.8284271247461903, 0.6055512754639891, 0.4721359549995796, 0.38516480713450374, 0.32455532033675905, 0.28010988928051805, 0.24621125123532117, 0.21954445729288707, 0.19803902718556898, 0.18033988749894903, 0.16552506059643868, 0.04159457879229578, 0.045361017187261155, 0.049875621120889946, 0.0553851381374173, 0.06225774829854913, 0.0710678118654755, 0.08276253029821934, 0.09901951359278449, 0.12310562561766059, 0.16227766016837952, 0.2360679774997898, 0.41421356237309515, 0.0, 0.41421356237309515, 0.2360679774997898, 0.16227766016837952, 0.12310562561766059, 0.09901951359278449, 0.08276253029821934, 0.0710678118654755, 0.06225774829854913, 0.0553851381374173, 0.049875621120889946, 0.045361017187261155, 0.04159457879229578, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04159457879229578, 0.045361017187261155, 0.049875621120889946, 0.0553851381374173, 0.06225774829854913, 0.0710678118654755, 0.08276253029821934, 0.09901951359278449, 0.12310562561766059, 0.16227766016837952, 0.2360679774997898, 0.41421356237309515, 0.0, 0.41421356237309515, 0.2360679774997898, 0.16227766016837952, 0.12310562561766059, 0.09901951359278449, 0.08276253029821934, 0.0710678118654755, 0.06225774829854913, 0.0553851381374173, 0.049875621120889946, 0.045361017187261155, 0.04159457879229578, 0.16552506059643868, 0.18033988749894903, 0.19803902718556898, 0.21954445729288707, 0.24621125123532117, 0.28010988928051805, 0.32455532033675905, 0.38516480713450374, 0.4721359549995796, 0.6055512754639891, 0.8284271247461903, 0.2360679774997898, 0.0, 0.2360679774997898, 0.8284271247461903, 0.6055512754639891, 0.4721359549995796, 0.38516480713450374, 0.32455532033675905, 0.28010988928051805, 0.24621125123532117, 0.21954445729288707, 0.19803902718556898, 0.18033988749894903, 0.16552506059643868, 0.36931687685298087, 0.4017542509913792, 0.4403065089105507, 0.4868329805051381, 0.5440037453175304, 0.6157731058639087, 0.7082039324993694, 0.8309518948453007, 0.0, 0.24264068711928477, 0.6055512754639891, 0.16227766016837952, 0.0, 0.16227766016837952, 0.6055512754639891, 0.24264068711928477, 0.0, 0.8309518948453007, 0.7082039324993694, 0.6157731058639087, 0.5440037453175304, 0.4868329805051381, 0.4403065089105507, 0.4017542509913792, 0.36931687685298087, 0.6491106406735181, 0.7046999107196257, 0.7703296142690075, 0.8488578017961039, 0.9442719099991592, 0.06225774829854913, 0.21110255092797825, 0.40312423743284853, 0.6568542494923806, 0.0, 0.4721359549995796, 0.12310562561766059, 0.0, 0.12310562561766059, 0.4721359549995796, 0.0, 0.6568542494923806, 0.40312423743284853, 0.21110255092797825, 0.06225774829854913, 0.9442719099991592, 0.8488578017961039, 0.7703296142690075, 0.7046999107196257, 0.6491106406735181, 0.0, 0.08304597359457233, 0.18033988749894903, 0.2956301409870008, 0.43398113205660316, 0.6023252670426267, 0.810249675906654, 0.0710678118654755, 0.40312423743284853, 0.8309518948453007, 0.38516480713450374, 0.09901951359278449, 0.0, 0.09901951359278449, 0.38516480713450374, 0.8309518948453007, 0.40312423743284853, 0.0710678118654755, 0.810249675906654, 0.6023252670426267, 0.43398113205660316, 0.2956301409870008, 0.18033988749894903, 0.08304597359457233, 0.0, 0.41640786499873883, 0.5299640861416677, 0.6619037896906015, 0.8166538263919687, 0.0, 0.21954445729288707, 0.48528137423856954, 0.810249675906654, 0.21110255092797825, 0.7082039324993694, 0.32455532033675905, 0.08276253029821934, 0.0, 0.08276253029821934, 0.32455532033675905, 0.7082039324993694, 0.21110255092797825, 0.810249675906654, 0.48528137423856954, 0.21954445729288707, 0.0, 0.8166538263919687, 0.6619037896906015, 0.41640786499873883, 0.892443989449804, 0.038404810405298306, 0.20655561573370207, 0.4017542509913792, 0.63014581273465, 0.8994949366116654, 0.21954445729288707, 0.6023252670426267, 0.06225774829854913, 0.6157731058639087, 0.28010988928051805, 0.0710678118654755, 0.0, 0.0710678118654755, 0.28010988928051805, 0.6157731058639087, 0.06225774829854913, 0.6023252670426267, 0.21954445729288707, 0.8994949366116654, 0.63014581273465, 0.4017542509913792, 0.20655561573370207, 0.038404810405298306, 0.892443989449804, 0.4222051018559565, 0.6014705087354439, 0.8062484748656971, 0.04159457879229578, 0.31370849898476116, 0.63014581273465, 0.0, 0.43398113205660316, 0.9442719099991592, 0.5440037453175304, 0.24621125123532117, 0.06225774829854913, 0.0, 0.06225774829854913, 0.24621125123532117, 0.5440037453175304, 0.9442719099991592, 0.43398113205660316, 0.0, 0.63014581273465, 0.31370849898476116, 0.04159457879229578, 0.8062484748656971, 0.6014705087354439, 0.4222051018559565, 0.0, 0.21267040355189515, 0.45362404707370985, 0.7279220613578552, 0.04159457879229578, 0.4017542509913792, 0.8166538263919687, 0.2956301409870008, 0.8488578017961039, 0.4868329805051381, 0.21954445729288707, 0.0553851381374173, 0.0, 0.0553851381374173, 0.21954445729288707, 0.4868329805051381, 0.8488578017961039, 0.2956301409870008, 0.8166538263919687, 0.4017542509913792, 0.04159457879229578, 0.7279220613578552, 0.45362404707370985, 0.21267040355189515, 0.0, 0.620499351813308, 0.866068747318506, 0.142135623730951, 0.45362404707370985, 0.8062484748656971, 0.20655561573370207, 0.6619037896906015, 0.18033988749894903, 0.7703296142690075, 0.4403065089105507, 0.19803902718556898, 0.049875621120889946, 0.0, 0.049875621120889946, 0.19803902718556898, 0.4403065089105507, 0.7703296142690075, 0.18033988749894903, 0.6619037896906015, 0.20655561573370207, 0.8062484748656971, 0.45362404707370985, 0.142135623730951, 0.866068747318506, 0.620499351813308, 0.2788205960997061, 0.556349186104045, 0.866068747318506, 0.21267040355189515, 0.6014705087354439, 0.038404810405298306, 0.5299640861416677, 0.08304597359457233, 0.7046999107196257, 0.4017542509913792, 0.18033988749894903, 0.045361017187261155, 0.0, 0.045361017187261155, 0.18033988749894903, 0.4017542509913792, 0.7046999107196257, 0.08304597359457233, 0.5299640861416677, 0.038404810405298306, 0.6014705087354439, 0.21267040355189515, 0.866068747318506, 0.556349186104045, 0.2788205960997061, 0.9705627484771391, 0.2788205960997061, 0.620499351813308, 0.0, 0.4222051018559565, 0.892443989449804, 0.41640786499873883, 0.0, 0.6491106406735181, 0.36931687685298087, 0.16552506059643868, 0.04159457879229578, 0.0, 0.04159457879229578, 0.16552506059643868, 0.36931687685298087, 0.6491106406735181, 0.0, 0.41640786499873883, 0.892443989449804, 0.4222051018559565, 0.0, 0.620499351813308, 0.2788205960997061, 0.9705627484771391]
items = sorted(items)
itemSet = sorted(list(set(items)))
def mySum(s):
return (sum([myList[i] for i in s]))%1
def mySum2(s):
return (sum([myList[i] for i in s]) + x)%1
start = time.time()
for step in range(1, 1000000):
myList = random.sample(items, listLength)
if(step<44):
continue
print("Step %s"%(step))
myList = sorted(myList)
listHalfIndices = [i for i in combinations(range(len(myList)),halfsize)]
listHalfIndices1 = sorted(listHalfIndices, key = mySum)
#print(listHalfIndices)
#print([mySum(s) for s in listHalfIndices])
listHalfIndices2 = [i for i in combinations(range(len(myList)),halfsize2)]
listHalfIndices2 = sorted(listHalfIndices2, key = mySum2)
#print(listHalfIndices2)
#print([mySum2(s) for s in listHalfIndices2])
"""
# SKIP THIS as I heuristically noted that it was pretty useless
# First answer if the sum of the first and second list is smaller than epsilon
print("ANSWER TYPE 1")
#print([mySum(s) for s in listHalfIndices1[0:10]])
#print([mySum2(s) for s in listHalfIndices2[0:10]])
listLowIndices1 = [s for s in listHalfIndices1 if mySum(s) <= epsilon]
#print(listLowIndices1)
#print([mySum(s) for s in listLowIndices1])
listLowIndices2 = [s for s in listHalfIndices2 if mySum2(s) <= epsilon]
#print(listLowIndices2)
#print([mySum2(s) for s in listLowIndices2])
combinationOfIndices1 = [list(set(sum(i, ()))) for i in itertools.chain(itertools.product(listLowIndices1, listLowIndices2))]
#print(combinationOfIndices1)
#print([mySum2(s) for s in combinationOfIndices1])
answer1 = [i for i in combinationOfIndices1 if len(i) == (2*halfsize) and mySum2(i)<=epsilon]
if(len(answer1) > 0):
print (answer1)
print([mySum2(s) for s in answer1])
break
# Second answer if the sum of the first and second list is larger than 2-epsilon
print("ANSWER TYPE 2")
#print([mySum(s) for s in listHalfIndices1[-10:-1]])
#print([mySum2(s) for s in listHalfIndices2[-10:-1]])
listHighIndices1 = [s for s in listHalfIndices1 if mySum(s) >= 1-epsilon]
#print(listHighIndices1)
listHighIndices2 = [s for s in listHalfIndices2 if mySum2(s) >= 1-epsilon]
#print(listHighIndices2)
combinationOfIndices2 = [list(set(sum(i, ()))) for i in itertools.chain(itertools.product(listHighIndices1, listHighIndices2))]
#print(combinationOfIndices2)
#print([mySum2(s) for s in combinationOfIndices2])
answer2 = [i for i in combinationOfIndices2 if len(i) == (2*halfsize) and mySum2(i)>=1-epsilon]
if(len(answer2) > 0):
print (answer2)
print([mySum2(s) for s in answer2])
break
"""
# Third answer if the sum of the first and second list is between 1-epsilon and 1+epsilon
#print("ANSWER TYPE 3")
i = 0
j = len(listHalfIndices2) - 1
answer3 = None
print("Answer of type 3 will explore at most %s combinations "%(2*len(listHalfIndices2)))
for k in range(2*len(listHalfIndices2)):
if(k%1000000 == 0 and k>0):
print(k)
setOfIndices = list(set(listHalfIndices1[i] + listHalfIndices2[j]))
#print(setOfIndices)
currentSum = mySum(listHalfIndices1[i]) + mySum2(listHalfIndices2[j])
#print(currentSum)
if(currentSum < 1-epsilon):
i = i+1
if(i>=len(listHalfIndices1)):
break
#print("i++")
else:
j = j-1
if(j<0):
break
#print("j--")
if(len(setOfIndices) < (halfsize+halfsize2)):
#print("skipping")
continue
if(currentSum >= 1-epsilon and currentSum <= 1+epsilon):
print("Found smart combination with sum : s=%s"%(currentSum))
print(sorted([myList[i] for i in setOfIndices]))
answer3 = setOfIndices
break
if answer3 is not None:
break
end = time.time()
print("Time elapsed %s"%(end-start))
x/10
来完全消除问题中的x
。 这样,只需要知道如何解决“从集合中找到10个数字,使它们的总和几乎为整数”即可。 - avysk[0.6491106406735181, 0.8284271247461903, 0.8309518948453007, 0.038404810405298306, 0.08276253029821934, 0.08304597359457233, 0.16227766016837952, 0.36931687685298087, 0.45362404707370985, 0.48528137423856954, 0.4868329805051381]
。当你把它和x
相加时,得到的是4.999999999543545
。 - B. Decoster