我有一个长度为 n 的字典选择 m ,其长度为 m 的元组的键包含整数1到名词的。我想计算这个字典值的最大总和,使得元组键的索引是唯一的,存储组成这个最大值的组合。
示例输入:
input_dict = {
(1, 2): 16,
(1, 3): 4,
(1, 4): 13,
(1, 5): 8,
(1, 6): 9,
(2, 3): 6,
(2, 4): 19,
(2, 5): 7,
(2, 6): 16,
(3, 4): 12,
(3, 5): 23,
(3, 6): 12,
(4, 5): 17,
(4, 6): 19,
(5, 6): 21
}
示例输出:
(((1, 2), (3, 5), (4, 6)), 58)
我目前的方法:计算所有独特输出组合的总和并取最大值。
gen_results = [{}]
for (key, val) in input_dict.items():
gen_results[0][(key,)] = val
i = 0
complete = False
while not complete:
complete = True
gen_results.append({})
for (combinations, running_sum) in gen_results[i].items():
for (key, val) in input_dict.items():
unique_combination = True
for combination in combinations:
for idx in key:
if idx in combination:
unique_combination = False
break
if not unique_combination:
break
if unique_combination:
complete = False
gen_results[i+1][combinations + (key,)] = running_sum + val
i += 1
generation_maximums = []
for gen_result in gen_results:
if gen_result == {}:
continue
generation_maximums.append(max(gen_result.items(), key=(lambda x: x[1])))
print(max(generation_maximums, key=(lambda x: x[1])))
如何改进大型 n 和 m 的算法?
答案 0 :(得分:0)
如果你不进行整数编程,你通常可以使用位作为哈希来强制使用这些东西
e.g。以下输出58
input_dict = {
(1, 2): 16,
(1, 3): 4,
(1, 4): 13,
(1, 5): 8,
(1, 6): 9,
(2, 3): 6,
(2, 4): 19,
(2, 5): 7,
(2, 6): 16,
(3, 4): 12,
(3, 5): 23,
(3, 6): 12,
(4, 5): 17,
(4, 6): 19,
(5, 6): 21
}
dp = {}
n, m = 2, 6
for group, score in input_dict.items():
bit_hash = 0
for x in group:
bit_hash += 1 << (x-1)
dp[bit_hash] = score
while True:
items = dp.items()
for hash1, score1 in items:
for hash2, score2 in items:
if hash1 & hash2 == 0:
dp[hash1|hash2] = max(dp.get(hash1|hash2), score1+score2)
if len(dp) == (1<<m)/2-1:
print dp[(1<<m)-1]
break