Java:我的Prim';什么样子?

Java:我的Prim';什么样子?,java,graph,minimum-spanning-tree,prims-algorithm,jgrapht,Java,Graph,Minimum Spanning Tree,Prims Algorithm,Jgrapht,我正试图用JGraphT实现Prim的最小生成树算法。看起来怎么样 我遇到的一个问题是JGraphT像导演一样处理一切。因此,有时有必要进行一些笨拙的调用,以反转g.getEdgeSource(e)和g.getEdgeTarget(e),如果它们不正确的话 我最初尝试用JGraphT的Fibonacci堆来实现这一点,但是太难了,所以我只做了一个常规的PQ 我没有将不存在边的权重设置为无穷大,只是没有将其添加到队列中 建议?文体问题?明显的低效率?我应该使用的代码,而不是我自己的 public

我正试图用JGraphT实现Prim的最小生成树算法。看起来怎么样

我遇到的一个问题是JGraphT像导演一样处理一切。因此,有时有必要进行一些笨拙的调用,以反转
g.getEdgeSource(e)
g.getEdgeTarget(e)
,如果它们不正确的话

我最初尝试用JGraphT的Fibonacci堆来实现这一点,但是太难了,所以我只做了一个常规的PQ

我没有将不存在边的权重设置为无穷大,只是没有将其添加到队列中

建议?文体问题?明显的低效率?我应该使用的代码,而不是我自己的

public static Graph<String, DefaultWeightedEdge> primPQ(final WeightedGraph<String, DefaultWeightedEdge> g, String root) {
  Graph<String, DefaultWeightedEdge> mst = new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
  Queue<DefaultWeightedEdge> pq = new PriorityQueue<DefaultWeightedEdge>(g.vertexSet().size(), new Comparator<DefaultWeightedEdge>() {
    @Override
    public int compare(DefaultWeightedEdge o1, DefaultWeightedEdge o2) {
      if (g.getEdgeWeight(o1) < g.getEdgeWeight(o2)) {
        return -1;
      }
      if (g.getEdgeWeight(o1) > g.getEdgeWeight(o2)) {
        return 1;
      } 
      return 0;
    }
  });

  mst.addVertex(root);
  DefaultWeightedEdge link;

  for (String v : g.vertexSet()) {
    link = g.getEdge(root, v);
    if (link != null) {
      pq.add(link);
    }
  }

  //this is made difficult by JGraphT's assumption that everything is directed
  DefaultWeightedEdge minEdge = pq.poll();
  String toAdd;
  String alreadyFound;
  String tmp;

  while (minEdge != null) {
    // guessing at which is in the MST
    toAdd = g.getEdgeTarget(minEdge);
    alreadyFound = g.getEdgeSource(minEdge);

    if (!(mst.containsVertex(toAdd) && mst.containsVertex(alreadyFound))) {
      // swap if backwards
      if (mst.containsVertex(toAdd)) {
        tmp = toAdd;
        toAdd = alreadyFound;
        alreadyFound = tmp;
      }
      mst.addVertex(toAdd);
      mst.addEdge(alreadyFound, toAdd, minEdge);
      System.out.format("%s --> %s\n", g.getEdgeSource(minEdge), toAdd);

      for (String v : g.vertexSet()) {
        if (! mst.containsVertex(v)) {
          link = g.getEdge(toAdd, v);
          if (pq.contains(link)) {
            g.setEdgeWeight(minEdge, Math.min(g.getEdgeWeight(minEdge), g.getEdgeWeight(link)));
          }
          if (link != null && ! pq.contains(link)) {
            pq.add(link);
          }
        }
      }
    }
    minEdge = pq.poll();
  }
  return mst;
}
公共静态图primPQ(最终权重图g,字符串根){
Graph mst=新的SimpleWeightedGraph(defaultWeightEdge.class);
队列pq=新的优先级队列(g.vertexSet().size(),新的比较器(){
@凌驾
公共整数比较(DefaultWeightedEdge o1,DefaultWeightedEdge o2){
如果(g.getedgewight(o1)g.getedgewight(o2)){
返回1;
} 
返回0;
}
});
mst.addVertex(根);
DefaultWeightedEdge链接;
对于(字符串v:g.vertexSet()){
link=g.getEdge(根,v);
如果(链接!=null){
pq.add(链接);
}
}
//JGraphT认为一切都是有方向的,这使得这一点变得困难
DefaultWeightedEdge minEdge=pq.poll();
串蟾蜍;
字符串已找到;
串tmp;
while(minEdge!=null){
//猜测MST中的哪个
toAdd=g.getEdgeTarget(minEdge);
alreadyFound=g.getEdgeSource(minEdge);
如果(!(mst.containsVertex(toAdd)和mst.containsVertex(ALREADYFUND))){
//倒换
如果(mst.containsVertex(toAdd)){
tmp=toAdd;
toAdd=已找到;
alreadyFound=tmp;
}
mst.addVertex(toAdd);
mst.addEdge(alreadyFound、toAdd、minEdge);
System.out.format(“%s-->%s\n”,g.getEdgeSource(minEdge),toAdd);
对于(字符串v:g.vertexSet()){
如果(!mst.containsVertex(v)){
link=g.getEdge(toAdd,v);
如果(pq.包含(链接)){
g、 setedgewight(minEdge,Math.min)(g.getedgewight(minEdge),g.getedgewight(link));
}
if(link!=null&&!pq.contains(link)){
pq.add(链接);
}
}
}
}
minEdge=pq.poll();
}
返回mst;
}

我将你的算法的结果与一个我的算法进行了比较,我的算法是一个家庭作业,它给出了相同的最小总权重,请继续

我将你的算法的结果与我的一个算法的结果进行了比较,我的算法是一个家庭作业,它给出了相同的最小总权重,请继续

在增加边数和顶点数的同时,我会得到不同的结果,我会回来…

在增加边数和顶点数的同时,我会得到不同的结果,我会回来…

好的,现在看起来不错

顺便说一句,我的练习有点棘手:我必须编写一个算法来找到最小生成树,但我的算法必须通过消除边来进行。我写了一些东西,它使用一些深度优先遍历来查找循环,然后通过将其“着色”为红色来消除最加权的边

对于4个随机生成的图,您的PRIM alg生成的最小总权重与我的alg相同,这些图具有N=200个节点,并且对于k=2,3,4,8的边数,具有不同的值M=(N*(N-1)/k)


乍一看,我会认为这种测试是过分的,但事实并非如此

好了,现在看起来不错

顺便说一句,我的练习有点棘手:我必须编写一个算法来找到最小生成树,但我的算法必须通过消除边来进行。我写了一些东西,它使用一些深度优先遍历来查找循环,然后通过将其“着色”为红色来消除最加权的边

对于4个随机生成的图,您的PRIM alg生成的最小总权重与我的alg相同,这些图具有N=200个节点,并且对于k=2,3,4,8的边数,具有不同的值M=(N*(N-1)/k)


乍一看,我会认为这种测试是过分的,但事实并非如此

我没有看所有的代码,但是AFAIK JGraphT显然支持无向图是的,但是,给定一条边,如何得到两个端点?没有看所有的代码,但是AFAIK JGraphT显然支持无向图是的,但是,给定一条边,你是如何得到这两个端点的呢?所以礼节要求你编辑你的原始答案,而不是做更多的回答。:)因此,礼仪部门更希望您编辑您的原始答案,而不是制作更多的答案。:)