如何用JUNG投影二分图

时间:2014-02-19 12:19:13

标签: java social-networking jung bipartite

我在JUNG中创建了一个二分图,我希望对其中一组节点进行单模投影。在投影中,如果同一组中的两个节点共同具有属于另一组的节点,则它们将被链接。 JUNG有功能吗?到目前为止我的代码(对于1600个节点的二分网络来说非常慢,其中只有400个属于我想要投影的集合):

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 个答案:

答案 0 :(得分:1)

到目前为止,最有效的方法是使用Hypergraph而不是二分图。 (一个分区成为超图顶点,另一个分区变成超边界,每个分支连接连接到原始图中相应顶点的顶点。)然后你可以在超图中向顶点询问它的邻居,你就是完成。