问题陈述:我有150个附加权重和值的对象。对象的权重可能会根据选择的顺序而改变,通常会选择约70-80个项目。我只能选择最大权重,因此一旦我找到了具有该序列的子解决方案,就需要跳过以相同序列开头的所有排列。目标是最大化价值。
我可以通过以下方式轻松创建所有排列:
from itertools import permutations
for i in permutations(list(range(150))):
# do something with i
然而,这将创建许多我不需要检查的序列。我也可以用r来限制置换长度
from itertools import permutations
for i in permutations(list(range(150)), r=80):
# do something with i
然而,对于非常糟糕的序列,仍然会有大量的冗余检查。此外,这可能会在“最佳”解决方案之前停止。
我可以做类似
的事情from itertools import permutations
v = []
for i in permutations(list(range(150)), r=80):
if v and v == i[:len(v)]:
continue
# do something with i
v = i # would be some optimal subset of i
然而,由于Python仍在生成和检查序列,因此仍需要很长时间才能运行。有关如何处理此问题的任何想法?理想情况下,我可以并行运行检查。
更多背景:我正在尝试为名为Black Desert Online的游戏创建优化的资源图表(图片示例在somethinglovely.net/bdo/)。该图具有~150个资源节点,每个节点可以连接到14个根节点的子集。图上的中间节点具有与它们相关联的权重。每个城市都有可以连接的最大节点数,并且将资源节点连接到城市还有额外的重量成本。我没有成功地使用随机图生成与遗传算法相结合来“找到”最优解。此外,只是做出贪婪的选择会导致次优解决方案。我目前难以理解如何生成一个在合理的时间段内运行的强力+综合解决方案(合理的在一天内在合理的台式计算机上运行。
答案 0 :(得分:1)
一次浏览库存清单,一个项目,并尝试打包有和没有该项目(两次递归)。当我们达到两点之一时报告解决方案:
通过积极的施工来处理剔除。
代码:
items = [
# Description, weight
("petrol", 10),
("clothes", 8),
("tents", 7),
("beer", 16),
("food", 20),
("teddy bear", 3),
("tank", 25),
("skin lotion", 2),
("library", 17),
("mortar", 9),
("cut lumber", 12),
("sports gear", 14),
]
limit = 20
def load(inventory, max_weight, current):
still_okay = [item for item in inventory if item[1] <= max_weight]
if len(still_okay) == 0:
# Can't add any more; emit solution and back up
print "RESULT", current
else:
# If the rest of the list fits in our weight budget,
# take everything.
if sum([item[1] for item in still_okay]) <= max_weight:
print "RESULT", current + still_okay
else:
item = still_okay.pop()
# recur on two branches: one each with and without this item
load(still_okay, max_weight - item[1], current + [item])
load(still_okay, max_weight, current)
load(items, limit, [])
输出:
RESULT [('sports gear', 14), ('teddy bear', 3), ('skin lotion', 2)]
RESULT [('cut lumber', 12), ('skin lotion', 2), ('teddy bear', 3)]
RESULT [('cut lumber', 12), ('teddy bear', 3)]
RESULT [('cut lumber', 12), ('tents', 7)]
RESULT [('cut lumber', 12), ('clothes', 8)]
RESULT [('mortar', 9), ('skin lotion', 2), ('teddy bear', 3)]
RESULT [('mortar', 9), ('skin lotion', 2), ('tents', 7)]
RESULT [('mortar', 9), ('skin lotion', 2), ('clothes', 8)]
RESULT [('mortar', 9), ('teddy bear', 3), ('tents', 7)]
RESULT [('mortar', 9), ('teddy bear', 3), ('clothes', 8)]
RESULT [('mortar', 9), ('tents', 7)]
RESULT [('mortar', 9), ('clothes', 8)]
RESULT [('mortar', 9), ('petrol', 10)]
RESULT [('library', 17), ('skin lotion', 2)]
RESULT [('library', 17), ('teddy bear', 3)]
RESULT [('skin lotion', 2), ('teddy bear', 3), ('tents', 7), ('clothes', 8)]
RESULT [('skin lotion', 2), ('teddy bear', 3), ('clothes', 8)]
RESULT [('skin lotion', 2), ('teddy bear', 3), ('petrol', 10)]
RESULT [('skin lotion', 2), ('beer', 16)]
RESULT [('skin lotion', 2), ('tents', 7), ('clothes', 8)]
RESULT [('skin lotion', 2), ('tents', 7), ('petrol', 10)]
RESULT [('skin lotion', 2), ('petrol', 10), ('clothes', 8)]
RESULT [('teddy bear', 3), ('beer', 16)]
RESULT [('teddy bear', 3), ('tents', 7), ('clothes', 8)]
RESULT [('teddy bear', 3), ('tents', 7), ('petrol', 10)]
RESULT [('teddy bear', 3), ('clothes', 8)]
RESULT [('teddy bear', 3), ('petrol', 10)]
RESULT [('food', 20)]
RESULT [('beer', 16)]
RESULT [('tents', 7), ('clothes', 8)]
RESULT [('tents', 7), ('petrol', 10)]
RESULT [('petrol', 10), ('clothes', 8)]