java - 查找加权有向图中两个指定顶点之间是否存在任何路径

标签 java algorithm data-structures graph

我正在尝试实现一种方法 isReachable(E fromKey, E toKey)以确定图中两个指定顶点之间是否存在任何路径。我有一个通用类 Graph<E>使用两个内部数据结构,VertexEdge , 来表示图的顶点和边。这是相关代码:

public class Graph<E extends Comparable<E>> implements GraphAPI<E>
{
    /*
     * number of vertices (size of this graph)
     */
    private long order;
    /**
     * pointer to the list of vertices
     */
    private Vertex first;

    /**
     * A vertex of a graph stores a data item and references
     * to its edge list and the succeeding vertex. The data
     * object extends the comparable interface.
     */
    private class Vertex
    {
        /**
         * pointer to the next vertex
         */
        public Vertex pNextVertex;
        /**
         * the data item
         */
        public E data;
        /**
         * indegree
         */
        public long inDeg;
        /**
         * outdegree
         */
        public long outDeg;
        /**
         * pointer to the edge list
         */
        public Edge pEdge;
        /**
         * Field for tracking vertex accesses
         */
        public long processed;
    }

    /**
     * An edge of a graph contains a reference to the destination
     * vertex, a reference to the succeeding edge in the edge list and
     * the weight of the directed edge.
     */
    private class Edge
    {
        /**
         * pointer to the destination vertex
         */
        public Vertex destination;
        /**
         * weight on this edge
         */
        public Double weight;
        /**
         * pointer to the next edge
         */
        public Edge pNextEdge;
    }
    /**
     * Constructs an empty weighted directed graph
     */
    public Graph()
    {
        first = null;
        order = 0;
    }
}

这是我的思考过程: (1)遍历顶点列表直到到达包含指定fromKey的顶点; (2) 将每个相邻的 Vertex 添加到 fromKey排队; (3) 当队列不为空时,检索并移除队列头部的 Vertex 并将其与 toKey 的键进行比较; (4) 如果匹配则返回真,否则继续搜索每个相邻顶点的边列表。

到目前为止,这是我的方法代码:

/**
 * Determines whether there is an outdirected path between two
 * vertices.
 * @param fromKey - search key of the originating vertex.
 * @param toKey - search key of the destination vertex.
 * @return true on success or false on failure.
 */
public boolean isReachable(E fromKey, E toKey)
{
    ArrayList<Vertex> queue = new ArrayList<Vertex>();
    E tmpKey = fromKey;
    Edge tmpEdge;
    Vertex tmp = first;
    while (tmp != null)
    {
        if (tmp.data.equals(tmpKey))
        {
            tmpEdge = tmp.pEdge;
            while (tmpEdge != null)
            {
                queue.add(tmpEdge.destination);
                tmpEdge = tmpEdge.pNextEdge;
            }
            tmp = first;
            tmpKey = queue.remove(0).data;
            if (tmpKey.equals(toKey))
                return true;
        }
        tmp = tmp.pNextVertex;
    }
    return false;
}

当两个指定键之间的路径存在时它起作用,但当不存在时抛出索引越界错误。

这是我为样本数据追踪的邻接表:

1  -> null
2  -> 1 -> 11 -> 12 -> null
3  -> 2 -> 4 -> null
4  -> null
5  -> 4 -> null
6  -> 5 -> 7 -> 13 -> 14 -> 15 -> null
7  -> 12 -> null
8  -> 7 -> 9 -> 10 -> 11 -> 12 -> null
9  -> 1 -> null
10 -> null
11 -> 1 -> 12 -> null
12 -> null
13 -> null
14 -> 2 -> 3 -> null
15 -> 3 -> 5 -> 14 -> null

当我调用 isReachable(5, 3) ,例如,我得到一个索引越界异常。但是,如果我在 (15, 2) 上调用该方法,它会返回 true。

我不太确定从这里到哪里去。一位 friend 建议尝试使用 BFS 方法来解决这个问题,但我并没有真正听从他的解释。我在正确的轨道上吗?感谢您的帮助。

最佳答案

这是一个基本的图搜索算法,以google“广度优先搜索”为起点。您需要跟踪您访问过的节点,我认为您还没有这样做。

此外,正如我在评论中所说,不要使用 ArrayList 来维护队列,remove 操作很慢,尤其是在开头删除元素数组,因为您必须将所有内容复制 1。直接使用 Queue ( https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html )

关于java - 查找加权有向图中两个指定顶点之间是否存在任何路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43058944/

相关文章:

java - 最好的做法是始终使用访问器方法,即使是在访问本地状态时也是如此吗?

java - Ubuntu,Java,找不到适合 jdbc :postgresql 的驱动程序

algorithm - 生成最长的位序列,其中所有 5 位连续子序列都是唯一的

c++ - 磁盘支持的 STL 容器类?

java - 简单的java层次结构问题

java - 映射 SQL-Server 日期时间列

java - 如何使用比较器和迭代器对整数 vector 进行排序?

algorithm - 为什么我们使用最大流方法来解决最大二分匹配?

algorithm - 二叉搜索树改组和重置

c - "Robot Arm moving block stacks"C 编程挑战