拓扑排序

时间:2016-05-23 14:57:25

标签: algorithm sorting graph-algorithm

给定具有N个节点的DAG,每个节点具有值(例如,0.2,0.5,1.3,0.1 ......)。我想将顶点排序成一个链。难点在于对​​节点进行排序时存在目标函数。

例如,链是x ---> y ---> z ---> W上。每个链接具有权重,对于(x,y)权重= x,链接(y,z)权重= xy,链接(z,w)权重= xyz等等。

目标函数是最小化所有链接权重的总和(此处为链:x + xy + xyz)。

我一直在考虑它。但我现在不知道。有人可以就算法设计或问题的复杂性证明提出一些想法吗?感谢。

1 个答案:

答案 0 :(得分:2)

这是kevmo314提到的算法,用Python实现。可能它应该在C中重新实现,逐位操作替换集合操作。

我们可以重写目标

x + x*y + x*y*z = x*(1 + y*(1 + z)),

因此,假设所有权重都是正数,则子问题目标中的总体目标是单调的,这允许动态编程。

def optimal_order(predecessors_map, weight_map):
    vertices = frozenset(predecessors_map.keys())
    memo_map = {frozenset(): (0, [])}
    return optimal_order_helper(predecessors_map, weight_map, vertices, memo_map)


def optimal_order_helper(predecessors_map, weight_map, vertices, memo_map):
    if vertices in memo_map:
        return memo_map[vertices]
    possibilities = []
    for v in vertices:
        if any(u in vertices for u in predecessors_map[v]):
            continue
        sub_obj, sub_order = optimal_order_helper(predecessors_map, weight_map, vertices - frozenset({v}), memo_map)
        possibilities.append((weight_map[v] * (1.0 + sub_obj), [v] + sub_order))
    best = min(possibilities)
    memo_map[vertices] = best
    return best


print(optimal_order({'u': [], 'v': ['u'], 'w': [], 'x': ['w']}, {'u': 1.2, 'v': 0.5, 'w': 1.1, 'x': 1.001}))