Python 蟒蛇3-使用最低重量将模式A更改为B

Python 蟒蛇3-使用最低重量将模式A更改为B,python,list,algorithm,sorting,dictionary,Python,List,Algorithm,Sorting,Dictionary,所以我有路径A和B以及路径中对象的权重,例如: A = [5, 4, 2, 1, 3, 8, 7, 6, 9] B = [2, 3, 4, 1, 9, 7, 8, 6, 5] W = {1:1000, 2:500, 3:200, 4:400, 5:700, 6:250, 7:100, 8:50, 9:900} 和重量,例如: A = [5, 4, 2, 1, 3, 8, 7, 6, 9] B = [2, 3, 4, 1, 9, 7, 8, 6, 5] W = {1:1000, 2:500,

所以我有路径A和B以及路径中对象的权重,例如:

A = [5, 4, 2, 1, 3, 8, 7, 6, 9]
B = [2, 3, 4, 1, 9, 7, 8, 6, 5]
W = {1:1000, 2:500, 3:200, 4:400, 5:700, 6:250, 7:100, 8:50, 9:900}
和重量,例如:

A = [5, 4, 2, 1, 3, 8, 7, 6, 9]
B = [2, 3, 4, 1, 9, 7, 8, 6, 5]
W = {1:1000, 2:500, 3:200, 4:400, 5:700, 6:250, 7:100, 8:50, 9:900}
我想用最轻的重量来代替A到B, 例如,如果我们要替换6和8,则使用的权重为:50+250=300

我应该使用什么排序算法等

例如:

 IN [5, 4, 2, 1, 3, 8, 7, 6, 9] swap 4,2 weight = 400+500=900 
    [5, 2, 4, 1, 3, 8, 7, 6, 9] swap 5,2 weight=700+500=1200 
    [2, 5, 4, 1, 3, 8, 7, 6, 9] swap 8,7 weight=50+100=150
    [2, 5, 4, 1, 3, 7, 8, 6, 9] swap 3,5 weight=200+7000=900 
    [2, 3, 4, 1, 5, 7, 8, 6, 9] swap 5,9 weight=700+900=1600
    [2, 3, 4, 1, 9, 7, 8, 6, 5] == B, sum = 900+1200+150+900+1600=4750

你首先应该决定什么是“运动”。是否需要互换,或者您是否可以单独移动一件物品

例如,如果您有一个无边界的稀疏数组,您能否在不影响任何其他块的情况下从开始到结束移动5个?在任何两件物品之间是否有无限的空间,这样你就不需要“分开”(向左移动一件,向右移动另一件)

如果是这样的话,那么我相信你的问题归结为找到所需移动的最小数量,即选择排序-对于A的每个元素,找到在B中移动它的位置。任何快速排序、合并排序、冒泡排序的实现都意味着排序,并且需要太多的移动交换

前几次迭代

[5, 4, 2, 1, 3, 8, 7, 6, 9]
[  , 4, 2, 1, 3, 8, 7, 6, 9, 5]  # move 5 to the end, weight=700
[  ,  , 2, 4, 1, 3, 8, 7, 6, 9]  # move 4 between 2 and 1, weight+=400

实现这一点的一般方法是使用类似or的图形搜索。基本原则是,您要以最小的累计成本(权重)构建路径图(交换)。如果您以最小的累积成本从图中的节点继续探索,则可以保证以最小的可能累积成本到达每个新节点。在A*的情况下,您使用一个启发式函数来估计实现目标所需的剩余成本,这导致需要更少的探索

这里是一个类似A*的搜索的实现和一个恢复中间状态的函数

from heapq import heappop, heappush

def search(start, goal, next_nodes, heuristic, hash_f):
    # start: starting node.
    # goal: goal node.
    # next_nodes: function of node and corresponding accumulated cost, 
    # should return iterable with new possible nodes and corresponding accumulated costs.
    # heuristic: function of node, should return an estimation of the remaining cost smaller than the true remaining cost.
    # hash_f: function of node, should return a hashable value.

    # (cost + heuristic, cost, start node, parent node)
    queue = [(0, 0, start, None)]
    # Dictionary representing minimum cost graph with visited nodes, their parent and cost
    minimum_graph = {} 

    while queue:
        _, node_cost, node, parent = heappop(queue)
        node_hash = hash_f(node)
        if node_hash in minimum_graph: continue
        minimum_graph[node_hash] = (parent, node_cost)

        if node == goal:
            return node_cost, minimum_graph

        for n, c in next_nodes(node, node_cost):
            if hash_f(n) not in minimum_graph:
                c_min = heuristic(n, goal)
                heappush(queue, (c + c_min, c, n, node))

    # Fail
    return None, minimum_graph

def get_path(start, goal, minimum_graph, hash_f):
    S = []
    C = []
    p = goal
    while p is not None:
        p_hash = hash_f(p)
        S.append(p)
        C.append(minimum_graph[p_hash][1])
        p = minimum_graph[p_hash][0]
    S.reverse()
    C.reverse()
    return S, C
以下函数给出了指定问题的下一个可能状态和相关成本

def next_nodes(n, c):
    nodes = []
    for i in range(len(n)):
        for j in range(len(n)):
            if i == j: continue
            n_new = n.copy()
            n_new[i] = n[j]
            n_new[j] = n[i]
            c_new = c + W[n[i]] + W[n[j]]
            nodes.append((n_new, c_new))
    return nodes
为了提高搜索性能,使用了一种启发式算法,只要它低估了排序数组的剩余成本,仍然可以得到最低的成本。直接移动而不交换是解决此问题的一种可能的启发式方法

def heuristic(n, goal):
    h = 0.0
    for i in range(len(n)):
        if n[i] != goal[i]:
            h += W[n[i]]
    return h
列表是不可散列的,但元组是可散列的,因此可以使用散列函数跟踪已访问的状态

def hash_f(n):
    return tuple(n)
然后可以将其用作

A = [5, 4, 2, 1, 3, 8, 7, 6, 9]
B = [2, 3, 4, 1, 9, 7, 8, 6, 5]
W = {1:1000, 2:500, 3:200, 4:400, 5:700, 6:250, 7:100, 8:50, 9:900}

cost, minimum_graph = search(A, B, next_nodes, heuristic, hash_f)
swaps, costs = get_path(A, B, minimum_graph, hash_f)

print(cost)
print(swaps)
哪个输出

3350
[[5, 4, 2, 1, 3, 8, 7, 6, 9], [5, 4, 2, 1, 8, 3, 7, 6, 9], [5, 4, 2, 1, 9, 3, 7, 6, 8], [8, 4, 2, 1, 9, 3, 7, 6, 5], [2, 4, 8, 1, 9, 3, 7, 6, 5], [2, 8, 4, 1, 9, 3, 7, 6, 5], [2, 3, 4, 1, 9, 8, 7, 6, 5], [2, 3, 4, 1, 9, 7, 8, 6, 5]]

请再解释一下。问题还不清楚。您期望的输出是什么?输出应该是用于对列表进行排序的最小权重,以便对此类算法难题进行排序。我会试试。请你解释一下列表A是如何被B替换的。列表A的每个元素都被列表B的每个元素替换了吗?我认为通过这样做,列表A将被更改为列表B。如果这样做,那么所有组合的权重应该是相同的。这是一个相当复杂的问题,如果把它看成是一个简单的逻辑难题。首先,我必须弄清楚算法应该是什么,然后我会给它编码。我想他是说排序时两个数字要交换。问题只问什么算法。没有明确限制交换,但在他的文章中,他展示了如何排序。他在那里交换,我解释为一个例子,不是问题要求的一部分,这是一个很好的解决方案!谢谢