最近正在学习karger-stein随机算法求无向图的全局最小割,想看看实现方法,网上搜的源码都是别的语言的看不太懂。希望有人能提供一份java版本实现karger-stein随机算法求全局最小割的代码,其他语言的看不太懂.。输入的无向图可以用邻接表形式存储并作为输入来处理,如果可以的话加一些注释这样我可能能看懂。感谢各位!
6条回答 默认 最新
- 懒羊羊的南瓜屋 2022-06-06 15:20关注
Kanger.java
package lesson_4; import java.util.*; import java.util.concurrent.ThreadLocalRandom; public class Karger { public static void main(String[] args) { Karger karger = new Karger(); Map<Character, Set<Integer>> graph = karger.getRandomGraph(50, 100); karger.printGraph(graph); int n = graph.size(); int iterationCount = 5 * n * (n - 1); int result = karger.runAlgorithm(graph, iterationCount); System.out.println("Smallest cut – " + result); } public int runAlgorithm(Map<Character, Set<Integer>> graph, int count) { int minCut = Integer.MAX_VALUE; while (count > 0) { Map<Character, Set<Integer>> copy = new HashMap<>(graph); int cutsNumber = randomCut(copy); if (cutsNumber < minCut) minCut = cutsNumber; count--; } return minCut; } // find the smallest cut (edges number) protected int randomCut(Map<Character, Set<Integer>> graph) { int cutsNumber = 0; // create common set of edges Set<Integer> totalSet = new HashSet<>(); for (Map.Entry<Character, Set<Integer>> entry: graph.entrySet()) totalSet.addAll(entry.getValue()); // algorithm is executed until there are 2 vertices left while (graph.size() != 2) { // берется рандомное ребро и запускается шаг алгоритма int randomEdge = getRandomElement(totalSet); kargetStep(graph, randomEdge, totalSet); } // calculation and section print System.out.println("Cut: "); for (Map.Entry<Character, Set<Integer>> entry: graph.entrySet()) { for (Integer edge : entry.getValue()) System.out.print(edge + " "); System.out.println(); cutsNumber = entry.getValue().size(); break; } return cutsNumber; } // execute a step of the algorithm with vertex contraction protected void kargetStep(Map<Character, Set<Integer>> graph, int randomEdge, Set<Integer> totalSet) { // find vertices of this edge Map.Entry<Character, Set<Integer>> firstVertex = null; Map.Entry<Character, Set<Integer>> secondVertex = null; for (Map.Entry<Character, Set<Integer>> entry: graph.entrySet()) { if (entry.getValue().contains(randomEdge)) { if (firstVertex == null) firstVertex = entry; else secondVertex = entry; } } assert firstVertex != null; assert secondVertex != null; // Two vertices converge into one Set<Integer> commonVertex = new HashSet<>(firstVertex.getValue()); commonVertex.addAll(secondVertex.getValue()); // Loops are removed Set<Integer> vertexWithoutLoops = new HashSet<>(); for (Integer edge : commonVertex) { boolean loop = firstVertex.getValue().contains(edge) && secondVertex.getValue().contains(edge); if (!loop) vertexWithoutLoops.add(edge); else totalSet.remove(edge); } // The first vertex is updated, the second one is deleted graph.put(firstVertex.getKey(), vertexWithoutLoops); graph.entrySet().remove(secondVertex); } // remove a random element from the set protected <T> T getRandomElement(Set<T> set) { int index = ThreadLocalRandom.current().nextInt(set.size()); int i = 0; for (T e : set) { if (i == index) { set.remove(e); return e; } i++; } return null; } // get static created graph protected Map<Character, Set<Integer>> getStaticGraph() { Map<Character, Set<Integer>> graph = new HashMap<>(); graph.put('A', Set.of(1, 2)); graph.put('B', Set.of(1, 3)); graph.put('C', Set.of(2, 4, 5)); graph.put('D', Set.of(3, 4, 6, 7)); graph.put('E', Set.of(5, 6, 8)); graph.put('F', Set.of(7, 8, 9)); graph.put('G', Set.of(9)); return graph; } // get randomly generated graph protected Map<Character, Set<Integer>> getRandomGraph(int vertexCount, int edgeCount) { Map<Character, Set<Integer>> graph = new HashMap<>(); ThreadLocalRandom random = ThreadLocalRandom.current(); // create graph without edges char[] vertexes = new char[vertexCount]; char key = 'A'; for (int i = 0; i < vertexCount; i++) { vertexes[i] = key; graph.put(key, new HashSet<>()); key++; } for (int i = 0; i < edgeCount; i++) { // obtain two random vertices int firstIndex = Math.abs(random.nextInt(vertexCount)); int secondIndex = Math.abs(random.nextInt(vertexCount)); while (secondIndex == firstIndex) secondIndex = Math.abs(random.nextInt(vertexCount)); char firstVertex = vertexes[firstIndex]; char secondVertex = vertexes[secondIndex]; // add common edge to the vertices graph.get(firstVertex).add(i); graph.get(secondVertex).add(i); } // remove vertices without edges from the graph graph.entrySet().removeIf(entry -> entry.getValue().size() == 0); return graph; } // print graph to console protected void printGraph(Map<Character, Set<Integer>> graph) { for (Map.Entry<Character, Set<Integer>> entry: graph.entrySet()) { System.out.println(entry); } } }
KargerStein.java
package lesson_4; import java.util.HashSet; import java.util.Map; import java.util.Set; public class KargerStein extends Karger { public static void main(String[] args) { KargerStein kargerStein = new KargerStein(); Map<Character, Set<Integer>> graph = kargerStein.getRandomGraph(50, 100); int result = kargerStein.runSteinAlgorithm(graph); System.out.println("Smallest cut – " + result); } // run the algorithm public int runSteinAlgorithm(Map<Character, Set<Integer>> graph) { int iterationCount = (int) Math.round(Math.sqrt(graph.size())); // graph is shrinking contractGraph(graph); // run main algorithm return runAlgorithm(graph, iterationCount); } // pull the graph several times private void contractGraph(Map<Character, Set<Integer>> graph) { int size = (int) Math.floor(Math.sqrt(graph.size())); Set<Integer> totalSet = new HashSet<>(); for (Map.Entry<Character, Set<Integer>> entry: graph.entrySet()) totalSet.addAll(entry.getValue()); while (graph.size() != size) { int randomEdge = getRandomElement(totalSet); kargetStep(graph, randomEdge, totalSet); } } }
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报 编辑记录
悬赏问题
- ¥20 双非跨考工科哪个专业和方向就业前景好?
- ¥20 求会6sv辐射传输模型,辅导(可py6s🙏🏻有偿
- ¥15 .xla后缀的文件拖到excel里什么内容也没有怎么办
- ¥20 Workbench中Mechanical打不开、闪退是什么原因?
- ¥240 MapReduce应用实践 学生课程
- ¥15 hlss视频显示AUTHORITY_INVALID
- ¥15 MAX9296A+MAX96717,美信gmsl解串有人做过吗?
- ¥15 求帮我解决一下inode 爆满的问题(有偿)
- ¥15 关于#vscode#的问题:布料滤波算法中C++实现pcl在Vscode中pcl库没有#include <pcl>
- ¥15 fpga:ov5640采集tft显示