【问题标题】:Java: How does my Prim's look?Java:我的 Prim 看起来怎么样?
【发布时间】:2009-11-24 00:02:07
【问题描述】:

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

我遇到的一个问题是 JGraphT 对所有事情的处理方式都像它所指示的那样。因此,有时有必要进行一些尴尬的调用来反转g.getEdgeSource(e)g.getEdgeTarget(e),如果它们碰巧不正确的话。

我最初尝试使用 JGraphT 的 Fibonacci Heap 来实现这一点,但它太难了,所以我只是做了一个常规的 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;
}

【问题讨论】:

标签: java graph minimum-spanning-tree prims-algorithm jgrapht


【解决方案1】:

我已经将你的算法结果与我的作业进行了比较,它都给出了相同的最小总重量,保持下去!

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 所以礼节希望您编辑原始答案而不是制作更多答案。 :)
    【解决方案3】:

    好的,现在看起来不错。

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

    对于具有 N=200 个节点和各种值 M=(N*(N-1)/k) for k=2,3,4 的 4 个随机生成的图,您的 PRIM alg 产生的最小总权重与我的 alg 相同,8 表示边数。

    乍一看,我会认为这种测试有点矫枉过正,但事实并非如此!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      相关资源
      最近更新 更多