2014-02-19 29 views
1

我在JUNG中創建了雙向圖,並且我希望對其中一組節點進行單模投影。在投影中,同一集合中的兩個節點如果共同擁有屬於另一個集合的節點,則將被鏈接。 JUNG中有一個函數已經做到了嗎?我至今(很慢的只有400屬於集合我希望以1600個節點的二分網絡)的代碼是:如何在JUNG中創建雙向圖的投影

public static void perform(UndirectedSparseGraph<Node, Edge> g, List<Node> companies) throws Exception { 
    // 
    UndirectedSparseGraph<Node, Edge> oneMode = new UndirectedSparseGraph<>(); 
    // 
    for (Node n : companies) { 
     // take my concepts 
     Collection<Node> myConcepts = g.getNeighbors(n); 
     // for each of my concepts 
     for (Node m : myConcepts) { 
      // take its companies 
      Collection<Node> itsCompanies = g.getNeighbors(m); 
      // for each of the companies that use this concept 
      for (Node nn : itsCompanies) { 
       // if company is not myself 
       if (!nn.equals(n)) { 
        // if at least one of these is not in the graph, go straight to add a link 
        if (!oneMode.containsVertex(nn) || !oneMode.containsVertex(n)) { 
         // add a new link 
         Edge edge = new Edge(1); 
         // set edge name 
         edge.setName(findEdgeLabel(n, nn)); 
         edge.setFrom(nn); 
         edge.setTo(n); 
         // add a link between myself and this company 
         oneMode.addEdge(edge, n, nn, EdgeType.UNDIRECTED); 
        } else { 
         if (oneMode.isNeighbor(n, nn)) { 
          // retrieve edge based on the label 
          boolean incrementWeight = incrementWeight(oneMode.getEdges(), findEdgeLabel(n, nn)); 
          if (!incrementWeight) { 
           throw new Exception("doesn't work"); 
          } 
         } else { 
          // add a new link 
          Edge edge = new Edge(1); 
          // set edge name 
          edge.setName(findEdgeLabel(n, nn)); 
          edge.setFrom(nn); 
          edge.setTo(n); 
          // add a link between myself and this company 
          oneMode.addEdge(edge, n, nn, EdgeType.UNDIRECTED); 
         } 
        } 
       } 
      } 
     } 
    } 
    // now write result to file 
    try (PrintWriter writer = new PrintWriter("icleantech-one-mode.csv", "UTF-8")) { 
     // iterate 
     for (Edge e : oneMode.getEdges()) { 
      writer.println(e.getFrom().getName() + ";" + e.getTo().getName() + ";" + String.valueOf(e.getWeight())); 
     } 
    } catch (FileNotFoundException | UnsupportedEncodingException ex) { 
     Logger.getLogger(BipartiteProjection.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

private static String findEdgeLabel(Node n, Node nn) { 
    if (n.getId() < nn.getId()) { 
     return String.valueOf(n.getId() + "-" + nn.getId()); 
    } else { 
     return String.valueOf(nn.getId() + "-" + n.getId()); 
    } 
} 

private static boolean incrementWeight(Collection<Edge> edges, String findEdgeLabel) { 
    for (Edge e : edges) { 
     if (e.getName().equals(findEdgeLabel)) { 
      // increase weight 
      e.setWeight(e.getWeight() + 1); 
      return true; 
     } 
    } 
    return false; 
} 

在代碼中的瓶頸是,當我想更新鏈接權重沒有它,代碼非常快......我不知道我的錯在哪裏......任何幫助都不是值得歡迎的。

回答

1

到目前爲止,最有效的方法是使用Hypergraph而不是雙向圖。 (一個分區成爲超圖的頂點,另一個成爲超圖,每個超圖連接與原始圖中對應頂點相連的頂點。)然後,您可以在超圖中問一個頂點作爲它的鄰居,而你完成。

+0

謝謝喬舒亞我認爲你已經提到,作爲我的另一個問題的解決方案...但是,如果我不必更新權重,我的代碼確實很快......超圖的方法如何解決重量更新?儘管如此,我仍然需要尋找在單模式下更新的正確邊緣,但我仍然會浪費很多時間,不是嗎? – user299791