Question

I have created a java program of which starts with 1 vertex and from there it adds one vertice and 2 edges per cycle. It uses the Static Layout

Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);
vv = new VisualizationViewer<Number, Number>(staticLayout, new Dimension(550, 550));

This is going to sound very un-technical, but the graph just doesn't look random enough, basically what i mean by this, is that every time it gets run they always seems to cluster a lot all the way around the edges of the graph, while very few get anywhere near the center. My program typically uses 100 generated verties and i will end up with half a dozen in the center and the others all round the edges.

Below is a random example that i just created just now.

Perhaps if someone could confirm that this is actually random, or if not if there is a way to get around this problem or if I've set something up wrong. As i wish to have the nodes as random as possible.

Any help would be appreciated. Thanks

Random Example

Below is the relevant code to the applet. involving its set up.

public class AnimatingAddNodeDemo extends JApplet {

        //create a graph
        Graph<Number, Number> ig = Graphs.synchronizedUndirectedGraph(new UndirectedSparseMultigraph<Number, Number>());

        ObservableGraph<Number, Number> og = new ObservableGraph<Number, Number>(ig);
        og.addGraphEventListener(new GraphEventListener<Number, Number>() {

            public void handleGraphEvent(GraphEvent<Number, Number> evt) {
                //System.err.println("got " + evt);
            }
        });
        this.g = og;
        //create a graphdraw
        layout = new FRLayout<Number, Number>(g);
        layout.setSize(new Dimension(600, 600));
        setSize(700, 700);
        Relaxer relaxer = new VisRunner((IterativeContext) layout);
        relaxer.stop();
        relaxer.prerelax();

        Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);
        vv = new VisualizationViewer<Number, Number>(staticLayout, new Dimension(550, 550));

        JRootPane rp = this.getRootPane();
        rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);

        getContentPane().setLayout(new BorderLayout());
    }

    Integer v_prev = null;

    public void process() {

        vv.getRenderContext().getPickedVertexState().clear();
        vv.getRenderContext().getPickedEdgeState().clear();
        try {
            if (g.getVertexCount() < 100) {
                //add a vertex

                Integer v1 = nodeCount;
                g.addVertex(v1);
                nodeCount++;
                System.out.println("adding vertex " + v1);
                vv.getRenderContext().getPickedVertexState().pick(v1, true);
                j.setText(myText);

                // wire it to some edges
                if (v_prev != null) {
                    Integer edge = edgeCount;
                    //vv.getRenderContext().getPickedEdgeState().pick(edge, true);

                    // let's connect to a random vertex, too!

                    int rand = (int) (Math.random() * (edgeCount-1)); // because there is a 0 node
                    while (v1.equals(rand)) {
                        System.out.println("avoided connecting to myself");
                        rand = (int) (Math.random() * (edgeCount-1)); // because there is a 0 node
                    }

                    edgeCount++;
                    g.addEdge(edge, rand, v1);  //add an edge called var1, between the nodes var2 and var3
                    vv.getRenderContext().getPickedEdgeState().pick(edge, true);
                    System.out.println("Adding edge " + edge + " between " + rand + " & " + v1 + "()");
                }

                v_prev = v1;
                layout.initialize();

                Relaxer relaxer = new VisRunner((IterativeContext) layout);
                relaxer.stop();
                relaxer.prerelax();
                vv.getRenderContext().getMultiLayerTransformer().setToIdentity();
                vv.repaint();

            } else {
                done = true;
            }

        } catch (Exception e) {
            System.out.println(e);
        }
    }


    public static void main(String[] args) {
        AnimatingAddNodeDemo and = new AnimatingAddNodeDemo();
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(and);

        and.init();
        and.start();
        frame.pack();
        //frame.setVisible(true);
    }
}
Was it helpful?

Solution

The reason your graph isn't random likely stems from the fact that you are passing a FRLayout to the constructor.

layout = new FRLayout<Number, Number>(g);
// ...
Layout<Number, Number> staticLayout = new StaticLayout<Number, Number>(g, layout);

You could make your own random layout class by extending AbstractLayout. But, according to the JavaDoc, StaticLayout will randomly layout nodes if you exclude the second constructor argument.

Layout<Number, Number> staticLayout = new StaticLayout(Number, Number>(g);

OTHER TIPS

I Didn't get to a conclusion on whether or not it is random. So instead when i create each vertex i decided to set the particular co-ordinate of the vertex using layout.setLocation(v1, x, y) With making x and y using math.random() and multiplying it by the width and height of my applet.

Therefore i now know that it is random.


EDIT

This actually seemed to work, however it actually did not, I had to remove the FRLayout. It turns out FRLayout will not let you set your own locations because of what the algorithm does.

FRLayout is a force directed Layout that will reposition the vertices according to the topology of the graph.

So i therefore changed the FRLayout to StaticLayout, removed a few things that worked only with FRLayout and it works correctly now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top