- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试实现 Kruskal 算法,并在 MST 中找到权重之和。我认为我的问题出在我设置每个节点的父节点的某个地方,但我不确定,因为在小示例中它工作正常,但是在大示例中它没有检测到循环,最终答案是错误的。所以我的发现可能是错误的,但我不确定。这是我的代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Scanner;
public class Graph {
private static int parent[];
private static int numberOfNodes, numberOfEdges, weight;
private static Node startNode, endNode;
private static Graph g;
private static ArrayList<Integer> listOfWeights = new ArrayList<Integer>();
private static ArrayList<Edge> listOfEdges = new ArrayList<Edge>();
private static ArrayList<Node> listOfNodes = new ArrayList<Node>();
private static HashMap<Edge, Integer> distance = new HashMap<Edge, Integer>();
private static HashMap<Edge, Integer> sortedMap = new HashMap<Edge, Integer>();
//values = Integer
private Scanner sc;
public static void main(String[] args) throws FileNotFoundException {
// TODO Auto-generated method stub
g = new Graph();
}
public Graph() throws FileNotFoundException {
sc = new Scanner(new File("data"));
numberOfNodes = Integer.parseInt(sc.next());
numberOfEdges = Integer.parseInt(sc.next());
if(numberOfEdges > 0){
for(int i = 0; i < numberOfEdges; i++) {
//read the start point
startNode = new Node(Integer.parseInt(sc.next()));
//read the end point
endNode = new Node(Integer.parseInt(sc.next()));
//read the price per node
weight = Integer.parseInt(sc.next());
Edge e = new Edge(startNode,endNode);
//set the weight per node
e.setWeight(weight);
//put them in a hashmap
distance.put(e,e.getWeight());
if(!listOfNodes.contains(startNode)){
listOfNodes.add(startNode);
}
if(!listOfNodes.contains(endNode)){
listOfNodes.add(endNode);
}
//System.out.println(distance.get(e));
}
System.out.println("without sort distance: " + distance.toString());
for (Object key : distance.keySet()) {
listOfEdges.add((Edge) key);
}
for (Object value : distance.values()) {
listOfWeights.add((Integer) value);
}
sortedMap = sortHashMapByValuesD(distance);
//System.out.println("list of nodes: "+ listOfNodes);
parent = new int[listOfNodes.size()];
System.out.println("sorted by weights: "+sortedMap.toString());
System.out.println(kruskalAlgo(sortedMap));
}
else{
System.out.println(0);
}
}
public static void makeSet(int x){
parent[x-1] = x;
}
public static int find(int x){
//System.out.println("FIND ==> x: " + x + ".parent = " + parent[x-1] );
if(parent[x-1] == x){
return x;
}
return find(parent[x-1]);
}
public static void union(int x, int y){
//System.out.println("parent[0]: "+parent[0]);
parent[x-1] = y;
System.out.println("x: " + x + " UNION parent[x-1]: " + parent[x-1] + " y " + y );
}
public static int kruskalAlgo(HashMap<Edge, Integer> s){
parent[0] = 0;
for(int i = 0; i < parent.length; i++){
makeSet(listOfNodes.get(i).getId());
//System.out.println("parent is: "+parent[i] + " for node"+ listOfNodes.get(i));
}
// for each edge (u,v) ∈ G, taken in increasing order by weight
int min = 0;
int edgeNumber = 0;
for (Edge key : s.keySet()) {
if(edgeNumber == listOfNodes.size()-1){
//System.out.println("edgeNumber: "+ edgeNumber);
//System.out.println("listOfNodes.size()-1: "+ (listOfNodes.size()-1));
return min;
}
Node u = key.getFromNode();
//System.out.println(u);
Node v = key.getToNode();
//System.out.println(v);
if(find(u.getId()) != find (v.getId())){
min += key.getWeight();
union(u.getId(),v.getId());
System.out.println(key + " weight is: " + key.getWeight());
edgeNumber++;
}
}
return min;
}
public static ArrayList<Edge> findSet(Node v){
ArrayList<Edge> nodes = new ArrayList<Edge>();
return nodes;
}
//make an ordered listed by increasing weights
public LinkedHashMap<Edge, Integer> sortHashMapByValuesD(HashMap<Edge, Integer> newMap) {
//list of edges
List<Edge> mapKeys = new ArrayList<Edge>(newMap.keySet());
//list of nodes
List<Integer> mapValues = new ArrayList<Integer>(newMap.values());
//sort the nodes
Collections.sort(mapValues);
LinkedHashMap<Edge, Integer> sortedMap = new LinkedHashMap<Edge, Integer>();
Iterator<Integer> valueIt = mapValues.iterator();
while (valueIt.hasNext()) {
Object val = valueIt.next();
Iterator<Edge> keyIt = mapKeys.iterator();
while (keyIt.hasNext()) {
Object key = keyIt.next();
String comp1 = newMap.get(key).toString();
String comp2 = val.toString();
if (comp1.equals(comp2)){
newMap.remove(key);
mapKeys.remove(key);
sortedMap.put((Edge)key, (Integer)val);
break;
}
}
}
return sortedMap;
}
}
最佳答案
我认为问题可能出在您的 union 实现上:
public static void union(int x, int y){
parent[x-1] = y;
}
问题是如果 x 已经被加入到一个集合中,它就会有一个你覆盖的父级。
解决方案是连接两个候选节点的根而不是叶节点:
public static void union(int x, int y){
x=find(x);
y=find(y);
parent[x-1] = y;
}
顺便说一下,关于这个不相交集算法的一个很好的描述,加上通过“按等级联合”和“路径压缩”使它更有效的提示在维基百科上 this page .
关于java - 我使用 union-find 数据结构实现 Kruskal 算法有什么问题。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20305590/
我正在尝试用 Python (scipy) 替换 Python 脚本中的一些 rpy2 代码。在这种情况下,我需要用 (Python: kruskal.test() ) 替换 Kruskal-Wall
一 构建后的图 二 代码 package graph.kruskal; import java.util.ArrayList; import java.util.Collections; impor
一 点睛 构造最小生成树还有一种算法,即 Kruskal 算法:设图 G=(V,E)是无向连通带权图,V={1,2,...n};设最小生成树 T=(V,TE),该树的初始状态只有 n 个节点而无边的非
来这里之前我已经努力尝试并做了我的研究。下面的代码崩溃了,我怀疑滥用了 cout。 (这不应该是最好的实现,但暂时不是 pb) 有经验的人能看出问题出在哪里吗? 提前致谢 #include #inc
据说Kruskal构造MST的算法是贪心的,但是该算法选择的是全局最小值而不是局部最小值,这与Prim的算法不同。谁能解释一下 Kruskal 算法为何被视为贪婪算法? 最佳答案 我们在克鲁斯卡尔做什
假设G是一个有n个顶点的无向图,每对顶点之间有加权边。你能按以下结构构造一棵树吗: v_1-v_2-v_3-...-v_n 使得树中的每个节点对应于 G 中的一个顶点,并且每个节点除叶子外只有一个子节
我正在学习 Kruskal 的算法,我遇到了几个不同的实现,并且想知道它们之间的权衡是什么。两种实现方式如下: 实现一- 将图中的所有边放入优先队列 PQ- 从 PQ 中移除最小边 e - 如果 e
我对什么是 Kruskal 算法有了基本的了解,这就是我的发现: 该算法基本上是通过合并多棵树来构造一棵最小生成树,它首先根据边的权重对边进行排序。该算法从一个空子图开始,扫描边列表,如果不创建循环,
我正在研究来自 this geeksforgeeks article 的 Kruskal 的 MST .给出的步骤是: 按权重的非降序对所有边进行排序。 选择最小的边。检查它是否与目前形成的生成树形成
我有一个任务,我需要从单元格网格创建一个迷宫。 我使用 Randomized Kruskal's algorithm 成功地做到了如 Wiki 页面所述并使用 Disjoint-set data st
我找到了一个创建 makes 和 finds 方法的教程 public void makeSet(long data) { Node node = new Node();
我发现最小生成树 (MST) 的某些边使用联合查找方法重叠,详见 here ,经过修改 - 使用 float 而不是 integer 权重,使用 integer 值而不是 string ID。下图中的
我打算用 C++ 实现 Kriskal 的算法,但是... Unhandled exception at 0x0127160d in DAA.exe: 0xC0000005: Access viola
我正在计算这样的 kruskal 算法的时间复杂度(请参阅附件中的算法) T(n) = O(1) + O(V) + O(E log E) + O(V log V) = O(E log E)
我正在尝试尽可能高效地实现 Kruskal。 对于运行时效率,使用堆或排序算法对边进行排序有区别吗? 还有哪些其他技术可以使 Kruskal 算法更有效地工作? 最佳答案 这取决于您要解决的确切问题。
我如何使用 Kruskal 算法计算 im R(3.0.0 - Linux x32) 最小生成树? 我使用 igraph (0.6.5) 库创建一个加权全图,如下所示: set.seed(123456
当图有多个连通分量时,我不确定如何实现 Kruskal 算法 根据我对 Kruskal 算法的理解,它反复将最小边添加到集合中。然后,当检查完所有边时,它返回最多的边集。 但是,如果我的图表断开连接怎
虽然我在工作an assignment在 Stanford CS106B C++ 类(class)上,但我大量坚持实现 Kruskal 算法以找到最小生成树。 更具体地说,我无法弄清楚确定是否向树添加
由于 Kruskal 算法是贪心算法,这意味着我们有时可能得不到真正的最小路径。 但是谁能举出一个例子来说明这个算法没有得到最小值? 我不是在寻找复杂性,只是需要一个确实没有得到最佳解决方案的案例。
Here is a Graph我需要使用 Prim 的 和 Kruskal 的 算法找到 G 的最小生成树。 我使用 Prim 算法找到了最小生成树。 Here is my attempt . 我在使
我是一名优秀的程序员,十分优秀!