简体   繁体   中英

Drawing graph for dijkstra algorithm

I've implemented Dijkstra's alorithm but I also want to implement a GUI for it. So I'll have a few quesions for you guys.

public class Dijkstra {

public static void main(String args[]) {

    Vertex v0 = new Vertex("A");
    Vertex v1 = new Vertex("B");
    Vertex v2 = new Vertex("C");
    Vertex v3 = new Vertex("D");
    Vertex v4 = new Vertex("E");
    Vertex v5 = new Vertex("F");
    Vertex v6 = new Vertex("G");
    Vertex v7 = new Vertex("H");

    v0.adjacencies = new Edge[]{new Edge(v1, 9), new Edge(v2, 1), new Edge(v6, 9), new Edge(v3, 2)};
    v1.adjacencies = new Edge[]{new Edge(v0, 9), new Edge(v4, 4)};
    v2.adjacencies = new Edge[]{new Edge(v0, 1), new Edge(v4, 2), new Edge(v5, 5)};
    v3.adjacencies = new Edge[]{new Edge(v0, 2), new Edge(v6, 5), new Edge(v7, 1)};
    v4.adjacencies = new Edge[]{new Edge(v1, 4), new Edge(v2, 2), new Edge(v5, 1)};
    v5.adjacencies = new Edge[]{new Edge(v4, 1), new Edge(v2, 5), new Edge(v6, 1), new Edge(v7, 4)};
    v6.adjacencies = new Edge[]{new Edge(v0, 9), new Edge(v5, 1), new Edge(v3, 5), new Edge(v7, 2)};
    v7.adjacencies = new Edge[]{new Edge(v5, 4), new Edge(v6, 2), new Edge(v3, 1)};

    Vertex[] vertices = {v0, v1, v2, v3, v4, v5, v6, v7};

    computePaths(v0);

    for (Vertex v : vertices) {
        System.out.println("Distance to " + v + ": " + v.getMinDistance());
        List<Vertex> path = getShortestPathTo(v);
        System.out.println("Path: " + path);
    }

}

public static void computePaths(Vertex source) {
    source.setMinDistance(0);

    PriorityQueue<Vertex> vertexQueue = new PriorityQueue<Vertex>();
    vertexQueue.add(source);

    while (!vertexQueue.isEmpty()) {
        Vertex u = vertexQueue.poll();

        for (Edge e : u.adjacencies) {
            Vertex v = e.target;
            int weight = e.weight;
            int distanceThroughU = u.getMinDistance() + weight;

            if (distanceThroughU < v.getMinDistance()) {
                vertexQueue.remove(v);
                v.setMinDistance(distanceThroughU);
                v.previous = u;
                vertexQueue.add(v);
            }
        }
    }
}

public static List<Vertex> getShortestPathTo(Vertex target) {
    List<Vertex> path = new ArrayList<Vertex>();

    for (Vertex vertex = target; vertex != null; vertex = vertex.previous) {
        path.add(vertex);
    }

    Collections.reverse(path);
    return path;
}

}

This is how the implementations looks like (without the GUI). I've seen that there is a library called JUNG for graphs and I downloaded it. I've tried to draw my graph by adding the following code to my main method.

SimpleGraphDraw f = new SimpleGraphDraw();

    DirectedSparseGraph g = new DirectedSparseGraph();
    g.addVertex(v0);
    g.addVertex(v1);
    g.addVertex(v2);
    g.addVertex(v3);
    g.addVertex(v4);
    g.addVertex(v5);
    g.addVertex(v6);
    g.addVertex(v7);
    g.addEdge("Edge1", v0, v1);
    g.addEdge("Edge2", v0, v2);
    g.addEdge("Edge3", v0, v6);
    g.addEdge("Edge4", v0, v3);
    g.addEdge("Edge5", v1, v0);
    g.addEdge("Edge6", v1, v4);
    g.addEdge("Edge7", v2, v0);
    g.addEdge("Edge8", v2, v4);
    g.addEdge("Edge9", v2, v5);

    VisualizationImageServer vs = new VisualizationImageServer(new CircleLayout(g), new Dimension(200, 200));

    JFrame frame = new JFrame();
    frame.getContentPane().add(vs);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);

How can I arrange all of my vertices the way I want them (they are in a circle right now) ?

How can I place the vertex name "A" inside the red circle in the GUI, so each vertex name should be displayed.

How can I add the each weight inside the GUI on top of the line between two vertices ?

Thanks in advance

While I am not familiar with JUNG, I had implemented a GUI for Dijkstra's algorithm for my college project ( Source code ).

It is based on Java Swing's Graphics2D object to draw edges. Since you have already implemented Dijkstra's algorithm, you might be interested in just the code given below for drawing an edge (line with an arrow and label). It uses trigonometry to draw the directional arrow.

private void drawLineSegment(Point from, Point to, Color c, int size, String label, Graphics2D g) {
    g.setColor(c);
    g.setStroke(new BasicStroke(size));
    int x1 = from.getX();
    int y1 = from.getY();
    int x2 = to.getX();
    int y2 = to.getY();
    g.drawLine(x1, y1, x2, y2);
    int sx = (int) ((x1 + x2) / 2.1);
    int sy = (int) ((y1 + y2) / 2.1);
    int cx = (int) ((x1 + x2) / 2);
    int cy = (int) ((y1 + y2) / 2);
    int d = 10;
    double angle = Util.angle360(from, to);
    double anglePlus45 = angle + 45;
    if (anglePlus45 > 360)
        anglePlus45 = anglePlus45 % 360;
    double angleMinus45 = angle - 45;
    if (angleMinus45 < 360)
        angleMinus45 = angleMinus45 + 360;
    anglePlus45 = Math.toRadians(anglePlus45);
    angleMinus45 = Math.toRadians(angleMinus45);
    int ax1 = (int) (cx - d * Math.cos(anglePlus45));
    int ay1 = (int) (cy - d * Math.sin(anglePlus45));
    int ax2 = (int) (cx - d * Math.cos(angleMinus45));
    int ay2 = (int) (cy - d * Math.sin(angleMinus45));
    g.drawLine(cx, cy, ax1, ay1);
    g.drawLine(cx, cy, ax2, ay2);
    g.drawString(label, sx, sy);
}

This is in `src/wban/simulate/view/SwingViewer.java. If you are interested in running the code you could download the runnable jar . Project documentation is available here and here .

To use a different layout algorithm, replace the reference to CircleLayout in your code to a different Layout implementation; JUNG provides several options.

The sample code included as part of the JUNG distribution includes several samples which demonstrate how to use vertex and edge labels.

You might also be interested in the JUNG ShortestPathDemo sample code.

Related questions (on JUNG vertex/edge labels):

Vertex label in JUNG graph visualization

How to add custom vertex labels in JUNG graph visualization?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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