private WeightedMultigraph<Vertex, LabeledWeightedEdge> step1() { logger.debug("<enter"); WeightedMultigraph<Vertex, LabeledWeightedEdge> g = new WeightedMultigraph<Vertex, LabeledWeightedEdge>(LabeledWeightedEdge.class); for (int i = 0; i < steinerNodes.size(); i++) { g.addVertex(steinerNodes.get(i)); } BellmanFordShortestPath<Vertex, LabeledWeightedEdge> path; for (int i = 0; i < steinerNodes.size(); i++) { path = new BellmanFordShortestPath<Vertex, LabeledWeightedEdge>(this.graph, steinerNodes.get(i)); for (int j = 0; j < steinerNodes.size(); j++) { if (i == j) continue; if (g.containsEdge(steinerNodes.get(i), steinerNodes.get(j))) continue; String id = "e" + String.valueOf(i) + String.valueOf(j); LabeledWeightedEdge e = new LabeledWeightedEdge(id, new URI(id, null, null), null); g.addEdge(steinerNodes.get(i), steinerNodes.get(j), e); g.setEdgeWeight(e, path.getCost(steinerNodes.get(j))); } } logger.debug("exit>"); return g; }
private void runAlgorithm() { logger.debug("<enter"); WeightedMultigraph<Vertex, LabeledWeightedEdge> g1 = step1(); // GraphUtil.printGraph(g1); // GraphUtil.printGraphSimple(g1); if (g1.vertexSet().size() < 2) { this.tree = g1; return; } WeightedMultigraph<Vertex, LabeledWeightedEdge> g2 = step2(g1); // GraphUtil.printGraph(g2); // GraphUtil.printGraphSimple(g2); WeightedMultigraph<Vertex, LabeledWeightedEdge> g3 = step3(g2); // GraphUtil.printGraph(g3); // GraphUtil.printGraphSimple(g3); WeightedMultigraph<Vertex, LabeledWeightedEdge> g4 = step4(g3); // GraphUtil.printGraph(g4); // GraphUtil.printGraphSimple(g4); WeightedMultigraph<Vertex, LabeledWeightedEdge> g5 = step5(g4); // GraphUtil.printGraph(g5); // GraphUtil.printGraphSimple(g5); this.tree = g5; logger.debug("exit>"); }
private WeightedMultigraph<Vertex, LabeledWeightedEdge> step2( WeightedMultigraph<Vertex, LabeledWeightedEdge> g1) { logger.debug("<enter"); KruskalMinimumSpanningTree<Vertex, LabeledWeightedEdge> mst = new KruskalMinimumSpanningTree<Vertex, LabeledWeightedEdge>(g1); // System.out.println("Total MST Cost: " + mst.getSpanningTreeCost()); Set<LabeledWeightedEdge> edges = mst.getEdgeSet(); WeightedMultigraph<Vertex, LabeledWeightedEdge> g2 = new WeightedMultigraph<Vertex, LabeledWeightedEdge>(LabeledWeightedEdge.class); List<LabeledWeightedEdge> edgesSortedByLabel = new ArrayList<LabeledWeightedEdge>(); for (LabeledWeightedEdge e : edges) edgesSortedByLabel.add(e); Collections.sort(edgesSortedByLabel, new EdgeComparatorByLabel()); for (LabeledWeightedEdge edge : edgesSortedByLabel) { // //just for test, forcing to select another equal minimal spanning tree // if (g1.getEdgeSource(edge).getLabel().equalsIgnoreCase("v1") && // g1.getEdgeTarget(edge).getLabel().equalsIgnoreCase("v3") ) { // Vertex v2 = steinerNodes.get(1); // g2.addVertex(g1.getEdgeTarget(edge)); // g2.addVertex(v2); // LabeledWeightedEdge e = new LabeledWeightedEdge("e"); // g2.setEdgeWeight(e, g1.getEdgeWeight(edge)); // g2.addEdge(g1.getEdgeTarget(edge), v2, e); // } else { g2.addVertex(edge.getSource()); g2.addVertex(edge.getTarget()); g2.addEdge(edge.getSource(), edge.getTarget(), edge); } } logger.debug("exit>"); return g2; }
private WeightedMultigraph<Vertex, LabeledWeightedEdge> step5( WeightedMultigraph<Vertex, LabeledWeightedEdge> g4) { logger.debug("<enter"); WeightedMultigraph<Vertex, LabeledWeightedEdge> g5 = g4; List<Vertex> nonSteinerLeaves = new ArrayList<Vertex>(); Set<Vertex> vertexSet = g4.vertexSet(); for (Vertex vertex : vertexSet) { if (g5.degreeOf(vertex) == 1 && steinerNodes.indexOf(vertex) == -1) { nonSteinerLeaves.add(vertex); } } Vertex source, target; for (int i = 0; i < nonSteinerLeaves.size(); i++) { source = nonSteinerLeaves.get(i); do { LabeledWeightedEdge e = g5.edgesOf(source).toArray(new LabeledWeightedEdge[0])[0]; target = this.graph.getEdgeTarget(e); // this should not happen, but just in case of ... if (target.equals(source)) target = e.getSource(); g5.removeVertex(source); source = target; } while (g5.degreeOf(source) == 1 && steinerNodes.indexOf(source) == -1); } logger.debug("exit>"); return g5; }
private WeightedMultigraph<Vertex, LabeledWeightedEdge> step3( WeightedMultigraph<Vertex, LabeledWeightedEdge> g2) { logger.debug("<enter"); WeightedMultigraph<Vertex, LabeledWeightedEdge> g3 = new WeightedMultigraph<Vertex, LabeledWeightedEdge>(LabeledWeightedEdge.class); Set<LabeledWeightedEdge> edges = g2.edgeSet(); DijkstraShortestPath<Vertex, LabeledWeightedEdge> path; Vertex source, target; for (LabeledWeightedEdge edge : edges) { source = edge.getSource(); target = edge.getTarget(); path = new DijkstraShortestPath<Vertex, LabeledWeightedEdge>(this.graph, source, target); List<LabeledWeightedEdge> pathEdges = path.getPathEdgeList(); if (pathEdges == null) continue; for (int i = 0; i < pathEdges.size(); i++) { if (g3.edgeSet().contains(pathEdges.get(i))) continue; source = pathEdges.get(i).getSource(); target = pathEdges.get(i).getTarget(); if (!g3.vertexSet().contains(source)) g3.addVertex(source); if (!g3.vertexSet().contains(target)) g3.addVertex(target); g3.addEdge(source, target, pathEdges.get(i)); } } logger.debug("exit>"); return g3; }
public EdgeBetweennessGraph(WeightedMultigraph<String, DefaultWeightedEdge> originalGraph) { super(DefaultWeightedEdge.class); // Constructor inherented from parent class // 1. Initialize the edge betweenness digraph // 1.1. Add vertices for (String thisVertex : originalGraph.vertexSet()) this.addVertex(thisVertex); // 1.2. Add edges for (DefaultWeightedEdge thisEdge : originalGraph.edgeSet()) { DefaultWeightedEdge newEdge = new DefaultWeightedEdge(); String sendingName = originalGraph.getEdgeSource(thisEdge); String receivingName = originalGraph.getEdgeTarget(thisEdge); this.addEdge(sendingName, receivingName, newEdge); this.setEdgeWeight(newEdge, 0.0); } // 1.3. Create corresponding unweighted graph // 1.3.1. Add vertices WeightedMultigraph<String, DefaultWeightedEdge> originalUnweightedGraph = new WeightedMultigraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class); for (String thisVertex : originalGraph.vertexSet()) originalUnweightedGraph.addVertex(thisVertex); // 1.3.2. Add edges for (DefaultWeightedEdge thisEdge : originalGraph.edgeSet()) { DefaultWeightedEdge newEdge = new DefaultWeightedEdge(); String sendingName = originalGraph.getEdgeSource(thisEdge); String receivingName = originalGraph.getEdgeTarget(thisEdge); originalUnweightedGraph.addEdge(sendingName, receivingName, newEdge); originalUnweightedGraph.setEdgeWeight(newEdge, 1.0); } for (String thisVertex : this.vertexSet()) { // 2. Create shortest-path graph for every vertex by Dijkstra algorithm Multigraph<String, DefaultEdge> shortestPathDigraph = DijkstraAlgorithm(originalUnweightedGraph, thisVertex); // 3. Calculate the contribution of current vertex's shortest-path graph to final edge // betweenness (Newman algorithm) SimpleWeightedGraph<String, DefaultWeightedEdge> edgeBetweennessDigraph = NewmanAlgorithm(shortestPathDigraph, thisVertex); // 4. Update final edge betweenness digraph with current vertex's shortest-path graph if (edgeBetweennessDigraph != null) for (DefaultWeightedEdge thisEdge : edgeBetweennessDigraph.edgeSet()) { String sourceVertex = edgeBetweennessDigraph.getEdgeSource(thisEdge); String targetVertex = edgeBetweennessDigraph.getEdgeTarget(thisEdge); double betweennessWeight = edgeBetweennessDigraph.getEdgeWeight(thisEdge); DefaultWeightedEdge edgeInWholeGraph = this.getEdge(sourceVertex, targetVertex); double newWeight = this.getEdgeWeight(edgeInWholeGraph) + betweennessWeight; this.setEdgeWeight(edgeInWholeGraph, newWeight); } } // 5. Revise the edge betweenness digraph with the original active power digraph for (DefaultWeightedEdge thisEdge : this.edgeSet()) { String sourceVertex = this.getEdgeSource(thisEdge); String targetVertex = this.getEdgeTarget(thisEdge); double betweennessWeight = this.getEdgeWeight(thisEdge); DefaultWeightedEdge edgeInWholeGraph = originalGraph.getEdge(sourceVertex, targetVertex); double newWeight = betweennessWeight / originalGraph.getEdgeWeight(edgeInWholeGraph); this.setEdgeWeight(thisEdge, newWeight); // System.out.println("Final edge betweenness between " + sourceVertex + " and " + // targetVertex + ": " + newWeight); } }
// Create shortest-path graph for every vertex by depth-first traversal algorithm private Multigraph<String, DefaultEdge> DijkstraAlgorithm( WeightedMultigraph<String, DefaultWeightedEdge> originalGraph, String thisVertex) { // 1. Simplify the multi-graph of the active power flow into a simple graph SimpleWeightedGraph<String, DefaultWeightedEdge> originalSimpleGraph = new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class); for (String curVertex : originalGraph.vertexSet()) originalSimpleGraph.addVertex(curVertex); for (DefaultWeightedEdge curEdge : originalGraph.edgeSet()) { String sourceVertex = originalGraph.getEdgeSource(curEdge); String targetVertex = originalGraph.getEdgeTarget(curEdge); if (originalSimpleGraph.containsEdge(sourceVertex, targetVertex)) { DefaultWeightedEdge modifiedEdge = originalSimpleGraph.getEdge(sourceVertex, targetVertex); double newEdgeWeight = originalSimpleGraph.getEdgeWeight(modifiedEdge) + originalGraph.getEdgeWeight(curEdge); originalSimpleGraph.setEdgeWeight(modifiedEdge, newEdgeWeight); } else { DefaultWeightedEdge newEdge = new DefaultWeightedEdge(); originalSimpleGraph.addEdge(sourceVertex, targetVertex, newEdge); originalSimpleGraph.setEdgeWeight(newEdge, originalGraph.getEdgeWeight(curEdge)); } } // Issue (2010/10/25): Maybe larger amount of active power transfer still means weaker // relationship between the two terminal buses of a certain branch, // thus originalSimpleGraph other than inverseGraph should be used here. // Use the inverse of active power to build a new weighted directed graph (the larger the active // power is, the close the two buses will be) // SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> inverseGraph = // new SimpleDirectedWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class); // for (String curVertex : originalSimpleGraph.vertexSet()) // inverseGraph.addVertex(curVertex); // for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgeSet()) { // String sourceVertex = originalSimpleGraph.getEdgeSource(curEdge); // String targetVertex = originalSimpleGraph.getEdgeTarget(curEdge); // DefaultWeightedEdge newEdge = new DefaultWeightedEdge(); // inverseGraph.addEdge(sourceVertex, targetVertex, newEdge); // inverseGraph.setEdgeWeight(newEdge, 1 / originalSimpleGraph.getEdgeWeight(curEdge)); // } // 2. Initialize the map of vertices and the corresponding weights (distance from current vertex // to the first vertex) HashMap<String, Double> mapVertexShortestDistance = new HashMap<String, Double>(); // for (String thisOriginalVertex : inverseGraph.vertexSet()) for (String thisOriginalVertex : originalSimpleGraph.vertexSet()) mapVertexShortestDistance.put(thisOriginalVertex, 10E10); // The weight of the first vertex is zero mapVertexShortestDistance.put(thisVertex, 0.0); // 3. Depth-first traversing, update the shortest-path values Stack<String> bfiVertices = new Stack<String>(); // Stack to store passed vertices in a breadth-first traversing // The map of a weighted edge and the flag of having been visited // HashMap<DefaultWeightedEdge, Boolean> mapEdgeVisited = new HashMap<DefaultWeightedEdge, // Boolean>(); // for (DefaultWeightedEdge thisEdge : inverseGraph.edgeSet()) // mapEdgeVisited.put(thisEdge, false); String currentVertex = thisVertex; bfiVertices.push(currentVertex); // System.out.println(bfiVertices.toString()); while (!bfiVertices.isEmpty()) { // Operate the following codes for those edges started with current vertex boolean hasNewEdge = false; // for (DefaultWeightedEdge curEdge : inverseGraph.outgoingEdgesOf(currentVertex)) { for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgesOf(currentVertex)) { // if (!mapEdgeVisited.get(curEdge)) { // Used for those edges that have not been treated // yet // 3.1. Mark current edge as already been visited // mapEdgeVisited.put(curEdge, true); // String nextVertex = inverseGraph.getEdgeTarget(curEdge); String nextVertex = originalSimpleGraph.getEdgeTarget(curEdge); // 3.2. Update shortest-path values double curSD = mapVertexShortestDistance.get(currentVertex); // double edgeWeight = inverseGraph.getEdgeWeight(curEdge); double edgeWeight = originalSimpleGraph.getEdgeWeight(curEdge); double newSD = curSD + edgeWeight; if (mapVertexShortestDistance.get(nextVertex) > newSD) { hasNewEdge = true; mapVertexShortestDistance.put(nextVertex, newSD); // 3.3. Push the target vertex of current edge into the stack bfiVertices.push(nextVertex); // System.out.println(bfiVertices.toString()); break; // System.out.println("New shortest path [" + nextVertex + "]: " + newSD); } // } } if (!hasNewEdge) { bfiVertices.pop(); } if (!bfiVertices.isEmpty()) currentVertex = bfiVertices.peek(); } // 4. Create shortest-path digraph of current vertex // 4.1. Initialize the shortest-path digraph Multigraph<String, DefaultEdge> shortestPathGraph = new Multigraph<String, DefaultEdge>(DefaultEdge.class); // 4.2. Add all qualified edges // for (DefaultWeightedEdge curEdge : inverseGraph.edgeSet()) { for (DefaultWeightedEdge curEdge : originalSimpleGraph.edgeSet()) { // 4.2.1. Evaluate if current edge is suitable // String sourceVertex = inverseGraph.getEdgeSource(curEdge); // String targetVertex = inverseGraph.getEdgeTarget(curEdge); String sourceVertex = originalSimpleGraph.getEdgeSource(curEdge); String targetVertex = originalSimpleGraph.getEdgeTarget(curEdge); // if (Math.abs(inverseGraph.getEdgeWeight(curEdge) - if (originalSimpleGraph.getEdgeWeight(curEdge) > 1.0E-5) { if (Math.abs( originalSimpleGraph.getEdgeWeight(curEdge) - (mapVertexShortestDistance.get(targetVertex) - mapVertexShortestDistance.get(sourceVertex))) < 1.0E-5) { // 4.2.2. Add suitable edge that found just now DefaultEdge newEdge = new DefaultEdge(); if (!shortestPathGraph.containsVertex(sourceVertex)) shortestPathGraph.addVertex(sourceVertex); if (!shortestPathGraph.containsVertex(targetVertex)) shortestPathGraph.addVertex(targetVertex); shortestPathGraph.addEdge(sourceVertex, targetVertex, newEdge); } } } return shortestPathGraph; }