/** * Saves a given graph to a dot file, it also creates the file, or overwrites the old one * * @param g : The jung graph to save * @param filename : A string that points to the destination of the save * @param labeler : A node object -> Node name converter object * @param graphName : The name of the graph to export (usually this is set the project's name) * @throws IOException On IO error */ public void save(Graph<V, E> g, String filename, Transformer<V, String> labeler, String graphName) throws IOException { SortedSet<V> nodes = new TreeSet<V>(); Map<V, SortedSet<V>> successors = new HashMap<V, SortedSet<V>>(); for (V source : g.getVertices()) { Collection<V> actSuccessors = g.getSuccessors(source); SortedSet<V> successorTree = new TreeSet<V>(); for (V destination : actSuccessors) { successorTree.add(destination); } nodes.add(source); successors.put(source, successorTree); } BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename), "UTF-8")); writer.write("digraph \"" + graphName + "\" {\n"); for (V from : nodes) { Collection<V> actSuccessors = successors.get(from); for (V to : actSuccessors) { writer.write( "\t\"" + labeler.transform(from) + "\" -> \"" + labeler.transform(to) + "\";\n"); } if (g.getPredecessorCount(from) == 0 && actSuccessors.isEmpty()) { writer.write("\t\"" + labeler.transform(from) + "\";\n"); } } writer.write("}"); writer.close(); }
@Override public Box newVertexBox(Object vertex) { for (Class c : types.keySet()) { if (c.isInstance(vertex)) { Transformer<Object, Box> t = types.get(c); Box b = t.transform(vertex); return b; } } return newDefaultBox(vertex); }
/** * Calculates betweenness scores based on the all-pairs weighted shortest paths in the graph. * * <p>NOTE: This version of the algorithm may not work correctly on all graphs; we're still * working out the bugs. Use at your own risk. * * @param graph the graph for which the scores are to be calculated * @param edge_weights the edge weights to be used in the path length calculations */ public BetweennessCentrality(Graph<V, E> graph, Transformer<E, ? extends Number> edge_weights) { // reject negative-weight edges up front for (E e : graph.getEdges()) { double e_weight = edge_weights.transform(e).doubleValue(); if (e_weight < 0) throw new IllegalArgumentException("Weight for edge '" + e + "' is < 0: " + e_weight); } initialize(graph); computeBetweenness(new MapBinaryHeap<V>(new BetweennessComparator()), edge_weights); }
/** * Returns the prior probability for <code>v</code>. * * @param v the vertex whose prior probability is being queried * @return the prior probability for <code>v</code> */ protected S getVertexPrior(V v) { return vertex_priors.transform(v); }
protected void computeBetweenness(Queue<V> queue, Transformer<E, ? extends Number> edge_weights) { for (V v : graph.getVertices()) { // initialize the betweenness data for this new vertex for (V s : graph.getVertices()) this.vertex_data.put(s, new BetweennessData()); // if (v.equals(new Integer(0))) // System.out.println("pause"); vertex_data.get(v).numSPs = 1; vertex_data.get(v).distance = 0; Stack<V> stack = new Stack<V>(); // Buffer<V> queue = new UnboundedFifoBuffer<V>(); // queue.add(v); queue.offer(v); while (!queue.isEmpty()) { // V w = queue.remove(); V w = queue.poll(); stack.push(w); BetweennessData w_data = vertex_data.get(w); for (E e : graph.getOutEdges(w)) { // TODO (jrtom): change this to getOtherVertices(w, e) V x = graph.getOpposite(w, e); if (x.equals(w)) continue; double wx_weight = edge_weights.transform(e).doubleValue(); // for(V x : graph.getSuccessors(w)) // { // if (x.equals(w)) // continue; // FIXME: the other problem is that I need to // keep putting the neighbors of things we've just // discovered in the queue, if they're undiscovered or // at greater distance. // FIXME: this is the problem, right here, I think: // need to update position in queue if distance changes // (which can only happen with weighted edges). // for each outgoing edge e from w, get other end x // if x not already visited (dist x < 0) // set x's distance to w's dist + edge weight // add x to queue; pri in queue is x's dist // if w's dist + edge weight < x's dist // update x's dist // update x in queue (MapBinaryHeap) // clear x's incoming edge list // if w's dist + edge weight = x's dist // add e to x's incoming edge list BetweennessData x_data = vertex_data.get(x); double x_potential_dist = w_data.distance + wx_weight; if (x_data.distance < 0) { // queue.add(x); // vertex_data.get(x).distance = // vertex_data.get(w).distance + 1; x_data.distance = x_potential_dist; queue.offer(x); } // note: // (1) this can only happen with weighted edges // (2) x's SP count and incoming edges are updated below if (x_data.distance > x_potential_dist) { x_data.distance = x_potential_dist; // invalidate previously identified incoming edges // (we have a new shortest path distance to x) x_data.incomingEdges.clear(); // update x's position in queue ((MapBinaryHeap<V>) queue).update(x); } // if (vertex_data.get(x).distance == // vertex_data.get(w).distance + 1) // // if (x_data.distance == x_potential_dist) // { // x_data.numSPs += w_data.numSPs; //// vertex_data.get(x).predecessors.add(w); // x_data.incomingEdges.add(e); // } } for (E e : graph.getOutEdges(w)) { V x = graph.getOpposite(w, e); if (x.equals(w)) continue; double e_weight = edge_weights.transform(e).doubleValue(); BetweennessData x_data = vertex_data.get(x); double x_potential_dist = w_data.distance + e_weight; if (x_data.distance == x_potential_dist) { x_data.numSPs += w_data.numSPs; // vertex_data.get(x).predecessors.add(w); x_data.incomingEdges.add(e); } } } while (!stack.isEmpty()) { V x = stack.pop(); // for (V w : vertex_data.get(x).predecessors) for (E e : vertex_data.get(x).incomingEdges) { V w = graph.getOpposite(x, e); double partialDependency = vertex_data.get(w).numSPs / vertex_data.get(x).numSPs * (1.0 + vertex_data.get(x).dependency); vertex_data.get(w).dependency += partialDependency; // E w_x = graph.findEdge(w, x); // double w_x_score = edge_scores.get(w_x).doubleValue(); // w_x_score += partialDependency; // edge_scores.put(w_x, w_x_score); double e_score = edge_scores.get(e).doubleValue(); edge_scores.put(e, e_score + partialDependency); } if (!x.equals(v)) { double x_score = vertex_scores.get(x).doubleValue(); x_score += vertex_data.get(x).dependency; vertex_scores.put(x, x_score); } } } if (graph instanceof UndirectedGraph) { for (V v : graph.getVertices()) { double v_score = vertex_scores.get(v).doubleValue(); v_score /= 2.0; vertex_scores.put(v, v_score); } for (E e : graph.getEdges()) { double e_score = edge_scores.get(e).doubleValue(); e_score /= 2.0; edge_scores.put(e, e_score); } } vertex_data.clear(); }