algorithm - 拓扑排序

标签 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)。

我一直在思考这个问题。但我现在不知道了。有人可以就算法设计或问题的复杂性证明提供一些想法吗?谢谢。

最佳答案

这是 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}))

关于algorithm - 拓扑排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37394331/

相关文章:

Haskell:常见的核心递归谬误

python - Debug Exact Cover Pentominoes,维基百科示例不完整?或者...我误解了一些东西(包括代码)

mysql - 如何替换 MySQL 枚举值进行排序

javascript - 在名字和姓氏之后对数组进行排序,javascript

c++ - 帮助使用 std::locale?

algorithm - 多对一或多对组匹配/分配

algorithm - 找到范围的最大相交子集

python - 用于整数分区的优雅 Python 代码

c++ - 优化昂贵函数的调用次数

c - 使用 for 循环从数组中删除对象