当前位置: 首页 > 知识库问答 >
问题:

Prim算法在Java中的实现

沈俊美
2023-03-14

我试图在Java中实现Prim的算法,用于我的图形HashMap LinkedList和一个包含连接顶点和权重的类Edge:

adjacencyList = new HashMap<T, LinkedList<Edge<T>>>();

我的想法是,从一个给定的顶点开始:1)将所有顶点保存到一个LinkedList中,这样每次访问它们时我都可以删除它们2)将路径保存到另一个LinkedList中,这样我就可以得到我的最终MST 3)使用PriorityQueue找到最小权重

最后我需要MST,边数和总重量。我很困惑如何返回MST,我的代码中几乎没有错误,我不知道如何修复它们!

首先,我得到了这个错误:

    Prim.java:21: error: no suitable method found for addAll(LinkedList<Edge<T>>)
        unvisited.addAll(graph.getVertices());
                 ^
    method Collection.addAll(Collection<? extends T>) is not applicable
      (argument mismatch; LinkedList<Edge<T>> cannot be converted to Collection<? extends T>)
    method List.addAll(Collection<? extends T>) is not applicable
      (argument mismatch; LinkedList<Edge<T>> cannot be converted to Collection<? extends T>)
    method AbstractCollection.addAll(Collection<? extends T>) is not applicable
      (argument mismatch; LinkedList<Edge<T>> cannot be converted to Collection<? extends T>)
    method LinkedList.addAll(Collection<? extends T>) is not applicable
      (argument mismatch; LinkedList<Edge<T>> cannot be converted to Collection<? extends T>)
  where T is a type-variable: T extends Comparable<T> declared in class Prim

问题似乎出在我的getVerites()方法(返回图的所有顶点)中,因为它返回一个Set

public class Graph<T extends Comparable<T>> {
    .
    .
    public Set<T> getVertices() {
            if (adjacencyList.isEmpty()) {
                System.out.println("Error message.\n");
                return null;
            } else
                return adjacencyList.keySet();
        }
    }

第二个错误是:

   Prim.java:28: error: incompatible types: T cannot be converted to Edge<T>
            for (Edge<T> edge : graph.getAdjacentVertices(source)) {
                                                          ^
  where T is a type-variable:
    T extends Comparable<T> declared in class Prim
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output

我可以通过铸造Edge来修复它

普里姆的:

public class Prim<T extends Comparable<T>> {
    public <SHOULD I RETURN graph ?> minimumSpanningTree(Graph<Edge<T>> graph, T vertex) {
        //ArgumentException

        double weight = 0;
        T source = vertex;

        LinkedList<T> vertexSet = new LinkedList<>();
        LinkedList<Edge<T>> path = new LinkedList<>();

        vertexSet.addAll(graph.getVertices()); //unvisited ERROR HERE
        vertexSet.remove(source);

        double numberOfVertices = graph.getVertices().size();
        PriorityQueue<Edge<T>> priorityQueue = new PriorityQueue<>();

        while (!vertexSet.isEmpty()) {
            for (Edge<T> edge : graph.getAdjacentVertices(source)) {//ERROR
               if (vertexSet.contains(edge.getDestination())) 
                    priorityQueue.insert(edge);
            }
            Edge<T> minWeight = priorityQueue.extractMin();
            weight += minWeight.getWeight();
            path.add(HERE I SHOULD PUT MST PATH BUT I DON'T KNOW HOW!!);

            source = minWeight.getDestination();
            vertexSet.remove(source);
        }
        return <graph??>;
    }
}

正如我之前所说的,我不知道我是否应该返回一个图作为MST(可能是我作为输入删除最昂贵的边给出的图)或一个名为path的LinkedList,它以最小的权重保存路径。我也不知道如何在MST中找到边的数量;我应该为每个顶点(HashMap的键集)找到LinkedList的大小(这是它的值)并将它们相加吗?

编辑:getAdjamentVerites方法

public LinkedList<T> getAdjacentVertices(T vertex) {
    if (adjacencyList.isEmpty() || adjacencyList.containsKey(vertex) == false) {
        System.out.println("Error msg.\n");
        return null;
    } else {
        LinkedList<T> allAdjacents = new LinkedList<>();
        for (Edge<T> edge : adjacencyList.get(vertex)) {
            allAdjacents.add(edge.getDestination());
        }
        return allAdjacents;
    }
}

共有1个答案

周通
2023-03-14

1) 我猜错误不在getVertices()中,而是在边上,您的图形被定义为泛型

我建议您将Graph定义为Graph

例如(蒙住眼睛):

public class Graph<T> {
    Map<T, Edge<T>> adjacencyList;
    public Set<T> getVertices() {
        if (adjacencyList.isEmpty()) {
            System.out.println("Error message.\n");
            return null;
        } else {
            return adjacencyList.keySet();
        }
    }
}

Graph<Point> p;
List<Point> points = new LinkedList<>();
points.addAll(p.getVertices());

2)1的变体。在这种情况下,您将返回一个列表

for (Edge<T> edge : graph.getAdjacentVertices(source))

getAdJacentVerques的返回值应该是一个枚举

LinkedList<Edge<T>> allAdjacents = new LinkedList<>();
for (Edge<T> edge : adjacencyList.get(vertex)) {
    allAdjacents.add(edge);
}
return allAdjacents;

 类似资料:
  • 本文向大家介绍Javascript中的Prim算法,包括了Javascript中的Prim算法的使用技巧和注意事项,需要的朋友参考一下 Prim的算法是一种贪婪算法,可为加权无向图找到最小生成树。它找到形成树的边缘子集,该树包括每个顶点,树中所有边缘的总权重最小。 该算法的工作方式是,从任意起始顶点一次构建一个树,在每个步骤中,从树到另一个顶点添加最便宜的连接。 Prim的算法如何工作? 让我们看

  • 一、普里姆算法介绍 普里姆(Prim)算法,是用来求加权连通图的最小生成树的算法。 基本思想 对于图G而言,V是所有顶点的集合;现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最小生成树中的边。 从所有uЄU,vЄ(V-U) (V-U表示出去U的所有顶点)的边中选取权值最小的边(u, v),将顶点v加入集合U中,将边(u, v)加入集合T中,如此不断重复,直到U=V为

  • 我必须使用基于最小堆的优先级队列来实现Prim的算法。如果我的图包含顶点A、B、C和D以及下面的邻接列表...[它被排序为(顶点名称,相邻顶点的权重)] 粗图: 优先级队列是什么样子的?我不知道该往里面放什么。我应该把所有东西都放进去吗?我应该只写A、B、C和D。我不知道,我真的很想得到答案。

  • 亲爱的读者,这些Data Structures & Algorithms Interview Questions专门设计用于让您熟悉在面试Data Structures & Algorithms时可能遇到的问题的本质。 根据我的经验,好的面试官在你的面试中几乎不打算问任何特定的问题,通常问题从这个主题的一些基本概念开始,然后他们继续基于进一步的讨论和你回答的内容: 什么是数据结构? 数据结构是一种

  • Prim用于查找最小成本生成树的算法(如Kruskal算法)使用贪婪方法。 Prim的算法与shortest path first算法共享相似性。 与Kruskal算法相比,Prim的算法将节点视为单个树,并继续从给定图形向生成树添加新节点。 为了与Kruskal的算法形成对比并更好地理解Prim算法,我们将使用相同的例子 - 第1步 - 删除所有循环和平行边缘 从给定图中删除所有循环和平行边。

  • 以下代码的时间复杂度是多少?我用图和优先级队列的邻接矩阵表示来实现prim的算法。在我看来,时间复杂度是:当源连接到每个其他节点时,堆最多可以增长到(n-1)的大小,而在内部循环中,邻接矩阵的成本是O(n),因此,总的来说:它的O((n-1)*n)-