Java 迪克斯特拉';最长路径的s算法
编辑2:这可能太晚了,但我发现问题出在我身上。我误解了这个项目,它要求的是最大的带宽路径,而不是最长的路径。这是不同的,但我直到现在才知道。所以基本上在任何带宽路径问题中(无论是最大的还是最小的),权重都不会累积,路径值是由路径中的最小权重决定的。将其视为管道路径,水流由路径上最细的管道决定。 编辑1:我修复了PQ问题,但仍然不起作用。 这是一项作业(我承认),但如果我不提交,我可能整个课程都不及格。我们应该修改Dijkstra算法来计算最长的简单路径,而不是最短路径。我想不出一个解决办法。我在互联网上搜索发现(甚至是同样的问题) 但当我运行它时,它会产生不正确的值。我还缺什么吗?为什么它不把重量和前一个加起来呢?为什么使用min 有关图表的信息: 1.我们随机生成图,这样每个节点都连接到 大约25%的其他节点。 2.权重为正。 3.图中有25个节点 问题是“路由算法是在图中寻找最大带宽路径的算法,它基于Dijkstra算法的修改,使用了最大堆结构”。有什么窍门可以帮上忙吗Java 迪克斯特拉';最长路径的s算法,java,algorithm,computer-science,graph-algorithm,dijkstra,Java,Algorithm,Computer Science,Graph Algorithm,Dijkstra,编辑2:这可能太晚了,但我发现问题出在我身上。我误解了这个项目,它要求的是最大的带宽路径,而不是最长的路径。这是不同的,但我直到现在才知道。所以基本上在任何带宽路径问题中(无论是最大的还是最小的),权重都不会累积,路径值是由路径中的最小权重决定的。将其视为管道路径,水流由路径上最细的管道决定。 编辑1:我修复了PQ问题,但仍然不起作用。 这是一项作业(我承认),但如果我不提交,我可能整个课程都不及格。我们应该修改Dijkstra算法来计算最长的简单路径,而不是最短路径。我想不出一个解决办法。我在
public class MaxDijkstra {
Graph graph;
PriorityQueue<Node> queue;
public MaxDijkstra(Graph graph, Node s){
this.graph = graph;
s.addAttribute("ui.class", "start");
queue = new PriorityQueue<>(new Comparator<Node>(){
@Override
public int compare(Node n1, Node n2) {
if(Utils.getNodeBW(n1) == Utils.getNodeBW(n2)){
return 0;
}else if(Utils.getNodeBW(n1) < Utils.getNodeBW(n2)){
return 1;
}else{
return -1;
}
}
});
// init
for(Node n : graph){
Utils.setNodeBW(n, 0);
}
Utils.setNodeBW(s, Float.POSITIVE_INFINITY);
// add to Q
for(Node n : graph){
queue.add(n);
}
while(!queue.isEmpty()){
Node u = queue.remove();
Iterator<Node> iterator = u.getNeighborNodeIterator();
while(iterator.hasNext()){
Node v = iterator.next();
float min = Float.min(Utils.getNodeBW(u), Utils.getEdgeBW(u.getEdgeBetween(v)));
if(min > Utils.getNodeBW(v)){
Utils.setNodeBW(v, min);
Utils.setPreOfNode(v, u);
}
}
// validate PQ
// I know it is not good, just for debuggin now
// I will implemnt my own PQ later
List<Node> list = new ArrayList<>();
while(!queue.isEmpty()){
Node w = queue.remove();
list.add(w);
}
for(Node w : list){
queue.add(w);
}
}
}
public void printInfo(){
for(Node n : graph){
System.out.println("N="+n.getId()+" D="+Utils.getNodeBW(n)+" pre="+ (Utils.getPreOfNode(n) == null ? "NIL" : Utils.getPreOfNode(n).getId()) );
}
}
/**
* Just to colourise the path
* @param target
*/
public void backtrack(Node target){
target.addAttribute("ui.class", "end");
Node currunt = target;
Node pre = Utils.getPreOfNode(currunt);
while(pre != null){
currunt.getEdgeBetween(pre).addAttribute("ui.class", "route");
currunt = pre;
pre = Utils.getPreOfNode(currunt);
}
}
公共类MaxDijkstra{
图形;
优先队列;
公共MaxDijkstra(图,节点s){
this.graph=图形;
s、 addAttribute(“ui.class”、“start”);
队列=新优先级队列(新比较器(){
@凌驾
公共整数比较(节点n1、节点n2){
if(Utils.getNodeBW(n1)=Utils.getNodeBW(n2)){
返回0;
}else if(Utils.getNodeBW(n1)Utils.getNodeBW(v)){
Utils.setNodeBW(v,最小值);
Utils.setPreOfNode(v,u);
}
}
//验证PQ
//我知道这不好,就为了现在
//稍后我将执行我自己的PQ
列表=新的ArrayList();
而(!queue.isEmpty()){
Node w=queue.remove();
列表。添加(w);
}
用于(节点w:列表){
添加(w);
}
}
}
public void printInfo(){
for(节点n:图形){
System.out.println(“N=“+N.getId()+”D=“+Utils.getNodeBW(N)+”pre=“+(Utils.getPreOfNode(N)==null?“NIL”:Utils.getPreOfNode(N).getId());
}
}
/**
*只是为了给这条路涂上颜色
*@param目标
*/
公共无效回溯(节点目标){
target.addAttribute(“ui.class”、“end”);
节点电流=目标;
Node pre=Utils.getPreOfNode(currunt);
while(pre!=null){
currunt.getEdgeBetween(pre.addAttribute(“ui.class”、“route”);
currunt=pre;
pre=Utils.getPreOfNode(current);
}
}
样本输出:
提前谢谢大家。你不能用Dijkstra的算法来寻找最长的简单路径。这个问题是NP难的。事实上,没有已知的多项式解 如果图相对较小,则可以使用动态规划获得
O(2^n*poly(n))
解决方案,该解决方案适用于n~20-30(状态为访问顶点和最后一个顶点的遮罩。如果可能,过渡是添加一个顶点)
如果图很大,您可以使用不同的启发式和近似方法,并结合局部优化技术来获得良好的(但不一定是最优的)结果解决方案。尝试将所有权重乘以-1,使所有权重为负。然后可以使用Floyd-Warshall算法。Floyd-Warshall算法在没有循环的图形中使用负权重。因此,使用Floyd-Warshall找到最小路径,当乘以-1时,将是ori中的最大路径基纳尔图。您不能更改优先级队列中已有的元素。 通常对于Dijkstra,您需要一个
reduce key
函数,但库中的函数不支持该功能,因此您可以使用不同的BW值将节点多次重新插入pq。类似这样的情况(将其视为伪代码:)
PriorityQueue队列;
公共MaxDijkstra(图,节点s){
队列=新优先级队列(新比较器(){
@凌驾
公共整数比较(对n1,对n2){
返回n1.second>n2.second;
}
});
//初始化
for(节点n:图形){
Utils.setNodeBW(n,0);
}
Utils.setNodeBW(s,Integer.MAX_值);
//添加到Q
for(节点n:图形){
add({n,n.getNodeBW()});
}
而(!queue.isEmpty()){
pair u=queue.remove();
如果(u.second PriorityQueue<pair<Node, int>> queue;
public MaxDijkstra(Graph graph, Node s){
queue = new PriorityQueue<>(new Comparator<pair<Node, int>>(){
@Override
public int compare(pair<Node, int> n1, pair<Node, int> n2) {
return n1.second > n2.second;
}
});
// init
for(Node n : graph){
Utils.setNodeBW(n, 0);
}
Utils.setNodeBW(s, Integer.MAX_VALUE);
// add to Q
for(Node n : graph){
queue.add({n, n.getNodeBW()});
}
while(!queue.isEmpty()){
pair<Node, int> u = queue.remove();
if (u.second < u.first.getNodeBW()) continue; //important - skip if you already saw better value
Iterator<Node> iterator = u.getNeighborNodeIterator();
while(iterator.hasNext()){
Node v = iterator.next();
int min = Integer.min(Utils.getNodeBW(u), Utils.getEdgeBW(u.getEdgeBetween(v)));
if(min > Utils.getNodeBW(v)){
Utils.setNodeBW(v, min);
queue.insert({v, min});
}
}
}
}
}