一個完整的解決方案,計算所有的方式來完成。 我使用整數作爲速度和內存使用的特徵集:19='0b10011'
代表[A[0],A[1],A[4]]=[8,9,33]
這裏。
A = [8, 9, 15, 15, 33, 36, 39, 45, 46, 60, 68, 73, 80, 92, 96]
B =[183, 36, 231, 128, 137]
def subsetsum(A,N):
res=[[0]]+[[] for i in range(N)]
for i,a in enumerate(A):
k=1<<i
stop=[len(l) for l in res]
for shift,l in enumerate(res[:N+1-a]):
n=a+shift
ln=res[n]
for s in l[:stop[shift]]: ln.append(s+k)
return res
res = subsetsum(A,max(B))
solB = [res[b] for b in B]
exactsol = ~-(1<<len(A))
def decode(answer):
return [[A[i] for i,b in enumerate(bin(sol)[::-1]) if b=='1'] for sol in answer]
def solve(i,currentsol,answer):
if currentsol==exactsol : print(decode(answer))
if i==len(B): return
for sol in solB[i]:
if not currentsol&sol:
answer.append(sol)
solve(i+1,currentsol+sol,answer)
answer.pop()
對於:比當兩個15
不在同一子集
solve(0,0,[])
[[9, 46, 60, 68], [36], [8, 15, 39, 73, 96], [15, 33, 80], [45, 92]]
[[9, 46, 60, 68], [36], [8, 15, 39, 73, 96], [15, 33, 80], [45, 92]]
[[8, 15, 15, 33, 39, 73], [36], [9, 46, 80, 96], [60, 68], [45, 92]]
[[9, 15, 33, 46, 80], [36], [8, 15, 39, 73, 96], [60, 68], [45, 92]]
[[9, 15, 33, 46, 80], [36], [8, 15, 39, 73, 96], [60, 68], [45, 92]]
[[15, 15, 73, 80], [36], [9, 39, 45, 46, 92], [60, 68], [8, 33, 96]]
[[15, 15, 73, 80], [36], [8, 9, 33, 39, 46, 96], [60, 68], [45, 92]]
[[45, 46, 92], [36], [15, 15, 60, 68, 73], [9, 39, 80], [8, 33, 96]]
[[45, 46, 92], [36], [9, 15, 15, 39, 73, 80], [60, 68], [8, 33, 96]]
[[45, 46, 92], [36], [8, 15, 39, 73, 96], [60, 68], [9, 15, 33, 80]]
[[45, 46, 92], [36], [8, 15, 39, 73, 96], [15, 33, 80], [9, 60, 68]]
[[45, 46, 92], [36], [8, 15, 39, 73, 96], [60, 68], [9, 15, 33, 80]]
[[45, 46, 92], [36], [8, 15, 39, 73, 96], [15, 33, 80], [9, 60, 68]]
[[15, 33, 39, 96], [36], [8, 15, 60, 68, 80], [9, 46, 73], [45, 92]]
[[15, 33, 39, 96], [36], [8, 9, 15, 46, 73, 80], [60, 68], [45, 92]]
[[15, 33, 39, 96], [36], [8, 15, 60, 68, 80], [9, 46, 73], [45, 92]]
[[15, 33, 39, 96], [36], [8, 9, 15, 46, 73, 80], [60, 68], [45, 92]]
[[8, 33, 46, 96], [36], [15, 15, 60, 68, 73], [9, 39, 80], [45, 92]]
[[8, 33, 46, 96], [36], [9, 15, 15, 39, 73, 80], [60, 68], [45, 92]]
通告,該溶液被加倍。
它解決了獨特的解決方案的問題:在一秒鐘
A=[1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011,
1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035,
1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
1048, 1049]
B=[5010, 5035, 5060, 5085, 5110, 5135, 5160, 5185, 5210, 5235]
。不幸的是,它還不足以解決(71,10)問題。
另一個之一,在純動態規劃精神:
@functools.lru_cache(max(B))
def solutions(n):
if n==0 : return set({frozenset()}) #{{}}
if n<0 : return set()
sols=set()
for i,a in enumerate(A):
for s in solutions(n-a):
if i not in s : sols.add(s|{i})
return sols
def decode(answer): return([[A[i] for i in sol] for sol in answer])
def solve(B=B,currentsol=set(),answer=[]):
if len(currentsol)==len(A) : sols.append(decode(answer))
if B:
for sol in solutions(B[0]):
if set.isdisjoint(currentsol,sol):
solve(B[1:],currentsol|sol,answer+[sol])
sols=[];solve()
看起來像揹包/揹包問題給我。查看 –
@ Jean-FrançoisFabre是的,你是對的,這是錯誤的代碼。修正了,謝謝! – Akintos
您是否想要找到所有產生給定目標總數或只有一組的集合?另外,「A」中的數字是否被假定爲非負數? –