如何使用 JUNG 对二部图进行投影
Posted
技术标签:
【中文标题】如何使用 JUNG 对二部图进行投影【英文标题】:how to make a projection of a bipartite graph with JUNG 【发布时间】:2014-02-19 12:19:13 【问题描述】:我在 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】:到目前为止,最有效的方法是使用超图而不是二分图。 (一个分区成为超图顶点,另一个成为超边,每个超边连接连接到原始图中相应顶点的顶点。)然后你可以在超图中向一个顶点询问它的邻居,你就是完成。
【讨论】:
谢谢 Joshua,我想你已经提到了作为我另一个问题的解决方案......但是如果我不必更新权重,我的代码确实很快......超图方法将如何解决权重更新?我仍然必须搜索正确的边缘以在单一模式下更新,但我仍然会浪费很多时间,不是吗?以上是关于如何使用 JUNG 对二部图进行投影的主要内容,如果未能解决你的问题,请参考以下文章