繁体   English   中英

未加权无向图中的最长路径

[英]Longest path in unweighted undirected graph

无向未加权图

将此图表作为参考,假设我想要0到5之间的最长路径。

那将是:0-> 1-> 3-> 2-> 4-> 6-> 5

对此有什么好的算法吗? 我搜索过,但没有发现任何我能理解的内容。 我找到了很多最短路径的算法(0-> 1-> 2-> 4-> 6-> 5),我已经成功实现了它们。 也许我是问题所在,但我想其他的想法:)

欢迎任何帮助

这个问题是NP-Hard(从哈密顿路径到你的问题有一个简单的减少,并且已知汉密尔顿路径搜索是NP难的)。 这意味着没有多项式解决这个问题(除非P = NP)。

如果需要精确解,可以使用动态编程(指数状态):状态为(mask of visited vertices, last_vertex) ,值为true或false。 转换是添加一个新的顶点,如果在last_vertex和新顶点之间有一条边,则该顶点不在mask 它具有O(2^n * n^2)时间复杂度,仍然优于O(n!)回溯。

这是动态编程解决方案的伪代码:

f = array of (2 ^ n) * n size filled with false values
f(1 << start, start) = true
for mask = 0 ... (1 << n) - 1:
    for last = 0 ... n - 1:
        for new = 0 ... n - 1:
            if there is an edge between last and new and mask & (1 << new) == 0:
                f(mask | (1 << new), new) |= f(mask, last)
res = 0
for mask = 0 ... (1 << n) - 1:
    if f(mask, end):
        res = max(res, countBits(mask))
return res

还有一点关于从汉密尔顿路径到这个问题的减少:

def hamiltonianPathExists():
    found = false
    for i = 0 ... n - 1:
        for j = 0 ... n - 1:
            if i != j:
                path = getLongestPath(i, j) // calls a function that solves this problem
                if length(path) == n:
                    found = true
    return found

这是一个Java实现(我没有正确测试,因此它可能包含错误):

/**
 * Finds the longest path between two specified vertices in a specified graph.
 * @param from The start vertex.
 * @param to The end vertex.
 * @param graph The graph represented as an adjacency matrix.
 * @return The length of the longest path between from and to.
 */
public int getLongestPath(int from, int to, boolean[][] graph) {
    int n = graph.length;
    boolean[][] hasPath = new boolean[1 << n][n];
    hasPath[1 << from][from] = true;
    for (int mask = 0; mask < (1 << n); mask++)
        for (int last = 0; last < n; last++)
            for (int curr = 0; curr < n; curr++)
                if (graph[last][curr] && (mask & (1 << curr)) == 0)
                    hasPath[mask | (1 << curr)][curr] |= hasPath[mask][last];
    int result = 0;
    for (int mask = 0; mask < (1 << n); mask++)
        if (hasPath[mask][to])
            result = Math.max(result, Integer.bitCount(mask));
    return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM