2013-10-31 49 views
1

我创建了一个java程序,该程序以1个顶点开始,从那里它每个周期添加一个顶点和2个边。它采用静态布局随机化顶点位置JUNG

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

这是要健全非常联合国的技术,而图形只是看起来不足够的随机,基本上是什么意思呢,就是每次被运行时,他们似乎总是在图的边缘周围聚集很多,而很少到达中心附近的任何地方。我的程序通常使用100个生成的顶点,我将在中心结束半打,其他所有结点都在边缘。

下面是我刚刚创建的一个随机示例。

也许如果有人能确认这实际上是随机的,或者如果没有办法解决这个问题,或者如果我设置了错误的东西。因为我希望节点尽可能随机。

任何帮助,将不胜感激。 感谢

Random Example

下面是相关代码的小程序。涉及其成立。

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); 
    } 
} 
+0

我走在黑暗中拍摄,但看起来你是通过你的'StaticLayout'的'FRLayout'(Fruchterman-莱因戈尔德)。您的屏幕截图是大多数FRLayout尺寸太小时的样子。节点靠在布局的墙上。我猜JUNG在'StaticLayout'类中使用'FRLayout'作为变换器。 – sdasdadas

回答

1

您的图形不是随机的原因可能源于您将FRLayout传递给构造函数的事实。

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

您可以通过扩展AbstractLayout来制作您自己的随机布局类。但是,根据JavaDoc,如果排除第二个构造函数参数,StaticLayout将随机排列节点。

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

我最终将布局更改为静态,即layout = new StaticLayout (g),而不是删除第二个构造函数参数,但这非常感谢。 – AlexioHill

+0

@AlexioHill我很高兴它的工作。看起来你只是通过'new StaticLayout (g)'而不是'new StaticLayout (g,layout)'来移除第二个构造函数参数。 – sdasdadas

1

我没有得出关于它是否是随机的结论。所以相反,当我创建每个顶点时,我决定使用layout.setLocation(v1, x, y) 设置顶点的特定坐标。使用math.random()制作x和y,并将其乘以我的小程序的宽度和高度。

因此,我现在知道它是随机的。


编辑

这实际上似乎工作,但它实际上并没有,我不得不删除FRLayout。 事实证明,FRLayout不会让你设置自己的位置,因为算法的作用。

FRLayout是一个力导向布局,将根据图形拓扑重新定位顶点 。

因此,我将FRLayout更改为StaticLayout,删除了一些仅适用于FRLayout的工作,现在它可以正常工作。