/** * Finds the set of clusters which have the strongest "community structure". The more edges * removed the smaller and more cohesive the clusters. * * @param graph the graph */ public Set<Set<V>> transform(Graph<V, E> graph) { if (mNumEdgesToRemove < 0 || mNumEdgesToRemove > graph.getEdgeCount()) { throw new IllegalArgumentException("Invalid number of edges passed in."); } edges_removed.clear(); for (int k = 0; k < mNumEdgesToRemove; k++) { BetweennessCentrality<V, E> bc = new BetweennessCentrality<V, E>(graph); E to_remove = null; double score = 0; for (E e : graph.getEdges()) { Integer weight = mWeight.get(e); if (bc.getEdgeScore(e) / weight > score) { to_remove = e; score = bc.getEdgeScore(e) / weight; } } edges_removed.put(to_remove, graph.getEndpoints(to_remove)); graph.removeEdge(to_remove); } WeakComponentClusterer<V, E> wcSearch = new WeakComponentClusterer<V, E>(); Set<Set<V>> clusterSet = wcSearch.transform(graph); for (Map.Entry<E, Pair<V>> entry : edges_removed.entrySet()) { Pair<V> endpoints = entry.getValue(); graph.addEdge(entry.getKey(), endpoints.getFirst(), endpoints.getSecond()); } return clusterSet; }
@Override public boolean addEdge(Integer edge, Pair<? extends Role> endpoints, EdgeType edgeType) { this.validateEdgeType(edgeType); Pair<Role> new_endpoints = getValidatedEndpoints(edge, endpoints); if (new_endpoints == null) return false; Role source = new_endpoints.getFirst(); Role dest = new_endpoints.getSecond(); if (findEdge(source, dest) != null) return false; if (makesCycle(source, dest)) { return false; } edges.put(edge, new_endpoints); if (!vertices.containsKey(source)) this.addVertex(source); if (!vertices.containsKey(dest)) this.addVertex(dest); // map source of this edge to <dest, edge> and vice versa vertices.get(source).getSecond().put(dest, edge); vertices.get(dest).getFirst().put(source, edge); // new edge, role map has unsaved changes map.setSaved(false); return true; }
public boolean removeEdge(E edge) { if (!containsEdge(edge)) return false; Pair<V> endpoints = this.getEndpoints(edge); V source = endpoints.getFirst(); V dest = endpoints.getSecond(); // remove vertices from each others' adjacency maps vertices.get(source).getSecond().remove(dest); vertices.get(dest).getFirst().remove(source); edges.remove(edge); return true; }
public boolean removeEdge(E edge) { if (!containsEdge(edge)) return false; Pair<V> endpoints = getEndpoints(edge); V v1 = endpoints.getFirst(); V v2 = endpoints.getSecond(); // remove incident vertices from each others' adjacency maps vertices.get(v1).remove(v2); vertices.get(v2).remove(v1); edges.remove(edge); return true; }
/** * Returns <code>true</code> if this edge and its endpoints in this graph are all included in the * collections of elements to be rendered, and <code>false</code> otherwise. * * @param context the edge and graph to be queried * @return <code>true</code> if this edge and its endpoints are all included in the collections of * elements to be rendered, <code>false</code> otherwise. */ protected boolean isEdgeRendered(Context<Graph<V, E>, E> context) { Predicate<Context<Graph<V, E>, V>> vertexIncludePredicate = vv.getRenderContext().getVertexIncludePredicate(); Predicate<Context<Graph<V, E>, E>> edgeIncludePredicate = vv.getRenderContext().getEdgeIncludePredicate(); Graph<V, E> g = context.graph; E e = context.element; boolean edgeTest = edgeIncludePredicate == null || edgeIncludePredicate.apply(context); Pair<V> endpoints = g.getEndpoints(e); V v1 = endpoints.getFirst(); V v2 = endpoints.getSecond(); boolean endpointsTest = vertexIncludePredicate == null || (vertexIncludePredicate.apply(Context.<Graph<V, E>, V>getInstance(g, v1)) && vertexIncludePredicate.apply(Context.<Graph<V, E>, V>getInstance(g, v2))); return edgeTest && endpointsTest; }
/** * Retrieves the shape template for <code>e</code> and transforms it according to the positions of * its endpoints in <code>layout</code>. * * @param layout the <code>Layout</code> which specifies <code>e</code>'s endpoints' positions * @param e the edge whose shape is to be returned * @return the transformed shape */ private Shape getTransformedEdgeShape(Layout<V, E> layout, E e) { Pair<V> pair = layout.getGraph().getEndpoints(e); V v1 = pair.getFirst(); V v2 = pair.getSecond(); boolean isLoop = v1.equals(v2); Point2D p1 = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, layout.apply(v1)); Point2D p2 = vv.getRenderContext().getMultiLayerTransformer().transform(Layer.LAYOUT, layout.apply(v2)); if (p1 == null || p2 == null) return null; float x1 = (float) p1.getX(); float y1 = (float) p1.getY(); float x2 = (float) p2.getX(); float y2 = (float) p2.getY(); // translate the edge to the starting vertex AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1); Shape edgeShape = vv.getRenderContext().getEdgeShapeTransformer().apply(e); if (isLoop) { // make the loops proportional to the size of the vertex Shape s2 = vv.getRenderContext().getVertexShapeTransformer().apply(v2); Rectangle2D s2Bounds = s2.getBounds2D(); xform.scale(s2Bounds.getWidth(), s2Bounds.getHeight()); // move the loop so that the nadir is centered in the vertex xform.translate(0, -edgeShape.getBounds2D().getHeight() / 2); } else { float dx = x2 - x1; float dy = y2 - y1; // rotate the edge to the angle between the vertices double theta = Math.atan2(dy, dx); xform.rotate(theta); // stretch the edge to span the distance between the vertices float dist = (float) Math.sqrt(dx * dx + dy * dy); xform.scale(dist, 1.0f); } // transform the edge to its location and dimensions edgeShape = xform.createTransformedShape(edgeShape); return edgeShape; }
@Override public boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edgeType) { this.validateEdgeType(edgeType); Pair<V> new_endpoints = getValidatedEndpoints(edge, endpoints); if (new_endpoints == null) return false; V v1 = new_endpoints.getFirst(); V v2 = new_endpoints.getSecond(); if (findEdge(v1, v2) != null) return false; edges.put(edge, new_endpoints); if (!vertices.containsKey(v1)) this.addVertex(v1); if (!vertices.containsKey(v2)) this.addVertex(v2); // map v1 to <v2, edge> and vice versa vertices.get(v1).put(v2, edge); vertices.get(v2).put(v1, edge); return true; }
@Override public boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edgeType) { this.validateEdgeType(edgeType); Pair<V> new_endpoints = getValidatedEndpoints(edge, endpoints); if (new_endpoints == null) return false; V source = new_endpoints.getFirst(); V dest = new_endpoints.getSecond(); if (findEdge(source, dest) != null) return false; edges.put(edge, new_endpoints); if (!vertices.containsKey(source)) this.addVertex(source); if (!vertices.containsKey(dest)) this.addVertex(dest); // map source of this edge to <dest, edge> and vice versa vertices.get(source).getSecond().put(dest, edge); vertices.get(dest).getFirst().put(source, edge); return true; }
/** * * Creates a new graph object containing the nodes of the argument It does not clone the nodes / * edges. It just creates a new graph and adds them to the collection of graph's nodes and edges * * @return a graph object */ @SuppressWarnings("unchecked") public <G extends EvolutionGraph<V, E>> G toGraphE(List<V> nodes) { G subGraph; try { subGraph = (G) this.getClass().newInstance(); for (V vertex : nodes) { subGraph.addVertex(vertex); Collection<E> incidentEdges = this.getIncidentEdges(vertex); for (E edge : incidentEdges) { Pair<V> endpoints = this.getEndpoints(edge); if (nodes.containsAll(endpoints)) { // put this edge into the subgraph subGraph.addEdge(edge, endpoints.getFirst(), endpoints.getSecond()); } } } return subGraph; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; }
@Override public void labelEdge(RenderContext<V, E> rc, Layout<V, E> layout, E e, String label) { if (label == null || label.length() == 0) { return; } Graph<V, E> graph = layout.getGraph(); // don't draw edge if either incident vertex is not drawn Pair<V> endpoints = graph.getEndpoints(e); V v1 = endpoints.getFirst(); V v2 = endpoints.getSecond(); if (!rc.getVertexIncludePredicate().evaluate(Context.<Graph<V, E>, V>getInstance(graph, v1)) || !rc.getVertexIncludePredicate() .evaluate(Context.<Graph<V, E>, V>getInstance(graph, v2))) { return; } Point2D p1 = layout.transform(v1); Point2D p2 = layout.transform(v2); p1 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p1); p2 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p2); float x1 = (float) p1.getX(); float y1 = (float) p1.getY(); float x2 = (float) p2.getX(); float y2 = (float) p2.getY(); GraphicsDecorator g = rc.getGraphicsContext(); float distX = x2 - x1; float distY = y2 - y1; double totalLength = Math.sqrt(distX * distX + distY * distY); double closeness = rc.getEdgeLabelClosenessTransformer() .transform(Context.<Graph<V, E>, E>getInstance(graph, e)) .doubleValue(); int posX = (int) (x1 + (closeness) * distX); int posY = (int) (y1 + (closeness) * distY); int xDisplacement = 0; int yDisplacement = 0; /* * BUG 1: change X and Y in distXXX xDisplacement = (int) (rc.getLabelOffset() * (distY / * totalLength)); yDisplacement = (int) (rc.getLabelOffset() * (-distX / totalLength)); */ xDisplacement = (int) (rc.getLabelOffset() * (distX / totalLength)); yDisplacement = (int) (rc.getLabelOffset() * (-distY / totalLength)); // BUG 2 /* * Component component = prepareRenderer(rc, rc.getEdgeLabelRenderer(), label, * rc.getPickedEdgeState().isPicked(e), e); Dimension d = component.getPreferredSize(); * Shape edgeShape = rc.getEdgeShapeTransformer().transform(Context.<Graph<V, E>, E> * getInstance(graph, e)); double parallelOffset = 1; * * parallelOffset -= rc.getParallelEdgeIndexFunction().getIndex(graph, e); * * if (edgeShape instanceof Ellipse2D) { parallelOffset += * edgeShape.getBounds().getHeight(); parallelOffset = -parallelOffset; } * * parallelOffset *= d.height; */ AffineTransform old = g.getTransform(); AffineTransform xform = new AffineTransform(old); xform.translate(posX + xDisplacement, posY + yDisplacement); // BUG 3 /* * double dx = x2 - x1; double dy = y2 - y1; if * (rc.getEdgeLabelRenderer().isRotateEdgeLabels()) { double theta = Math.atan2(dy, dx); if * (dx < 0) { theta += Math.PI; } xform.rotate(theta); } if (dx < 0) { parallelOffset = * -parallelOffset; } */ double parallelOffset = 0.0d; Component component = prepareRenderer( rc, rc.getEdgeLabelRenderer(), label, rc.getPickedEdgeState().isPicked(e), e); Dimension d = component.getPreferredSize(); xform.translate(-d.width / 2.0d, -(d.height / 2.0d - parallelOffset)); g.setTransform(xform); g.draw(component, rc.getRendererPane(), 0, 0, d.width, d.height, true); g.setTransform(old); }
@Override public final Pair<V, V> getEndpoints(final E edge) { final edu.uci.ics.jung.graph.util.Pair<V> endpoints = graph.getEndpoints(edge); return new Pair<>(endpoints.getFirst(), endpoints.getSecond()); }
public void testMixedSaveLoadSave() throws IOException { Graph<Number, Number> graph1 = new SparseMultigraph<Number, Number>(); for (int i = 0; i < 5; i++) { graph1.addVertex(i); } int j = 0; List<Number> id = new ArrayList<Number>(graph1.getVertices()); GreekLabels<Number> gl = new GreekLabels<Number>(id); Number[] edges = {0, 1, 2, 3, 4, 5}; graph1.addEdge(j++, 0, 1, EdgeType.DIRECTED); graph1.addEdge(j++, 0, 2, EdgeType.DIRECTED); graph1.addEdge(j++, 1, 2, EdgeType.DIRECTED); graph1.addEdge(j++, 1, 3); graph1.addEdge(j++, 1, 4); graph1.addEdge(j++, 4, 3); Map<Number, Number> nr = new HashMap<Number, Number>(); for (int i = 0; i < edges.length; i++) { nr.put(edges[i], new Float(Math.random())); } assertEquals(graph1.getEdgeCount(), 6); // System.err.println(" mixed graph1 = "+graph1); // for(Number edge : graph1.getEdges()) { // System.err.println("edge "+edge+" is directed? "+graph1.getEdgeType(edge)); // } // for(Number v : graph1.getVertices()) { // System.err.println(v+" outedges are "+graph1.getOutEdges(v)); // System.err.println(v+" inedges are "+graph1.getInEdges(v)); // System.err.println(v+" incidentedges are "+graph1.getIncidentEdges(v)); // } String testFilename = "mtest.net"; String testFilename2 = testFilename + "2"; // assign arbitrary locations to each vertex Map<Number, Point2D> locations = new HashMap<Number, Point2D>(); for (Number v : graph1.getVertices()) { locations.put(v, new Point2D.Double(v.intValue() * v.intValue(), 1 << v.intValue())); } Function<Number, Point2D> vld = Functions.forMap(locations); PajekNetWriter<Number, Number> pnw = new PajekNetWriter<Number, Number>(); pnw.save(graph1, testFilename, gl, Functions.forMap(nr), vld); Graph<Number, Number> graph2 = pnr.load(testFilename, graphFactory); Function<Number, String> pl = pnr.getVertexLabeller(); List<Number> id2 = new ArrayList<Number>(graph2.getVertices()); Function<Number, Point2D> vld2 = pnr.getVertexLocationTransformer(); assertEquals(graph1.getVertexCount(), graph2.getVertexCount()); assertEquals(graph1.getEdgeCount(), graph2.getEdgeCount()); // test vertex labels and locations for (int i = 0; i < graph1.getVertexCount(); i++) { Number v1 = id.get(i); Number v2 = id2.get(i); assertEquals(gl.apply(v1), pl.apply(v2)); assertEquals(vld.apply(v1), vld2.apply(v2)); } // test edge weights Function<Number, Number> nr2 = pnr.getEdgeWeightTransformer(); for (Number e2 : graph2.getEdges()) { Pair<Number> endpoints = graph2.getEndpoints(e2); Number v1_2 = endpoints.getFirst(); Number v2_2 = endpoints.getSecond(); Number v1_1 = id.get(id2.indexOf(v1_2)); Number v2_1 = id.get(id2.indexOf(v2_2)); Number e1 = graph1.findEdge(v1_1, v2_1); assertNotNull(e1); assertEquals(nr.get(e1).floatValue(), nr2.apply(e2).floatValue(), 0.0001); } pnw.save(graph2, testFilename2, pl, nr2, vld2); compareIndexedGraphs(graph1, graph2); pnr.setVertexLabeller(null); Graph<Number, Number> graph3 = pnr.load(testFilename2, graphFactory); compareIndexedGraphs(graph2, graph3); File file1 = new File(testFilename); File file2 = new File(testFilename2); Assert.assertTrue(file1.length() == file2.length()); file1.delete(); file2.delete(); }
/* * (non-Javadoc) * * @see org.bigwiv.blastgraph.command.Command#concreteExecute() */ @Override public void concreteExecute() { String curPath = Global.getAppPath(this.getClass()); File mclGraphFile = new File(curPath + File.separator + "mcl_graph_file"); File mclClustFile = new File( curPath + File.separator + "out.mcl_graph_file.I" + ("" + inflation).replace(".", "").substring(0, 2)); // System.out.println(mclClustFile); try { ArrayList<ValueEdge> edges = new ArrayList<ValueEdge>(Global.graph.getEdges()); BufferedWriter bw; bw = new BufferedWriter(new FileWriter(mclGraphFile)); Global.WORK_STATUS.setMessage(""); Global.WORK_STATUS.setMessage("Stage1: Generating Tabular Format..."); for (ValueEdge valueEdge : edges) { Pair<HitVertex> pair = Global.graph.getEndpoints(valueEdge); HitVertex hv1 = pair.getFirst(); HitVertex hv2 = pair.getSecond(); double weight = 0; if (weightType == EVALUE_WEIGHT) { double evalue = valueEdge.getExpectValue(); if (evalue >= lowCutoff) { weight = 0; } else if (evalue < highCutoff) { weight = -Math.log10(highCutoff); } else { weight = -Math.log10(evalue); } } else if (weightType == SCORE_WEIGHT) { double score = valueEdge.getScore(); if (score <= lowCutoff) { weight = 0; } else if (score > highCutoff) { weight = highCutoff; } else { weight = score; } } else if (weightType == SCORE_DENSITY_WEIGHT) { double scoreDensity = Global.graph.getScoreDensity(valueEdge); if (scoreDensity <= lowCutoff) { weight = 0; } else if (scoreDensity > highCutoff) { weight = highCutoff; } else { weight = scoreDensity; } } bw.write(hv1.getId() + "\t" + hv2.getId() + "\t" + weight + "\n"); } // store single vertices for (HitVertex hv : Global.graph.getVertices()) { if (Global.graph.getInEdges(hv).size() == 0) bw.write(hv.getId() + "\t" + hv.getId() + "\t" + 10 + "\n"); } bw.close(); Global.WORK_STATUS.setMessage("Stage1 Complete"); Global.WORK_STATUS.setMessage(""); String mclCmd; String cmdPath = Global.SETTING.get("MCL_PATH"); if (cmdPath != null && (new File(cmdPath).isDirectory())) { mclCmd = cmdPath + File.separator + "mcl"; } else { mclCmd = "mcl"; } ProcessBuilder pb = new ProcessBuilder(mclCmd, "mcl_graph_file", "--abc", "-I", "" + inflation); // System.out.println(pb.command().toString()); pb.redirectErrorStream(true); pb.directory(new File(curPath)); Process p = pb.start(); Global.WORK_STATUS.setMessage("Stage2: Markov Clustering..."); BufferedInputStream in = new BufferedInputStream(p.getInputStream()); BufferedReader inBr = new BufferedReader(new InputStreamReader(in)); String lineStr; while ((lineStr = inBr.readLine()) != null) { // System.out.println(lineStr); Global.WORK_STATUS.setMessage(lineStr); } if (p.waitFor() != 0) { if (p.exitValue() == 1) // System.err.println("Failed to run mcl!"); Global.WORK_STATUS.setError("Failed to run mcl!"); } inBr.close(); in.close(); Global.WORK_STATUS.setMessage("Stage2 Complete"); mclGraphFile.delete(); Global.WORK_STATUS.setMessage(""); Global.WORK_STATUS.setMessage("Stage3: Regenerating SubGraphs..."); BufferedReader br = new BufferedReader(new FileReader(mclClustFile)); String line = br.readLine(); BlastGraph<HitVertex, ValueEdge> tempGraph = new BlastGraph<HitVertex, ValueEdge>(); int count = 0; while (line != null && !line.equals("")) { String[] ids = line.split("\t"); // set to store vertices Set<HitVertex> hvs2 = new HashSet<HitVertex>(); // get and add vertices into hvs by GI in ids for (int i = 0; i < ids.length; i++) { hvs2.add(Global.graph.getVertex(ids[i])); } tempGraph.union(FilterUtils.createInducedSubgraph(hvs2, Global.graph)); line = br.readLine(); Global.WORK_STATUS.setMessage("Subgraph: " + (++count)); } br.close(); mclClustFile.delete(); Global.graph.copy(tempGraph); Global.WORK_STATUS.setMessage("Stage3 Complete"); Global.WORK_STATUS.setMessage(""); Global.WORK_STATUS.setMessage("Markov Clustering Complete"); // System.out.println(curPath); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }