简体   繁体   English

获取两个图顶点之间的边列表

[英]Get Edge list between two graph Vertex

I have the own data structure for the graph, and I need the implementation method: 我有自己的图形数据结构,并且需要实现方法:

List<Edge<T>> getPath(T start, T finish)

Performance not important, I search the simplest and most readable way. 性能并不重要,我搜索最简单,最易读的方式。 But my data structure should support the directed and undirected graph types and I stuck with it. 但是我的数据结构应该支持有向图和无向图类型,因此我坚持使用它。

public class Graph<T> {

    private boolean isDirected = false;

    private Map<Vertex<T>, List<Edge<T>>> graph = new HashMap<>();

    public Graph() {
    }

    public Graph(boolean isDirected) {
        this.isDirected = isDirected;
    }

    public List<Edge<T>> getPath(T start, T finish) {
        if (start.equals(finish)) {
            return new ArrayList<>();
        }

        // TODO here is the method I'm stuck with.    
        if (isDirected) {
            // Call search for directed graph
        } else {
            // Call search for undirected graph
        }
    }

    public void addEdge(T first, T second) {
        final Vertex<T> master = new Vertex<>(first);
        final Vertex<T> slave = new Vertex<>(second);

        final Set<Vertex<T>> vertices = graph.keySet();
        if (!vertices.contains(master) || !vertices.contains(slave)) {
            throw new IllegalArgumentException();
        }

        graph.get(master).add(new Edge<>(master, slave));

        if (!isDirected) {
            graph.get(slave).add(new Edge<>(slave, master));
        }
    }

    public void addVertex(T value) {
        final List<Edge<T>> result = graph.putIfAbsent(new Vertex<>(value), new ArrayList<>());
        if (result != null) {
            throw new IllegalArgumentException();
        }
    }
}

This Vertex and Edge class: 此“ VertexEdge类:

@Data
@AllArgsConstructor
@EqualsAndHashCode
public class Vertex<T> {
    private T value;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Edge<T> {
    private Vertex<T> first;
    private Vertex<T> second;
}

I will be very grateful for Your help. 我将非常感谢您的帮助。

It is not totally clear what kind of path you want to find. 您还不确定要找到哪种路径。 The shortest path, any path,...? 最短的路径,任何路径,...?

If you want to find the shortest path, A* is a really simple algorithm to implement. 如果您想找到最短的路径,则A *是一种非常简单的算法。 The pseudo code can be found here . 伪代码可以在这里找到。 A* is a best-first search algorithm for a weighted graph (Eg the distance of an edge or another kind of cost to travel on the edge like time). A *是加权图的最佳优先搜索算法(例如,一条边的距离或另一条像时间一样在边上行驶的成本)。 The algorithm uses a heuristic function to select the next node/vertex to evaluate. 该算法使用启发式功能选择要评估的下一个节点/顶点。 A* basically repeats the following steps: A *基本上重复以下步骤:

  • Select a next node/vertex which has not already been visited. 选择尚未访问的下一个节点/顶点。 The selection is made using the heuristic function 使用启发式功能进行选择
  • If this new node equals the goal position, return the shortest path found 如果此新节点等于目标位置,则返回找到的最短路径
  • Evaluate all paths currently known and select the one with the lowest cost 评估当前已知的所有路径并选择成本最低的路径

I could also provide a Java code snippet (based on the pseudo code) if it's necessary. 如果需要,我还可以提供一个Java代码段(基于伪代码)。 Be aware that the pseudo code in the end constructs the shortest path backwards (from goal to start). 请注意,伪代码最终会构造出最短的反向路径(从目标到起点)。

You are also using a generic for your graph. 您还为图形使用泛型。 Both your Vertext and Edge class use this generic. 您的VertextEdge类都使用此泛型。 Let's assume that this generic T is a double . 假设此通用Tdouble In your code this means that your Vertex is only a one-dimensional double . 在您的代码中,这意味着您的Vertex只是一维double This does not make sense when you want to represent a graph of 2D or 3D points. 当您要表示2D或3D点的图形时,这没有任何意义。

Is it even really necessary to use this generic? 甚至真的有必要使用此泛型吗? Wouldn't it be sufficient to simply support vertices which consists of floats, doubles or integers? 仅支持由浮点数,双精度数或整数组成的顶点是否足够? Using a generic type or more abstract class (like Number ) might give some problems when you for example want to compute the distance between vertices. 例如,当您想计算顶点之间的距离时,使用泛型类型或更抽象的类(例如Number )可能会带来一些问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM