gpt4 book ai didi

java - Prim的算法在Java中的实现

转载 作者:行者123 更新时间:2023-12-02 01:59:37 24 4
gpt4 key购买 nike

我正在尝试在 Java 中使用我的图 HashMap + LinkedList 和包含连接顶点和权重的 Edge 类来实现 Prim 算法:

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

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

最后我需要 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

问题似乎出在我的 getVertices() 方法(该方法返回图形的所有顶点)中,因为它返回 Set<T> ;我尝试使用 addAll 将所有内容放入 LinkedList 中,并返回此 LinkedList 但它给了我同样的错误。我做错了什么?

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<T> 来修复它至source但我认为这根本没有任何意义,因为我的想法是我给出一个可以包含任何类型的顶点,而不仅仅是边。

普里姆的:

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(可能是我作为输入给出的删除最昂贵边的图),或者称为路径的 LinkedList,它保存权重最低的路径。我也不知道如何找到MST中的边数;我应该为每个顶点(我的 HashMap 的 keySet)找到 LinkedList 的大小(这是它的值)并对它们进行求和吗?

编辑:getAdjacentVertices方法

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) 我猜错误不在 getVertices() 中但事实上你的Graph被定义为 Edge<T> 上的通用而不是TGraph<T>实例化为 Graph<Edge<T1>> ,所以Set<T>因为返回值被实例化为 Set<Edge<T1>> .

我建议你定义GraphGraph<Edge<T>> ,并从那里重构图的逻辑,或者定义 IEdge<T>作为 Edge<T> 的 super 接口(interface)并将 Graph 重新定义为 Graph<? extends IEdge<T>> .

例如(蒙住眼睛):

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 的变体。在本例中,您将返回 List<T>但因为你骑自行车时:

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

getAdjacentVertices的返回值应该是 Enumerable<Edge<T>> ,当您提供 Enumerable<T> 时。您可能想在 getAdjacentVertices 中返回类似的内容实现:

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

关于java - Prim的算法在Java中的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51819394/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com