【问题标题】:Error with getting the Minimum Spanning Tree from a Graph? [closed]从图中获取最小生成树时出错? [关闭]
【发布时间】:2023-03-28 22:38:02
【问题描述】:

我正在尝试获取无向加权图的最小生成树,它应该返回最小生成树的权重,如果使用名为 CITS2200 的包找不到最小生成树,则返回 -1,下面是链接到 CITS2200.jar:

CITS2200.jar

我想知道是否有人能明白为什么我在以下代码中的 getMinSpanningTree 方法没有通过测试,任何帮助将不胜感激。干杯,本。 c",)

import CITS2200.*;
public class PathImp implements Path {  

 public int getMinSpanningTree(Graph g) {
    int parent[] = new int[g.getNumberOfVertices()];
    int key[] = new int [g.getNumberOfVertices()];
    Boolean mstSet[] = new Boolean[g.getNumberOfVertices()];
    for (int i = 0; i < g.getNumberOfVertices(); i++)
    {
        key[i] = Integer.MAX_VALUE;
        mstSet[i] = false;
    }
    key[0] = 0;     
    parent[0] = -1;
    int sum = -1;
    for (int count = 0; count < g.getNumberOfVertices()-1; count++)
    {
        int u = minKey(key, mstSet);
        mstSet[u] = true;
        for (int v = 0; v < g.getNumberOfVertices(); v++){
            if (g.getWeight(u,v)!=0 && mstSet[v] == false &&
                g.getWeight(u,v) <  key[v])
            {
                parent[v]  = u;
                key[v] = g.getWeight(u,v);
                sum += g.getWeight(u,v);
            }
         }
    }
    return sum;
}
public int minKey(int key[], Boolean mstSet[])
{
    int min = Integer.MAX_VALUE, min_index=-1;
    for (int v = 0; v < key.length; v++)
        if (mstSet[v] == false && key[v] < min)
        {
            min = key[v];
            min_index = v;
        }
    return min_index;
}
 public int minDistance(int dist[], Boolean sptSet[])
    {
        int min = Integer.MAX_VALUE, min_index=-1;
        for (int v = 0; v < dist.length; v++)
            if (sptSet[v] == false && dist[v] <= min)
            {
                min = dist[v];
                min_index = v;
            }
        return min_index;
    }
 public int[] getShortestPaths(Graph g, int src)
{
    int dist[] = new int[g.getNumberOfVertices()]; 
    int graph[][] = g.getEdgeMatrix();                         
    Boolean sptSet[] = new Boolean[g.getNumberOfVertices()];
    for (int i = 0; i < g.getNumberOfVertices(); i++)
    {
        dist[i] = Integer.MAX_VALUE;
        sptSet[i] = false;
    }
    dist[src] = 0;
    for (int count = 0; count < g.getNumberOfVertices()-1; count++)
    {
        int u = minDistance(dist, sptSet);
        sptSet[u] = true;
        for (int v = 0; v < g.getNumberOfVertices(); v++)
            if (!sptSet[v] && graph[u][v]!=0 &&
                    dist[u] != Integer.MAX_VALUE &&
                    dist[u]+graph[u][v] < dist[v])
                dist[v] = dist[u] + graph[u][v];
    }
    return dist;
}
}

getShortestPath(G, v) 方法可以正常工作,但是,下面是我在针对测试类测试代码时收到的错误消息:

 Checking files:
 PathImp.java
 Files exist and are readable.

 Compiling Files:
 PathImp
 Compilation complete.

 Loading Files:
 PathImp
 Loading complete.

 Implements CITS2200.Path

Constructing instance...
Constructed PathImp

 Analysing PathImp...
MST:
1
MST incorrect for 500 vertices at 0.03 density.
2
MST incorrect for 1000 vertices at 0.02 density.
3
MST incorrect for 1500 vertices at 0.01 density.
SSSP:
1
Shortest paths correct for 500 vertices at 0.03 density.
2
Shortest paths correct for 1000 vertices at 0.02 density.
3
Shortest paths correct for 1500 vertices at 0.01 density.


!Analysis halted: Your code has produced an incorrect output. 

Your submission was not successful on this occasion.
Please try again when you've addressed this problem.
Execution stack trace (if any) follows.

java.lang.Exception: Your code has produced an incorrect output. 
    at Lab8.main(Lab8.java:86)

【问题讨论】:

    标签: java algorithm graph tree


    【解决方案1】:

    我认为问题在于这一行:

    sum += g.getWeight(u,v);
    

    每当您考虑向生成树添加一条边时,您都会将权重添加到您的总成本中。这会高估生成树的真实成本。

    相反,您应该只在您确定边被添加到生成树(即紧接在int u = minKey(key, mstSet); 之后)时添加权重

    例如类似:

    int u = minKey(key, mstSet);
    if (parent[u] != -1)
        sum += g.getWeight(parent[u],u);
    

    【讨论】:

    • 感谢彼得的输入,我把你说的那行删掉了,直接放在 int u = minKey(key, mstSet);虽然,我仍然没有得到正确的解决方案?我明白你在说什么,也许我需要另一种方法来解决这个问题......干杯,本。 c",)
    • 我添加了一些示例代码。如果还是不行,我建议你用一些非常小的案例(例如 3 个节点)进行测试,并确认结果符合预期。如果没有,请使用调试器单步执行以尝试跟踪失败的位置。
    • 感谢 Peter,我已投票支持您,但在我达到 15 岁之前它不会生效...谢谢,Ben。 c",)
    【解决方案2】:
    1. 行内:for (int count = 0; count &lt; g.getNumberOfVertices()-1; count++) - 删除减号:for (int count = 0; count &lt; g.getNumberOfVertices(); count++)

    2. 正如彼得所说,您的问题在于求和。您不需要在 mst 查找过程中求和。最后需要对找到的 MST 的权重求和:

    从 for 循环中删除 sum += g.getWeight(u,v);

    在for循环之后添加:

    int sum = 0;
            for (int v = 0; v < mstSet.length; v++)
            {
                if (mstSet[v] && parent[v] >= 0)
                {
                    System.out.println("In MST: (" + (parent[v]+1) + ", " + (v+1) + ")");
                    sum += g.getWeight(parent[v], v);
                }
            }
    
            return sum;
    

    【讨论】:

    • 感谢aviad,我已投票支持您,但在我达到15 的状态之前它不会生效...您的解决方案完美运行。干杯,本。 c",)
    • 不客气。祝你好运
    猜你喜欢
    • 2017-04-18
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 2010-10-07
    • 2020-12-28
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多