Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在剔除坏序列时生成置换?_Python_Algorithm_Permutation - Fatal编程技术网

Python 如何在剔除坏序列时生成置换?

Python 如何在剔除坏序列时生成置换?,python,algorithm,permutation,Python,Algorithm,Permutation,问题陈述:我有150个附加了权重和值的对象。对象的权重可能会根据其选择的顺序而改变,通常选择约70-80个项目。我最多只能选择一个最大权重,因此,一旦我找到了具有该序列的子解,就需要跳过以相同序列开始的所有置换。目标是实现价值最大化 我可以通过以下方式轻松创建所有排列: from itertools import permutations for i in permutations(list(range(150))): # do something with i 然而,这将创建许多我不

问题陈述:我有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仍然在生成和检查序列。我该如何处理这个问题?理想情况下,我将能够并行运行检查


更多背景:我正在尝试为一款名为“黑色沙漠在线”的游戏创建优化的资源图(图形示例位于somethinglaye.net/bdo/)。该图有约150个资源节点,每个节点可以连接到14个根节点的子集。图上的中间节点具有与其关联的权重。每个城市都有最多可连接的节点数量,并且将资源节点连接到城市会产生额外的权重成本。我没有成功地将随机图生成与遗传算法结合起来“找到”最优解。此外,贪婪的选择会导致次优解。我目前正被困在如何生成一个蛮力+综合解决方案上,该解决方案将在合理的时间内运行(合理的是在合理的台式计算机上运行一天)。

一次一项地浏览库存列表,并尝试打包有或没有该项目(两次递归).当我们达到以下两点之一时,报告解决方案:

  • 没有更多的项目需要考虑
  • 剩下的清单符合我们的重量预算
  • 这将通过主动构建来进行筛选

    代码:


    如果您使用通常的递归算法,您可以轻松地从递归中的任何位置返回以修剪整个子树。我们以前尝试过这种方法,但遇到了递归深度错误。但是在过度设计问题时,我忘记了设置RecursionLimit。虽然我认为这仍然需要比我愿意运行程序更长的时间才能完成,但它确实回答了我所问的问题。如果对象的权重根据选择的顺序而变化,那么这会使问题变得更加困难,因为同一组对象的权重可能会因选择的顺序而不同。这似乎意味着您必须尝试所有对象的组合每一种排列。你能更详细地描述这个问题是如何工作的吗?更详细的答案可能是,增加连接的成本只是额外边的权重加上“连接惩罚”的总和(或者,不管你怎么称呼它,将更多节点链接到根节点的成本增加)?因为这样看来,你不必关注顺序(只需关注边是否正在使用的二进制事实,以及与根连接的事物的数量)在不优化顺序的情况下,你应该有一个小得多的问题。也许你也可以把它写成一个线性规划,以获得一个好的修剪启发。这回答了我问题的一个更简单的版本。你的解决方案假设静态权重,而我的版本顺序很重要,因为它可以改变权重。然而,这应该给我一个更大的挑战这比我最初的贪婪算法更接近。我只需要在运行模拟现实的选择顺序(以及静态权重)之前弄清楚如何对项目进行排序。是的,我认为这会起作用。您需要在第一个递归步骤中插入权重更新。也许可以颠倒顺序,所以您可以执行“不”操作递归,然后改变权重,最后进行“with”递归调用。
    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)]