package edu.nd.nina.snap.agm; import java.util.HashSet; import java.util.Set; import java.util.Vector; import edu.nd.nina.UndirectedGraph; import edu.nd.nina.graph.ClassBasedEdgeFactory; import edu.nd.nina.graph.DefaultEdge; import edu.nd.nina.graph.SimpleGraph; import edu.nd.nina.math.Randoms; import edu.nd.nina.structs.Pair; public class AGM { public static UndirectedGraph<Integer, DefaultEdge> generateAGM( Vector<Vector<Integer>> cmtyVV, final Double densityCoef, final Double scaleCoef, Randoms rnd) { Vector<Float> cProbV = new Vector<Float>(); float prob; for (int i = 0; i < cmtyVV.size(); i++) { prob = (float) (scaleCoef * Math.pow( ((double) cmtyVV.get(i).size()), -densityCoef)); if (prob > 1.0) { prob = 1; } cProbV.add(prob); } return generateAGM(cmtyVV, cProbV, rnd); } private static UndirectedGraph<Integer, DefaultEdge> generateAGM( final Vector<Vector<Integer>> cmtyVV, Vector<Float> cProbV, Randoms rnd) { return generateAGM(cmtyVV, cProbV, rnd, -1d); } private static UndirectedGraph<Integer, DefaultEdge> generateAGM( final Vector<Vector<Integer>> cmtyVV, Vector<Float> cProbV, Randoms rnd, final Double pNoCom) { UndirectedGraph<Integer, DefaultEdge> g = new SimpleGraph<Integer, DefaultEdge>( new ClassBasedEdgeFactory<Integer, DefaultEdge>( DefaultEdge.class)); System.out.println("AGM begins"); for (int i = 0; i < cmtyVV.size(); i++) { Vector<Integer> cmtyV = cmtyVV.get(i); for (int u = 0; u < cmtyV.size(); u++) { if (g.containsVertex(cmtyV.get(u))) continue; g.addVertex(cmtyV.get(u)); } double prob = cProbV.get(i); RndConnectInsideCommunity(g, cmtyV, prob, rnd); } if (pNoCom > 0.0) { // if we want to connect nodes that do not share any // community Set<Integer> nIDS = new HashSet<Integer>(); for (int c = 0; c < cmtyVV.size(); c++) { for (int u = 0; u < cmtyVV.get(c).size(); u++) { nIDS.add(cmtyVV.get(c).get(u)); } } Vector<Integer> nIDV = new Vector<Integer>(); nIDV.addAll(nIDS); RndConnectInsideCommunity(g, nIDV, pNoCom, rnd); } System.out.println("AGM completed (" + g.vertexSet().size() + " nodes " + g.edgeSet().size() + " edges)"); // g.Defrag(); return g; } private static void RndConnectInsideCommunity( UndirectedGraph<Integer, DefaultEdge> g, final Vector<Integer> cmtyV, final Double prob, Randoms rnd) { int cNodes = cmtyV.size(), cEdges; if (cNodes < 20) { cEdges = rnd.getBinomialDeviance(prob, cNodes * (cNodes - 1) / 2) .intValue(); } else { cEdges = (int) (prob * cNodes * (cNodes - 1) / 2); } Set<Pair<Integer, Integer>> newEdgeSet = new HashSet<Pair<Integer, Integer>>(cEdges); for (int edge = 0; edge < cEdges;) { int srcNId = cmtyV.get(rnd.GetUniDevInt(cNodes)); int dstNId = cmtyV.get(rnd.GetUniDevInt(cNodes)); if (srcNId > dstNId) { // swap int x = srcNId; srcNId = dstNId; dstNId = x; } Pair<Integer, Integer> p = new Pair<Integer, Integer>(srcNId, dstNId); if (srcNId != dstNId && !newEdgeSet.contains(p)) { newEdgeSet.add(p); g.addEdge(srcNId, dstNId); edge++; } } } }