private MinAvgMax RunFolderDynamicGraph(string folder, IDynamicGraph alg) { var values = new List<long>(); var sw = new Stopwatch(); foreach (var file in Directory.EnumerateFiles(folder)) { var graph = readFile(file); alg.ResetAll(graph.n, graph.m); for(int i = 0; i < graph.n; i++) alg.AddVertex(); sw.Reset(); //force gc GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); sw.Start(); foreach (var edge in graph.edges) { alg.AddEdge(edge.from, edge.to); } var top = alg.Topology(); sw.Stop(); values.Add(sw.ElapsedTicks); } return new MinAvgMax(values.Min(), (long)values.Average(), values.Max()); }
/// <summary> /// Creates a new edge difference calculator. /// </summary> /// <param name="data"></param> /// <param name="witness_calculator"></param> public EdgeDifferenceContractedSearchSpace(IDynamicGraph<CHEdgeData> data, INodeWitnessCalculator witness_calculator) { _data = data; _witness_calculator = witness_calculator; _contraction_count = new Dictionary<uint, short>(); _depth = new Dictionary<long, long>(); }
/// <summary> /// Creates a new edge difference calculator. /// </summary> /// <param name="data"></param> /// <param name="witness_calculator"></param> public EdgeDifferenceContractedSearchSpace(IDynamicGraph <CHEdgeData> data, INodeWitnessCalculator witness_calculator) { _data = data; _witness_calculator = witness_calculator; _contraction_count = new Dictionary <uint, short>(); _depth = new Dictionary <long, long>(); }
private List<long> runFile(string file, IDynamicGraph alg, int resolution, int repeatCount) { InputFile graph = readFile(file); Stopwatch sw = new Stopwatch(); List<List<long>> times = new List<List<long>>(); List<List<long>> timesVector = new List<List<long>>(); for (int i = 0; i < repeatCount; i++) { alg.ResetAll(graph.n); int skip = 0; times.Add(new List<long>()); for (int n = 0; n < graph.n; n++) alg.AddVertex(); do { sw.Start(); foreach(var edge in graph.edges.Skip(skip).Take(resolution)) { alg.AddEdge(edge.from, edge.to); } sw.Stop(); times[i].Add(sw.ElapsedTicks); sw.Reset(); skip += resolution; } while (skip < graph.edges.Count); } var ret = Transpose(times).ConvertAll(item => ((long)item.Average())); return ret; }
/// <summary> /// Creates a new osm memory router data source. /// </summary> /// <param name="graph"></param> /// <param name="tagsIndex"></param> /// <exception cref="ArgumentNullException"></exception> public DynamicGraphRouterDataSource(IDynamicGraph <TEdgeData> graph, ITagsIndex tagsIndex) { if (graph == null) { throw new ArgumentNullException("graph"); } if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } _graph = graph; _vertexIndex = new QuadTree <GeoCoordinate, uint>(); _tagsIndex = tagsIndex; _supportedVehicles = new HashSet <Vehicle>(); // add the current graph's vertices to the vertex index. for (uint newVertexId = 1; newVertexId < graph.VertexCount + 1; newVertexId++) { // add to the CHRegions. float latitude, longitude; graph.GetVertex(newVertexId, out latitude, out longitude); _vertexIndex.Add(new GeoCoordinate(latitude, longitude), newVertexId); } }
public void TestLiveEdgeDynamicGraphEdge10000() { int count = 10000; IDynamicGraph <LiveEdge> graph = this.CreateGraph(); uint vertex1 = graph.AddVertex(51, 1); while (count > 0) { uint vertex2 = graph.AddVertex(51, 1); graph.AddArc(vertex1, vertex2, new LiveEdge() { Tags = 0, Forward = false }, null); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1); Assert.AreEqual(10000 - count + 1, arcs.Length); graph.AddArc(vertex2, vertex1, new LiveEdge() { Tags = 0, Forward = false }, null); arcs = graph.GetArcs(vertex2); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex1, arcs[0].Key); count--; } }
public void TestLiveEdgeDynamicGraphEdge() { IDynamicGraph <LiveEdge> graph = this.CreateGraph(); uint vertex1 = graph.AddVertex(51, 1); uint vertex2 = graph.AddVertex(51, 2); graph.AddArc(vertex1, vertex2, new LiveEdge() { Forward = true, Tags = 0 }, null); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex2, arcs[0].Key); graph.AddArc(vertex2, vertex1, new LiveEdge() { Forward = true, Tags = 0 }, null); arcs = graph.GetArcs(vertex2); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex1, arcs[0].Key); }
/// <summary> /// Creates a new osm memory router data source. /// </summary> /// <exception cref="ArgumentNullException"></exception> public DynamicGraphRouterDataSource(ITagsIndex tagsIndex) { if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } _graph = new MemoryDynamicGraph <TEdgeData>(); _vertexIndex = new QuadTree <GeoCoordinate, uint>(); _tagsIndex = tagsIndex; _supportedVehicles = new HashSet <Vehicle>(); }
/// <summary> /// Creates a new osm memory router data source. /// </summary> /// <exception cref="ArgumentNullException"></exception> public DynamicGraphRouterDataSource(ITagsCollectionIndexReadonly tagsIndex, int initSize) { if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } _graph = new MemoryDynamicGraph <TEdgeData>(initSize); _vertexIndex = null; // do not create an index initially. _tagsIndex = tagsIndex; _supportedVehicles = new HashSet <Vehicle>(); }
public void TestLiveEdgeDynamicGraphVertex() { IDynamicGraph <LiveEdge> graph = this.CreateGraph(); uint vertex = graph.AddVertex(51, 4); float latitude, longitude; graph.GetVertex(vertex, out latitude, out longitude); Assert.AreEqual(51, latitude); Assert.AreEqual(4, longitude); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex); Assert.AreEqual(0, arcs.Length); }
/// <summary> /// Creates a new processor target. /// </summary> /// <param name="dynamicGraph">The graph that will be filled.</param> /// <param name="interpreter">The interpreter to generate the edge data.</param> /// <param name="edgeComparer"></param> /// <param name="tagsIndex"></param> /// <param name="idTransformations"></param> /// <param name="box"></param> protected DynamicGraphOsmStreamWriter( IDynamicGraph <TEdgeData> dynamicGraph, IRoutingInterpreter interpreter, IDynamicGraphEdgeComparer <TEdgeData> edgeComparer, ITagsIndex tagsIndex, IDictionary <long, uint> idTransformations, GeoCoordinateBox box) { _dynamicGraph = dynamicGraph; _interpreter = interpreter; _edgeComparer = edgeComparer; _box = box; _tagsIndex = tagsIndex; _idTransformations = idTransformations; _preIndexMode = true; _preIndex = new HashSet <long>(); _usedTwiceOrMore = new HashSet <long>(); }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witnessCalculator"></param> /// <param name="keepReverseEdges"></param> public CHPreProcessor(IDynamicGraph <CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witnessCalculator, bool keepReverseEdges) { _comparer = new CHEdgeDataComparer(); _target = target; _calculator = calculator; _witnessCalculator = witnessCalculator; _queue = new CHPriorityQueue(); _contracted = new bool[1000]; _keepReverseEdges = keepReverseEdges; }
/// <summary> /// Returns the arcs that point to lower vertices. /// </summary> /// <param name="graph"></param> /// <param name="vertexId"></param> /// <returns></returns> public static KeyValuePair <uint, CHEdgeData>[] GetArcsLower(this IDynamicGraph <CHEdgeData> graph, uint vertexId) { KeyValuePair <uint, CHEdgeData>[] arcs = graph.GetEdges(vertexId); KeyValuePair <uint, CHEdgeData>[] higherArcs = new KeyValuePair <uint, CHEdgeData> [arcs.Length]; int higherIdx = 0; for (int idx = 0; idx < arcs.Length; idx++) { if (!arcs[idx].Value.ToHigher) { higherArcs[higherIdx] = arcs[idx]; higherIdx++; } } Array.Resize(ref higherArcs, higherIdx); return(higherArcs); }
/// <summary> /// Adds all downward edges. /// </summary> /// <param name="graph"></param> public static void AddDownwardEdges(this IDynamicGraph <CHEdgeData> graph) { // add the reverse edges to get a easy depth-first search. for (uint vertexId = 1; vertexId < graph.VertexCount; vertexId++) { List <KeyValuePair <uint, CHEdgeData> > arcs = new List <KeyValuePair <uint, CHEdgeData> >(graph.GetArcs(vertexId)); foreach (KeyValuePair <uint, CHEdgeData> arc in arcs) { if (arc.Value.ToHigher) { // create severse edge. CHEdgeData reverseEdge = new CHEdgeData(); reverseEdge.SetDirection(arc.Value.Backward, arc.Value.Forward, false); reverseEdge.Weight = arc.Value.Weight; graph.AddArc(arc.Key, vertexId, reverseEdge, null); } } } }
public void TestLiveEdgeDynamicGraphVertex10000() { IDynamicGraph <LiveEdge> graph = this.CreateGraph(); int count = 10000; while (count > 0) { uint vertex = graph.AddVertex(51, 4); float latitude, longitude; graph.GetVertex(vertex, out latitude, out longitude); Assert.AreEqual(51, latitude); Assert.AreEqual(4, longitude); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex); Assert.AreEqual(0, arcs.Length); count--; } Assert.AreEqual((uint)10000, graph.VertexCount); }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="graph"></param> public LiveEdgePreprocessor(IDynamicGraph <LiveEdge> graph) { _graph = graph; }
/// <summary> /// Creates a new witness calculator. /// </summary> /// <param name="data"></param> public CHRouterWitnessCalculator(IDynamicGraph<CHEdgeData> data) { _router = new CHRouter(data); }
/// <summary> /// Returns a topologically sorted version of the given graph. /// </summary> /// <param name="graph"></param> /// <returns></returns> public static IDynamicGraph <CHEdgeData> SortGraph(IDynamicGraph <CHEdgeData> graph) { // also add all downward edges. graph.AddDownwardEdges(); // sort the topologically ordered vertices into bins representing a certain height range. List <uint>[] heightBins = new List <uint> [1000]; foreach (var vertexDepth in new CHDepthFirstEnumerator(graph)) { // enumerates all vertixes depth-first. int binIdx = (int)(vertexDepth.Depth / HeightBinSize); if (heightBins.Length < binIdx) { // resize bin array if needed. Array.Resize(ref heightBins, System.Math.Max(heightBins.Length + 1000, binIdx + 1)); } // add to the current bin. List <uint> bin = heightBins[binIdx]; if (bin == null) { // create new bin. bin = new List <uint>(); heightBins[binIdx] = bin; } bin.Add(vertexDepth.VertexId); } // temp test. MemoryDynamicGraph <CHEdgeData> sortedGraph = new MemoryDynamicGraph <CHEdgeData>(); Dictionary <uint, uint> currentBinIds = new Dictionary <uint, uint>(); uint newVertexId; for (int idx = 0; idx < heightBins.Length; idx++) { List <uint> bin = heightBins[idx]; if (bin != null) { // translate ids. // fill current bin ids and add vertices to the new graph. foreach (uint binVertexId in bin) { float latitude, longitude; graph.GetVertex(binVertexId, out latitude, out longitude); newVertexId = sortedGraph.AddVertex(latitude, longitude); currentBinIds.Add(binVertexId, newVertexId); // add to the current bin index. } } } // rebuild the CH graph based on the new ordering and build the CHRegions. newVertexId = 0; for (int idx = 0; idx < heightBins.Length; idx++) { List <uint> bin = heightBins[idx]; if (bin != null) { // translate ids. // fill current bin ids and add vertices to the new graph. //foreach (uint binVertexId in bin) //{ // float latitude, longitude; // graph.GetVertex(binVertexId, out latitude, out longitude); // newVertexId = sortedGraph.AddVertex(latitude, longitude); // currentBinIds.Add(binVertexId, newVertexId); // add to the current bin index. //} foreach (uint binVertexId in bin) { currentBinIds.TryGetValue(binVertexId, out newVertexId); // get the higher arcs and convert their ids. KeyValuePair <uint, CHEdgeData>[] arcs = graph.GetArcsHigher(binVertexId); foreach (KeyValuePair <uint, CHEdgeData> arc in arcs) { // get target vertex. uint nextVertexArcId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Key, currentBinIds, heightBins); // convert edge. CHEdgeData newEdge = new CHEdgeData(); newEdge.Direction = arc.Value.Direction; if (arc.Value.HasContractedVertex) { // contracted info. newEdge.ContractedVertexId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Value.ContractedVertexId, currentBinIds, heightBins); } else { // no contracted info. newEdge.ContractedVertexId = 0; } newEdge.Tags = arc.Value.Tags; newEdge.Weight = arc.Value.Weight; sortedGraph.AddArc(newVertexId, nextVertexArcId, newEdge, null); } } } } return(sortedGraph); }
/// <summary> /// Creates a new processor target. /// </summary> /// <param name="dynamicGraph">The graph that will be filled.</param> /// <param name="interpreter">The interpreter to generate the edge data.</param> /// <param name="edgeComparer"></param> /// <param name="tagsIndex"></param> /// <param name="idTransformations"></param> protected DynamicGraphOsmStreamWriter(IDynamicGraph <TEdgeData> dynamicGraph, IRoutingInterpreter interpreter, IDynamicGraphEdgeComparer <TEdgeData> edgeComparer, ITagsIndex tagsIndex, IDictionary <long, uint> idTransformations) : this(dynamicGraph, interpreter, edgeComparer, tagsIndex, idTransformations, null) { }
/// <summary> /// Creates a new sparse ordering calculator. /// </summary> /// <param name="data"></param> public SparseOrdering(IDynamicGraph <CHEdgeData> data) { _data = data; }
/// <summary> /// Creates a new witness calculator. /// </summary> /// <param name="data"></param> public CHRouterWitnessCalculator(IDynamicGraph <CHEdgeData> data) { _router = new CHRouter(data); }
/// <summary> /// Creates a new witness calculator. /// </summary> /// <param name="data"></param> public DykstraWitnessCalculator(IDynamicGraph <CHEdgeData> data) { _data = data; }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witness_calculator"></param> public CHPreProcessor(IDynamicGraph<CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witness_calculator) { _comparer = new CHEdgeDataComparer(); _target = target; _calculator = calculator; _witness_calculator = witness_calculator; _queue = new CHPriorityQueue(); _contracted = new bool[1000]; }
/// <summary> /// Creates a new edge difference calculator. /// </summary> /// <param name="data"></param> /// <param name="witness_calculator"></param> public EdgeDifference(IDynamicGraph<CHEdgeData> data, INodeWitnessCalculator witness_calculator) { _data = data; _witness_calculator = witness_calculator; }
/// <summary> /// Creates a new witness calculator. /// </summary> /// <param name="data"></param> public DykstraWitnessCalculator(IDynamicGraph<CHEdgeData> data) { _data = data; }
/// <summary> /// Creates a new sparse ordering calculator. /// </summary> /// <param name="data"></param> public SparseOrdering(IDynamicGraph<CHEdgeData> data) { _data = data; }
/// <summary> /// Creates a new edge difference calculator. /// </summary> /// <param name="data"></param> /// <param name="witness_calculator"></param> public EdgeDifference(IDynamicGraph <CHEdgeData> data, INodeWitnessCalculator witness_calculator) { _data = data; _witness_calculator = witness_calculator; }
/// <summary> /// Creates a new processor target. /// </summary> /// <param name="dynamicGraph">The graph that will be filled.</param> /// <param name="interpreter">The interpreter to generate the edge data.</param> /// <param name="edgeComparer"></param> /// <param name="tagsIndex"></param> protected DynamicGraphOsmStreamWriter(IDynamicGraph <TEdgeData> dynamicGraph, IRoutingInterpreter interpreter, IDynamicGraphEdgeComparer <TEdgeData> edgeComparer, ITagsIndex tagsIndex) : this(dynamicGraph, interpreter, edgeComparer, tagsIndex, new Dictionary <long, uint>()) { }
/// <summary> /// Does the v2 serialization. /// </summary> /// <param name="stream"></param> /// <param name="graph"></param> /// <returns></returns> protected override void DoSerialize(LimitedStream stream, DynamicGraphRouterDataSource <CHEdgeData> graph) { // sort the graph. IDynamicGraph <CHEdgeData> sortedGraph = CHEdgeDataDataSourceSerializer.SortGraph(graph); // create the regions. SortedDictionary <ulong, List <uint> > regions = new SortedDictionary <ulong, List <uint> >(); for (uint newVertexId = 1; newVertexId < sortedGraph.VertexCount + 1; newVertexId++) { // add to the CHRegions. float latitude, longitude; sortedGraph.GetVertex(newVertexId, out latitude, out longitude); Tile tile = Tile.CreateAroundLocation(new GeoCoordinate( latitude, longitude), RegionZoom); List <uint> regionVertices; if (!regions.TryGetValue(tile.Id, out regionVertices)) { regionVertices = new List <uint>(); regions.Add(tile.Id, regionVertices); } regionVertices.Add(newVertexId); } // serialize the sorted graph. // [START_OF_BLOCKS][[SIZE_OF_REGION_INDEX][REGION_INDEX][REGIONS]][[SIZE_OF_BLOCK_INDEX][BLOCK_INDEX][BLOCKS]] // STRART_OF_BLOCKS: 4bytes // SIZE_OF_REGION_INDEX: 4bytes // REGION_INDEX: see SIZE_OF_REGION_INDEX // REGIONS: see START_OF_BLOCKS - 4bytes // SIZE_OF_BLOCK_INDEX: 4bytes // BLOCK_INDEX: see SIZE_OF_BLOCK_INDEX. // BLOCKS: from START_OF_BLOCKS + 4bytes + SIZE_OF_BLOCKS_INDEX until END. // serialize regions and build their index. CHVertexRegionIndex chRegionIndex = new CHVertexRegionIndex(); chRegionIndex.LocationIndex = new int[regions.Count]; chRegionIndex.RegionIds = new ulong[regions.Count]; var memoryStream = new MemoryStream(); int regionIdx = 0; foreach (KeyValuePair <ulong, List <uint> > region in regions) { // serialize. CHVertexRegion chRegion = new CHVertexRegion(); chRegion.Vertices = region.Value.ToArray(); _runtimeTypeModel.Serialize(memoryStream, chRegion); // set index. chRegionIndex.LocationIndex[regionIdx] = (int)memoryStream.Position; chRegionIndex.RegionIds[regionIdx] = region.Key; regionIdx++; } stream.Seek(8, SeekOrigin.Begin); // move to beginning of [REGION_INDEX] _runtimeTypeModel.Serialize(stream, chRegionIndex); // write region index. int sizeRegionIndex = (int)(stream.Position - 8); // now at beginning of [REGIONS] memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.WriteTo(stream); // write regions. memoryStream.Dispose(); int startOfBlocks = (int)stream.Position; // now at beginning of [SIZE_OF_BLOCK_INDEX] stream.Seek(0, SeekOrigin.Begin); // move to beginning stream.Write(BitConverter.GetBytes(startOfBlocks), 0, 4); // write start position of blocks. Now at [SIZE_OF_REGION_INDEX] stream.Write(BitConverter.GetBytes(sizeRegionIndex), 0, 4); // write size of blocks index. // serialize the blocks and build their index. memoryStream = new MemoryStream(); List <int> blockLocations = new List <int>(); uint vertexId = 1; while (vertexId < sortedGraph.VertexCount) { uint blockId = vertexId; List <CHArc> blockArcs = new List <CHArc>(); List <CHVertex> blockVertices = new List <CHVertex>(); while (vertexId < blockId + BlockVertexSize && vertexId < sortedGraph.VertexCount + 1) { // create this block. CHVertex chVertex = new CHVertex(); float latitude, longitude; sortedGraph.GetVertex(vertexId, out latitude, out longitude); chVertex.Latitude = latitude; chVertex.Longitude = longitude; chVertex.ArcIndex = (ushort)(blockArcs.Count); foreach (KeyValuePair <uint, CHEdgeData> sortedArc in sortedGraph.GetArcs(vertexId)) { CHArc chArc = new CHArc(); chArc.TargetId = sortedArc.Key; chArc.ShortcutId = sortedArc.Value.ContractedVertexId; chArc.Weight = sortedArc.Value.Weight; chArc.Direction = sortedArc.Value.Direction; blockArcs.Add(chArc); } chVertex.ArcCount = (ushort)(blockArcs.Count - chVertex.ArcIndex); blockVertices.Add(chVertex); vertexId++; // move to the next vertex. } // create block. CHBlock block = new CHBlock(); block.Arcs = blockArcs.ToArray(); block.Vertices = blockVertices.ToArray(); // TODO: get rid of the list and create an array to begin with. // write blocks. _runtimeTypeModel.Serialize(memoryStream, block); blockLocations.Add((int)memoryStream.Position); } CHBlockIndex blockIndex = new CHBlockIndex(); blockIndex.LocationIndex = blockLocations.ToArray(); stream.Seek(startOfBlocks + 4, SeekOrigin.Begin); // move to beginning of [BLOCK_INDEX] _runtimeTypeModel.Serialize(stream, blockIndex); // write region index. int sizeBlockIndex = (int)(stream.Position - (startOfBlocks + 4)); // now at beginning of [BLOCKS] memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.WriteTo(stream); // write blocks. memoryStream.Dispose(); stream.Seek(startOfBlocks, SeekOrigin.Begin); // move to [SIZE_OF_BLOCK_INDEX] stream.Write(BitConverter.GetBytes(sizeBlockIndex), 0, 4); // write start position of blocks. Now at [SIZE_OF_REGION_INDEX] stream.Flush(); }
/// <summary> /// Disposes of all resources associated with this enumerator. /// </summary> public void Dispose() { _graph = null; _current = null; }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witnessCalculator"></param> public CHPreProcessor(IDynamicGraph <CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witnessCalculator) : this(target, calculator, witnessCalculator, false) { }
/// <summary> /// Creates depth-first enumerator. /// </summary> /// <param name="graph"></param> public CHDepthFirstEnumerator(IDynamicGraph <CHEdgeData> graph) { _graph = graph; _index = new LongIndex(); }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witnessCalculator"></param> public CHPreProcessor(IDynamicGraph<CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witnessCalculator) : this(target, calculator, witnessCalculator, false) { }