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

add the largest connected component code

parent b9ec71b2
No related branches found
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) {
......@@ -61,7 +60,7 @@ public class OSMParser {
System.out.println("Split segment with ID " + osmId + " in " + geometry.size());
}
for (int i = 0; i<geometry.size(); i++) {
for (int i = 0; i < geometry.size(); i++) {
this.createSegment(element, geometry.get(i));
}
}
......@@ -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();
......@@ -107,13 +107,13 @@ public class OSMParser {
private boolean isOneWay(JSONObject element) {
return OSMJSONUtils.isTagValueEqualTo(element, "oneway", "yes") ||
OSMJSONUtils.isTagValueEqualTo(element, "highway", "motorway") ||
OSMJSONUtils.isTagValueEqualTo(element, "junction", "roundabout");
OSMJSONUtils.isTagValueEqualTo(element, "highway", "motorway") ||
OSMJSONUtils.isTagValueEqualTo(element, "junction", "roundabout");
}
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