Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 迪克斯特拉';最长路径的s算法_Java_Algorithm_Computer Science_Graph Algorithm_Dijkstra - Fatal编程技术网

Java 迪克斯特拉';最长路径的s算法

Java 迪克斯特拉';最长路径的s算法,java,algorithm,computer-science,graph-algorithm,dijkstra,Java,Algorithm,Computer Science,Graph Algorithm,Dijkstra,编辑2:这可能太晚了,但我发现问题出在我身上。我误解了这个项目,它要求的是最大的带宽路径,而不是最长的路径。这是不同的,但我直到现在才知道。所以基本上在任何带宽路径问题中(无论是最大的还是最小的),权重都不会累积,路径值是由路径中的最小权重决定的。将其视为管道路径,水流由路径上最细的管道决定。 编辑1:我修复了PQ问题,但仍然不起作用。 这是一项作业(我承认),但如果我不提交,我可能整个课程都不及格。我们应该修改Dijkstra算法来计算最长的简单路径,而不是最短路径。我想不出一个解决办法。我在

编辑2:这可能太晚了,但我发现问题出在我身上。我误解了这个项目,它要求的是最大的带宽路径,而不是最长的路径。这是不同的,但我直到现在才知道。所以基本上在任何带宽路径问题中(无论是最大的还是最小的),权重都不会累积,路径值是由路径中的最小权重决定的。将其视为管道路径,水流由路径上最细的管道决定。

编辑1:我修复了PQ问题,但仍然不起作用。

这是一项作业(我承认),但如果我不提交,我可能整个课程都不及格。我们应该修改Dijkstra算法来计算最长的简单路径,而不是最短路径。我想不出一个解决办法。我在互联网上搜索发现(甚至是同样的问题)

但当我运行它时,它会产生不正确的值。我还缺什么吗?为什么它不把重量和前一个加起来呢?为什么使用min

有关图表的信息: 1.我们随机生成图,这样每个节点都连接到 大约25%的其他节点。 2.权重为正。 3.图中有25个节点

问题是“路由算法是在图中寻找最大带宽路径的算法,它基于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});
                }
            }
        }
    }
}