参考:
https://blog.csdn.net/lezg_bkbj/article/details/11299335
还是上一篇的图
/** * @Author : * @Date : 2021/9/30 16:16 * @Description: 判断一个图是否存在回路 * 方法1:利用减枝的方法 * 如果G为有向图: * 1)首先删除入度为0的点,并且将对应的和该点相连的点的入度-1。 * 2)重复过程1),直到没有入度为0的点,如果还有没被删除的节点,则该有向图一定存在回路 * 如果G为无向图: * 1)首先删除所有度数<=1的点,然后将与这些点相连的所有点的度数-1,然后将所有度数为1的点加入队列中 * 2)对队列中的每个点,重复过程1),如果还有没被删除的节点,那么证明该图一定存在回路。 */ public class Loop { public static void main(String[] args) { WeightGraph weightGraph =new WeightGraph(); Set<String> node = Sets.newLinkedHashSet("v1", "v2", "v3", "v4", "v5", "v6"); List<WeightEdge<String, String, Integer>> edge = Lists.newArrayList(); edge.add(new WeightEdge<>("v1", "v2", 10)); edge.add(new WeightEdge<>("v2", "v3", 7)); edge.add(new WeightEdge<>("v4", "v3", 4)); edge.add(new WeightEdge<>("v4", "v5", 7)); edge.add(new WeightEdge<>("v6", "v5", 1)); weightGraph.setNodes(node); weightGraph.setEdgeList(edge); boolean loop = isLoop(weightGraph); System.out.println(loop); System.out.println("========================="); System.out.println("loop1"); WeightGraph weightGraph1 = WeightGraph.buildGraph(); boolean loop1 = isLoop(weightGraph1); System.out.println(loop1); } /** * 如果有入度为0的点,将它从图中删除,并删除相关的边, * 继续循环知道没有入度为0的点,如果此时图的顶点还不为空,则说明图中有回路 * @param graph * @return */ public static boolean isLoop(WeightGraph graph) { Map<String, Integer> inDegree = getInDegree(graph); //如果有入度为0的点,将它删除,并把所有相关的点入度-1 while (inDegree.containsValue(0)) { System.out.println(inDegree); Set<String> key = getKeyByValue(inDegree, 0); for (String s : key) { graph = graph.removeNode(s); } inDegree = getInDegree(graph); } System.out.println(inDegree); return graph.getNodes().size() != 0; } /** * 返回一条图的入度map * 对无边的节点也要进行初始化,因为判断入度的时候需要 * @param weightGraph * @return */ public static Map<String, Integer> getInDegree(WeightGraph weightGraph) { Map<String, Integer> map = new HashMap<>(); Set<String> nodes = weightGraph.getNodes(); for (String node : nodes) { map.put(node,0); } List<WeightEdge<String, String, Integer>> edgeList = weightGraph.getEdgeList(); for (WeightEdge<String, String, Integer> edge : edgeList) { String end = edge.getEnd(); map.computeIfPresent(end, (k, v) -> v + 1); } return map; } public static <K, V> Set<K> getKeyByValue(Map<K, V> map, V val) { Set<K> set = new HashSet<>(); for (Map.Entry<K, V> entry : map.entrySet()) { if (entry.getValue().equals(val)) { set.add(entry.getKey()) ; } } return set; } }
输出:
{v6=0, v1=0, v2=1, v3=2, v4=0, v5=2} {v2=0, v3=1, v5=0} {v3=0} {} false ========================= loop1 {v6=1, v1=1, v2=2, v3=2, v4=2, v5=2} true