Java判断图中是否存在回路

参考:

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

 

posted @ 2021-09-30 17:16  Mars.wang  阅读(157)  评论(0编辑  收藏  举报