Skip to content
Snippets Groups Projects
Commit b7c70010 authored by kraleva's avatar kraleva
Browse files

add the largest connected component code

parent b9ec71b2
Branches
No related tags found
1 merge request!26Add LLC
......@@ -42,7 +42,7 @@
<dependency>
<groupId>de.fuberlin.navigator</groupId>
<artifactId>proto</artifactId>
<version>1.00.06</version>
<version>1.00.08</version>
</dependency>
</dependencies>
......
package map.builder;
import java.io.IOException;
import java.util.ArrayList;
import org.json.JSONArray;
import de.fuberlin.navigator.protos.map_builder.RoadNetwork;
import map.builder.osm.OSMConnectedComponentParser;
import map.builder.osm.OSMFetcher;
import map.builder.osm.OSMParser;
import map.builder.utilities.BoundingBox;
import map.builder.utilities.ConnectedComponentGraph;
import map.builder.utilities.FileHandler;
public class App {
......@@ -46,6 +49,23 @@ public class App {
parser.parseTurnRestrictions(restrictions);
parser.parseRoads(roads);
// set it to 0 so that it can be collected by garbage collector
restrictions = null;
roads = null;
bbox = null;
parser = null;
// create the nodes graph in order to run LCC on it
ConnectedComponentGraph graph = new ConnectedComponentGraph();
OSMConnectedComponentParser.addNodes(roadNetworkBuilder, graph);
OSMConnectedComponentParser.addEdges(roadNetworkBuilder, graph);
ArrayList<Long> component = graph.getSCCs();
System.out.println(component.toString());
// cleanup
graph = null;
RoadNetwork roadNetwork = roadNetworkBuilder.build();
System.out.println("Turn restrictions count: " + roadNetwork.getTurnRestrictionsCount());
System.out.println("Nodes count: " + roadNetwork.getNodesCount());
......
package map.builder.osm;
import de.fuberlin.navigator.protos.map_builder.RoadNetwork;
import de.fuberlin.navigator.protos.map_builder.Segment;
import map.builder.utilities.ConnectedComponentGraph;
public class OSMConnectedComponentParser {
public static void addNodes(RoadNetwork.Builder roadnetwowrBuilder, ConnectedComponentGraph graph) {
for (Long nodeId : roadnetwowrBuilder.getNodesMap().keySet()) {
graph.addNode(nodeId);
}
}
public static void addEdges(RoadNetwork.Builder roadnetworkbuilder, ConnectedComponentGraph graph) {
for (Long edgeId : roadnetworkbuilder.getSegmentsMap().keySet()) {
Segment segment = roadnetworkbuilder.getSegmentsMap().get(edgeId);
Long startNode = segment.getStartNode();
Long endNode = segment.getEndNode();
graph.addEdge(startNode, endNode);
if (!segment.getOneWay()) {
graph.addEdge(endNode, startNode);
}
}
}
}
\ No newline at end of file
......@@ -2,8 +2,6 @@ package map.builder.osm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.JSONArray;
import org.json.JSONObject;
......@@ -18,7 +16,7 @@ import map.builder.utilities.ComputationalUtils;
public class OSMParser {
private final Coordinates.Builder coordinatesBuilder;
private final HashMap<Long, Node> nodesDump;
RoadNetwork.Builder roadNetworkBuilder;
public RoadNetwork.Builder roadNetworkBuilder;
public OSMParser(RoadNetwork.Builder roadNetworkBuilder) {
this.roadNetworkBuilder = roadNetworkBuilder;
......@@ -49,6 +47,7 @@ public class OSMParser {
this.splitSegment(element);
}
}
}
private void splitSegment(JSONObject element) {
......@@ -72,8 +71,7 @@ public class OSMParser {
try {
line = this.findNodePositions(geometry);
}
catch (NullPointerException e) {
} catch (NullPointerException e) {
System.out.println("Dropping segment with ID " + osmId);
System.out.println(e.getMessage());
return;
......@@ -86,7 +84,9 @@ public class OSMParser {
int maxSpeed = SegmentUtils.getMaxSpeed(element);
System.out.printf("Max speed: %d \n", maxSpeed);
System.out.printf("Way id: %d, Start node id : %d, End node id: %d \n", osmId, startNodeId, endNodeId);
System.out.printf("Way id: %d, Start node id : %d, End node id: %d \n", osmId,
this.roadNetworkBuilder.getNodesMap().get(startNodeId).getId(),
this.roadNetworkBuilder.getNodesMap().get(endNodeId).getId());
long internalId = this.roadNetworkBuilder.getSegmentsCount();
......@@ -113,7 +113,7 @@ public class OSMParser {
private void moveNodeToProto(Node node) {
long osmId = node.getOsmId();
this.roadNetworkBuilder.putNodes(osmId, node);
this.roadNetworkBuilder.putNodes(node.getOsmId(), node);
}
private void createNode(JSONObject element) {
......@@ -121,7 +121,7 @@ public class OSMParser {
long osmId = element.getLong(OSMKey.id.name());
Node node = Node.newBuilder()
.setId(this.roadNetworkBuilder.getNodesCount())
.setId(this.roadNetworkBuilder.getNodesCount() + this.nodesDump.size())
.setOsmId(osmId)
.setPosition(position)
.build();
......@@ -143,8 +143,10 @@ public class OSMParser {
}
/**
* Returns an array list of array lists of geometries. If the outer list has only one entry, it means the segment
* Returns an array list of array lists of geometries. If the outer list has
* only one entry, it means the segment
* doesn't need to be split, otherwise it needs to.
*
* @param nodeIds
* @return
* @throws NullPointerException
......@@ -176,7 +178,6 @@ public class OSMParser {
private Node findParsedNodeById(long osmId) throws NullPointerException {
if (this.nodesDump.containsKey(osmId)) {
Node node = this.nodesDump.get(osmId);
return node;
}
......
......@@ -3,8 +3,6 @@ package map.builder.utilities;
import de.fuberlin.navigator.protos.map_builder.Coordinates;
public class ComputationalUtils {
private ComputationalUtils() {
}
public static double haversine(Coordinates position_0,
de.fuberlin.navigator.protos.map_builder.Coordinates position_1) {
......
package map.builder.utilities;
import java.util.ArrayList;
import java.util.HashMap;
// Code from : https://www.geeksforgeeks.org/strongly-connected-components/
// Java implementation of Kosaraju's algorithm to print all SCCs
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Stack;
//TODO: change data structure here to be more appropriate
// This class represents a directed ConnectedComponentGraph using adjacency list
// representation
class ConnectedComponentGraph {
private int V; // No. of vertices
private LinkedList<Integer> adj[]; // Adjacency List
public class ConnectedComponentGraph {
private HashMap<Long, LinkedList<Long>> adj; // Adjacency List
// Constructor
ConnectedComponentGraph(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList<Integer>();
public ConnectedComponentGraph() {
adj = new HashMap<Long, LinkedList<Long>>();
}
public void addNode(Long v) {
adj.put(v, new LinkedList<Long>());
}
// Function to add an edge into the ConnectedComponentGraph
public void addEdge(int v, int w) {
adj[v].add(w);
public void addEdge(Long v, Long w) {
adj.get(v).add(w);
}
// A recursive function to print DFS starting from v
public void DFSUtil(int v, boolean visited[]) {
public ArrayList<Long> DFSUtil(Long v, HashMap<Long, Boolean> visited) {
// Mark the current node as visited and print it
visited[v] = true;
System.out.print(v + " ");
visited.put(v, true);
int n;
ArrayList<Long> component = new ArrayList<Long>();
Long n;
// Recur for all the vertices adjacent to this vertex
Iterator<Integer> i = adj[v].iterator();
Iterator<Long> i = adj.get(v).iterator();
while (i.hasNext()) {
n = i.next();
if (!visited[n])
DFSUtil(n, visited);
if (!visited.get(n))
component = DFSUtil(n, visited, component);
}
component.add(v);
return component;
}
public ArrayList<Long> DFSUtil(Long v, HashMap<Long, Boolean> visited, ArrayList<Long> list) {
// Mark the current node as visited and print it
visited.put(v, true);
Long n;
// Recur for all the vertices adjacent to this vertex
Iterator<Long> i = adj.get(v).iterator();
while (i.hasNext()) {
n = i.next();
if (!visited.get(n))
DFSUtil(n, visited, list);
}
list.add(v);
return list;
}
// Function that returns reverse (or transpose) of this ConnectedComponentGraph
public ConnectedComponentGraph getTranspose() {
ConnectedComponentGraph g = new ConnectedComponentGraph(V);
for (int v = 0; v < V; v++) {
ConnectedComponentGraph g = new ConnectedComponentGraph();
for (Long v : adj.keySet()) {
g.addNode(v);
}
for (Long v : adj.keySet()) {
// Recur for all the vertices adjacent to this vertex
Iterator<Integer> i = adj[v].listIterator();
while (i.hasNext())
g.adj[i.next()].add(v);
Iterator<Long> i = adj.get(v).listIterator();
while (i.hasNext()) {
Long next = i.next();
g.adj.get(next).add(v);
}
}
return g;
}
public void fillOrder(int v, boolean visited[], Stack<Integer> stack) {
public void fillOrder(Long v, HashMap<Long, Boolean> visited, Stack<Long> stack) {
// Mark the current node as visited and print it
visited[v] = true;
visited.put(v, true);
// Recur for all the vertices adjacent to this vertex
Iterator<Integer> i = adj[v].iterator();
Iterator<Long> i = adj.get(v).iterator();
while (i.hasNext()) {
int n = i.next();
if (!visited[n])
Long n = i.next();
if (!visited.get(n))
fillOrder(n, visited, stack);
}
......@@ -73,53 +99,67 @@ class ConnectedComponentGraph {
// The main function that finds and prints all strongly
// connected components
public void printSCCs() {
Stack<Integer> stack = new Stack<Integer>();
public ArrayList<Long> getSCCs() {
Stack<Long> stack = new Stack<Long>();
// Mark all the vertices as not visited (For first DFS)
boolean visited[] = new boolean[V];
for (int i = 0; i < V; i++)
visited[i] = false;
HashMap<Long, Boolean> visited = new HashMap<Long, Boolean>();
for (Long i : this.adj.keySet()) {
visited.put(i, false);
}
// Fill vertices in stack according to their finishing
// times
for (int i = 0; i < V; i++)
if (visited[i] == false)
for (Long i : this.adj.keySet())
if (visited.get(i) == false)
fillOrder(i, visited, stack);
// Create a reversed ConnectedComponentGraph
ConnectedComponentGraph gr = getTranspose();
// Mark all the vertices as not visited (For second DFS)
for (int i = 0; i < V; i++)
visited[i] = false;
for (Long i : this.adj.keySet())
visited.put(i, false);
// Now process all vertices in order defined by Stack
ArrayList<Long> largestComponent = new ArrayList<Long>();
int maxLength = 0;
while (stack.empty() == false) {
// Pop a vertex from stack
int v = (int) stack.pop();
Long v = stack.pop();
// Print Strongly connected component of the popped vertex
if (visited[v] == false) {
gr.DFSUtil(v, visited);
System.out.println();
if (visited.get(v) == false) {
ArrayList<Long> component = gr.DFSUtil(v, visited);
if (maxLength < component.size()) {
maxLength = component.size();
largestComponent = component;
}
}
}
return largestComponent;
}
// Driver method
public static void main(String args[]) {
// Create a ConnectedComponentGraph given in the above diagram
ConnectedComponentGraph g = new ConnectedComponentGraph(5);
g.addEdge(1, 0);
g.addEdge(0, 2);
g.addEdge(2, 1);
g.addEdge(0, 3);
g.addEdge(3, 4);
ConnectedComponentGraph g = new ConnectedComponentGraph();
// add nodes
g.addNode((long) 0);
g.addNode((long) 1);
g.addNode((long) 2);
g.addNode((long) 3);
g.addNode((long) 4);
g.addEdge((long) 1, (long) 0);
g.addEdge((long) 0, (long) 2);
g.addEdge((long) 2, (long) 1);
g.addEdge((long) 0, (long) 3);
g.addEdge((long) 3, (long) 4);
System.out.println("Following are strongly connected components " +
"in given ConnectedComponentGraph ");
g.printSCCs();
g.getSCCs();
}
}
// This code is contributed by Aakash Hasija
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment