【问题标题】:How to calculate the shortest path between two vertices in Graph with given parameters?如何使用给定参数计算Graph中两个顶点之间的最短路径?
【发布时间】:2016-11-03 14:29:45
【问题描述】:

我们需要计算 minCost(),它有以下参数:

  1. gNodes - 图 g 中的节点数。
  2. int 数组,gFrom,其中每个 gfrom[i] 表示由图 g 中的 ith 边连接的节点。
  3. int 数组,gTo,其中每个 gTo[i] 表示由图 g 中的 ith 边连接的节点。
  4. int 数组,gWeight,表示图 g 中每条边的相应权重。
  5. 一个int,start,表示起始节点索引。
  6. 一个int,end,表示结束节点索引。
  7. 整数,wExtra,表示可选额外边的权重。

我们需要找到从头到尾具有最小可能权重的路径。我们最多可以在任何两个尚未通过边连接的不同节点之间添加一个具有wExtra权重的额外边(即零或一)。该函数必须返回一个表示从开始到结束的最小路径权重的 int。

我能够提出以下代码(Dijkstra 算法),但它没有给出预期的输出。

    public static int minCost(int gNodes, int[] gFrom, int[] gTo, int[] gWeights, int start, int end) {
//making a array to store shortest length and filling it with infinity except the first one
            int[] shortest = new int[gNodes];
            for (int i = 0; i < gNodes; i++) {
                shortest[i] = Integer.MAX_VALUE;
            }
            shortest[start]=0;
//filling the Queue with all vertices
        Queue<Integer> theQ = new PriorityQueue<>();
        for (int i = 0; i < gNodes; i++) {
            theQ.add(i + 1);
        }
//following the algorithm
        while (!theQ.isEmpty()) {
            int u = theQ.poll();
//making a list of adjacent vertices

            List<Integer> adjacent = new ArrayList<>();
            for (int i = 0; i < gFrom.length; i++) {
                if (gFrom[i] == u) {
                    adjacent.add(gTo[i]);
                } else if (gTo[i] == u) {
                    adjacent.add(gFrom[i]);
                }
            }
            for (int v: adjacent) {
                int weight=0;
                for (int i = 0; i < gFrom.length; i++) {
                    if ((gFrom[i] == u && gTo[i] == v) || (gFrom[i] == v && gTo[i] == u)) {
                        weight = gWeights[i];
                    }
                }

//relaxing the verices
                if (shortest[v] > shortest[u] + weight) {
                    shortest[v] = shortest[u] + weight;
                }
                if (v == end) {
                    return shortest[v];
                }
                theQ.add(v);
            }
        }
        return -1;
    }


    public static void main(String[] args) {
        int gNodes = 4;
        int[] gFrom = {1, 2, 2, 3};
        int[] gTo = {2, 3, 4, 4};
        int[] gWeights = {2, 1, 2, 3};
        int start =1;
        int end = 4;
        System.out.println(shortestDistance(gNodes, gFrom, gTo, gWeights, start, end));
    }
}

它没有给出我认为的预期输出,因为我想不出如何使用那个 wExtra。此外,代码非常混乱。请让我知道出了什么问题,或者随时提供任何可以很好地执行此操作的健壮代码。谢谢。

【问题讨论】:

    标签: java algorithm graph shortest-path dijkstra


    【解决方案1】:

    整合wExtra 的可能想法如下:

    复制图形,这样每个输入节点都有两个节点。原始图表示引入新边之前的状态。副本代表介绍后的状态。对于原始图中的每个节点n,您应该将权重为wExtra 的有向边引入副本中的所有节点m,其中m 的原始节点与n 不相邻。这基本上代表了您可以在任何两个不相邻的边之间引入新边的事实。但是一旦你这样做了,你就不能回去了。然后,在start 与原始endend 的副本之间的修改后的图表上运行通常的Dijkstra,您应该会得到正确的结果。

    可视化这一点的最佳方法可能是将两个子图解释为层。您从原始层开始,想要到达两个end 节点之一(以更接近者为准)。但您只能切换一次图层。

    【讨论】:

    • 谢谢 Nico,你能提供相同的代码吗?
    • 不,这需要一些时间才能完全正确。我相信你能弄清楚。
    猜你喜欢
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多