Graph 查找有向循环图中的所有路径

Graph 查找有向循环图中的所有路径,graph,networkx,path-finding,Graph,Networkx,Path Finding,实际上,我正在制作一个基于文本的有向图,将每个单词作为图中的一个节点,边位于文本句子中两个相邻单词之间 我需要找到从开始节点到结束节点的所有路径 有任何Python库可以帮助我完成这项任务吗 实际上,我试着用networkx来做这件事,但networkx的问题是它只输出简单的路径(简单路径对于输入中的一个长句来说非常短,并且不包含该句的很多信息)。我的任务需要更复杂的路径。您需要为DFS(深度优先搜索)或BFS(广度优先搜索)编写算法来收集所有路径。下面是一个示例,用于收集用java编写的从源到

实际上,我正在制作一个基于文本的有向图,将每个单词作为图中的一个节点,边位于文本句子中两个相邻单词之间

我需要找到从开始节点到结束节点的所有路径

有任何Python库可以帮助我完成这项任务吗


实际上,我试着用networkx来做这件事,但networkx的问题是它只输出简单的路径(简单路径对于输入中的一个长句来说非常短,并且不包含该句的很多信息)。我的任务需要更复杂的路径。

您需要为
DFS
(深度优先搜索)或
BFS
(广度优先搜索)编写算法来收集所有路径。下面是一个示例,用于收集用java编写的从
目标
的所有可能路径

    package com.nirav.modi;

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedHashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.NoSuchElementException;
    import java.util.Set;

    class Graph<T> implements Iterable<T> {

        /*
         * A map from nodes in the graph to sets of outgoing edges. Each set of
         * edges is represented by a map from edges to doubles.
         */
        private final Map<T, Map<T, Double>> graph = new HashMap<T, Map<T, Double>>();

        /**
         * Adds a new node to the graph. If the node already exists then its a
         * no-op.
         * 
         * @param node
         *            Adds to a graph. If node is null then this is a no-op.
         * @return true if node is added, false otherwise.
         */
        public boolean addNode(T node) {
            if (node == null) {
                throw new NullPointerException("The input node cannot be null.");
            }
            if (graph.containsKey(node))
                return false;

            graph.put(node, new HashMap<T, Double>());
            return true;
        }

        /**
         * Given the source and destination node it would add an arc from source to
         * destination node. If an arc already exists then the value would be
         * updated the new value.
         * 
         * @param source
         *            the source node.
         * @param destination
         *            the destination node.
         * @param length
         *            if length if
         * @throws NullPointerException
         *             if source or destination is null.
         * @throws NoSuchElementException
         *             if either source of destination does not exists.
         */
        public void addEdge(T source, T destination, double length) {
            if (source == null || destination == null) {
                throw new NullPointerException("Source and Destination, both should be non-null.");
            }
            if (!graph.containsKey(source) || !graph.containsKey(destination)) {
                throw new NoSuchElementException("Source and Destination, both should be part of graph");
            }
            /* A node would always be added so no point returning true or false */
            graph.get(source).put(destination, length);
        }

        /**
         * Removes an edge from the graph.
         * 
         * @param source
         *            If the source node.
         * @param destination
         *            If the destination node.
         * @throws NullPointerException
         *             if either source or destination specified is null
         * @throws NoSuchElementException
         *             if graph does not contain either source or destination
         */
        public void removeEdge(T source, T destination) {
            if (source == null || destination == null) {
                throw new NullPointerException("Source and Destination, both should be non-null.");
            }
            if (!graph.containsKey(source) || !graph.containsKey(destination)) {
                throw new NoSuchElementException("Source and Destination, both should be part of graph");
            }
            graph.get(source).remove(destination);
        }

        /**
         * Given a node, returns the edges going outward that node, as an immutable
         * map.
         * 
         * @param node
         *            The node whose edges should be queried.
         * @return An immutable view of the edges leaving that node.
         * @throws NullPointerException
         *             If input node is null.
         * @throws NoSuchElementException
         *             If node is not in graph.
         */
        public Map<T, Double> edgesFrom(T node) {
            if (node == null) {
                throw new NullPointerException("The node should not be null.");
            }
            Map<T, Double> edges = graph.get(node);
            if (edges == null) {
                throw new NoSuchElementException("Source node does not exist.");
            }
            return Collections.unmodifiableMap(edges);
        }

        /**
         * Returns the iterator that travels the nodes of a graph.
         * 
         * @return an iterator that travels the nodes of a graph.
         */
        @Override
        public Iterator<T> iterator() {
            return graph.keySet().iterator();
        }
    }

    /**
     * Given a connected directed graph, find all paths between any two input
     * points.
     */
    public class GraphTester<T> {

        private final Graph<T> graph;

        /**
         * Takes in a graph. This graph should not be changed by the client
         */
        public GraphTester(Graph<T> graph) {
            if (graph == null) {
                throw new NullPointerException("The input graph cannot be null.");
            }
            this.graph = graph;
        }

        private void validate(T source, T destination) {

            if (source == null) {
                throw new NullPointerException("The source: " + source + " cannot be  null.");
            }
            if (destination == null) {
                throw new NullPointerException("The destination: " + destination + " cannot be  null.");
            }
            if (source.equals(destination)) {
                throw new IllegalArgumentException("The source and destination: " + source + " cannot be the same.");
            }
        }

        /**
         * Returns the list of paths, where path itself is a list of nodes.
         * 
         * @param source
         *            the source node
         * @param destination
         *            the destination node
         * @return List of all paths
         */
        public List<List<T>> getAllPaths(T source, T destination) {
            validate(source, destination);

            List<List<T>> paths = new ArrayList<List<T>>();
            recursive(source, destination, paths, new LinkedHashSet<T>());
            return paths;
        }

        // so far this dude ignore's cycles.
        private void recursive(T current, T destination, List<List<T>> paths, LinkedHashSet<T> path) {
            path.add(current);

            if (current == destination) {
                paths.add(new ArrayList<T>(path));
                path.remove(current);
                return;
            }

            final Set<T> edges = graph.edgesFrom(current).keySet();

            for (T t : edges) {
                if (!path.contains(t)) {
                    recursive(t, destination, paths, path);
                }
            }

            path.remove(current);
        }

        public static void main(String[] args) {
            Graph<String> graphFindAllPaths = new Graph<String>();
            graphFindAllPaths.addNode("A");
            graphFindAllPaths.addNode("B");
            graphFindAllPaths.addNode("C");
            graphFindAllPaths.addNode("D");

            graphFindAllPaths.addEdge("A", "B", 10);
            graphFindAllPaths.addEdge("A", "C", 10);
            graphFindAllPaths.addEdge("B", "D", 10);
            graphFindAllPaths.addEdge("C", "D", 10);

            graphFindAllPaths.addEdge("B", "C", 10);
            graphFindAllPaths.addEdge("C", "B", 10);

            GraphTester<String> findAllPaths = new GraphTester<String>(graphFindAllPaths);
            List<List<String>> allPaths = findAllPaths.getAllPaths("A", "D");
            System.out.println(allPaths);

            // assertEquals(paths, findAllPaths.getAllPaths("A", "D"));
        }
    }
package com.nirav.modi;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.HashMap;
导入java.util.Iterator;
导入java.util.LinkedHashSet;
导入java.util.List;
导入java.util.Map;
导入java.util.NoSuchElementException;
导入java.util.Set;
类图实现了Iterable{
/*
*从图中的节点到输出边集的映射
*边由从边到双边的贴图表示。
*/
私有最终映射图=新HashMap();
/**
*将新节点添加到图形中。如果该节点已存在,则其
*禁止操作。
* 
*@param节点
*添加到图形中。如果节点为null,则这是一个no-op。
*@如果添加了节点,则返回true,否则返回false。
*/
公共布尔addNode(T节点){
if(node==null){
抛出新的NullPointerException(“输入节点不能为null”);
}
if(图.containsKey(节点))
返回false;
put(node,newhashmap());
返回true;
}
/**
*给定源节点和目标节点,它将从源节点到目标节点添加一个弧
*目标节点。如果弧已存在,则值为
*更新了新值。
* 
*@param源
*源节点。
*@param目的地
*目标节点。
*@param长度
*如果长度如果
*@抛出NullPointerException
*如果源或目标为空。
*@NoSuchElementException
*如果目标的任一源不存在。
*/
公共无效补遗(T源、T目标、双倍长度){
如果(源==null | |目标==null){
抛出新的NullPointerException(“源和目标,两者都应为非null”);
}
如果(!graph.containsKey(源)| |!graph.containsKey(目标)){
抛出新的NoSuchElementException(“源和目标,两者都应该是图形的一部分”);
}
/*始终添加一个节点,这样就不会返回true或false*/
graph.get(源)、put(目的地、长度);
}
/**
*从图形中删除边。
* 
*@param源
*如果是源节点。
*@param目的地
*如果选择目标节点。
*@抛出NullPointerException
*如果指定的源或目标为空
*@NoSuchElementException
*如果图形既不包含源也不包含目标
*/
公共无效删除(T源,T目标){
如果(源==null | |目标==null){
抛出新的NullPointerException(“源和目标,两者都应为非null”);
}
如果(!graph.containsKey(源)| |!graph.containsKey(目标)){
抛出新的NoSuchElementException(“源和目标,两者都应该是图形的一部分”);
}
graph.get(源)、remove(目标);
}
/**
*给定一个节点,返回该节点外部的边,作为不可变的
*地图。
* 
*@param节点
*应查询其边的节点。
*@返回离开该节点的边的不可变视图。
*@抛出NullPointerException
*如果输入节点为空。
*@NoSuchElementException
*如果节点不在图形中。
*/
公共地图边缘自(T节点){
if(node==null){
抛出新的NullPointerException(“节点不应为null”);
}
映射边=graph.get(节点);
如果(边==null){
抛出新的NoSuchElementException(“源节点不存在”);
}
返回集合。不可修改的映射(边);
}
/**
*返回遍历图的节点的迭代器。
* 
*@返回一个遍历图节点的迭代器。
*/
@凌驾
公共迭代器迭代器(){
返回graph.keySet().iterator();
}
}
/**
*给定一个连通有向图,找出任意两个输入之间的所有路径
*要点。
*/
公共类GraphTester{
私有最终图;
/**
*接收图形。客户端不应更改此图形
*/
公共图形酯(图形){
if(图==null){
抛出新的NullPointerException(“输入图形不能为null”);
}
this.graph=图形;
}
私有无效验证(T)