public void TestUncontractedWitnessed() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 2, 100, null, Constants.NO_VERTEX); graph.AddEdge(2, 1, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 3, 10, null, Constants.NO_VERTEX); graph.AddEdge(3, 1, 10, null, Constants.NO_VERTEX); graph.AddEdge(3, 2, 10, null, Constants.NO_VERTEX); graph.AddEdge(2, 3, 10, null, Constants.NO_VERTEX); graph.Compress(); // contract graph. var priorities = new Dictionary <uint, float>(); priorities.Add(1, 0); priorities.Add(0, 1); priorities.Add(2, 2); priorities.Add(3, 3); var hierarchyBuilder = new HierarchyBuilder(graph, new MockPriorityCalculator(priorities), new DykstraWitnessCalculator(int.MaxValue)); hierarchyBuilder.Run(); // edges 1->2 and 2->1 should have been removed. var edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); var edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(110, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); }
public void Test3Vertices() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 2, 100, null, Constants.NO_VERTEX); graph.AddEdge(2, 1, 100, null, Constants.NO_VERTEX); graph.Compress(); // contract graph. var hierarchyBuilder = new HierarchyBuilder(graph, new EdgeDifferencePriorityCalculator(graph, new DykstraWitnessCalculator(int.MaxValue)), new DykstraWitnessCalculator(int.MaxValue)); hierarchyBuilder.Run(); // check edges. var edges01 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges01); var edge10 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edge10); var edge12 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edge12); var edges21 = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges21); }
public void TestOneEdge() { // build graph. var graph = new Itinero.Graphs.Graph(EdgeDataSerializer.Size); graph.AddVertex(0); graph.AddVertex(1); graph.AddEdge(0, 1, EdgeDataSerializer.Serialize(new EdgeData() { Distance = 100, Profile = 1 })); // build speed profile function. var speed = 100f / 3.6f; Func <ushort, Factor> getFactor = (x) => { return(new Factor() { Direction = 0, Value = 1.0f / speed }); }; // convert graph. var directedGraph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); var algorithm = new DirectedGraphBuilder(graph, directedGraph, getFactor); algorithm.Run(); // check result. Assert.IsTrue(algorithm.HasRun); Assert.IsTrue(algorithm.HasSucceeded); directedGraph.Compress(); Assert.AreEqual(2, directedGraph.VertexCount); Assert.AreEqual(2, directedGraph.EdgeCount); // verify all edges. var edges = directedGraph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count); var data = ContractedEdgeDataSerializer.Serialize(100 * getFactor(1).Value, null); Assert.AreEqual(data, edges.First().Data[0]); Assert.AreEqual(Constants.NO_VERTEX, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = directedGraph.GetEdgeEnumerator(1); Assert.AreEqual(1, edges.Count); data = ContractedEdgeDataSerializer.Serialize(100 * getFactor(1).Value, null); Assert.AreEqual(data, edges.First().Data[0]); Assert.AreEqual(Constants.NO_VERTEX, edges.First().MetaData[0]); Assert.AreEqual(0, edges.First().Neighbour); }
public void TestUncontractedWitnessed() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 2, 100, null, Constants.NO_VERTEX); graph.AddEdge(2, 1, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 3, 10, null, Constants.NO_VERTEX); graph.AddEdge(3, 1, 10, null, Constants.NO_VERTEX); graph.AddEdge(3, 2, 10, null, Constants.NO_VERTEX); graph.AddEdge(2, 3, 10, null, Constants.NO_VERTEX); graph.Compress(); // contract graph. var hierarchyBuilder = new Itinero.Algorithms.Contracted.Dual.HierarchyBuilder(graph, new DykstraWitnessCalculator(graph.Graph, int.MaxValue)); hierarchyBuilder.ContractedFactor = 0; hierarchyBuilder.DepthFactor = 0; hierarchyBuilder.Run(); var edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edge); var edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); }
/// <summary> /// Search forward from one vertex. /// </summary> /// <returns></returns> private void SearchForward(BinaryHeap <EdgePath <T> > queue, EdgePath <T> current) { if (current != null) { // there is a next vertex found. // check restrictions. if (_restrictions != null && _restrictions.Update(current.Vertex) && _restrictions.Restricts(current.Vertex)) { // vertex is restricted, don't settle. return; } // get the edge enumerator. var edgeEnumerator = _graph.GetEdgeEnumerator(); // add to the settled vertices. EdgePath <T> previousLinkedRoute; if (_forwardVisits.TryGetValue(current.Vertex, out previousLinkedRoute)) { if (_weightHandler.IsLargerThan(previousLinkedRoute.Weight, current.Weight)) { // settle the vertex again if it has a better weight. _forwardVisits[current.Vertex] = current; } } else { // settled the vertex. _forwardVisits.Add(current.Vertex, current); } // get neighbours. edgeEnumerator.MoveTo(current.Vertex); // add the neighbours to the queue. while (edgeEnumerator.MoveNext()) { bool?neighbourDirection; var neighbourWeight = _weightHandler.GetEdgeWeight(edgeEnumerator.Current, out neighbourDirection); if (neighbourDirection == null || neighbourDirection.Value) { // the edge is forward, and is to higher or was not contracted at all. var neighbourNeighbour = edgeEnumerator.Neighbour; if (!_forwardVisits.ContainsKey(neighbourNeighbour)) { // if not yet settled. var routeToNeighbour = new EdgePath <T>( neighbourNeighbour, _weightHandler.Add(current.Weight, neighbourWeight), current); queue.Push(routeToNeighbour, _weightHandler.GetMetric(routeToNeighbour.Weight)); } } } } }
/// <summary> /// Search forward from one vertex. /// </summary> /// <returns></returns> private void SearchForward(BinaryHeap <uint> queue, uint cPointer, uint cVertex, T cWeight) { if (cPointer != uint.MaxValue) { // there is a next vertex found. // add to the settled vertices. uint ePointer; // the existing pointer. if (_forwardVisits.TryGetValue(cVertex, out ePointer)) { uint eVertex, ePreviousPointer; T eWeight; _weightHandler.GetPathTree(_pathTree, ePointer, out eVertex, out eWeight, out ePreviousPointer); if (_weightHandler.IsLargerThan(eWeight, cWeight)) { // settle the vertex again if it has a better weight. _forwardVisits[cVertex] = cPointer; } else { // this is a worse settled, don't continue the search. return; } } else { // settled the vertex. _forwardVisits.Add(cVertex, cPointer); } // get neighbours. var edgeEnumerator = _graph.GetEdgeEnumerator(); edgeEnumerator.MoveTo(cVertex); // add the neighbours to the queue. while (edgeEnumerator.MoveNext()) { var nWeightAndDirection = _weightHandler.GetEdgeWeight(edgeEnumerator.Current); if (nWeightAndDirection.Direction.F) { var nVertex = edgeEnumerator.Neighbour; if (!_forwardVisits.ContainsKey(nVertex)) { // if not yet settled. var nWeight = _weightHandler.Add(cWeight, nWeightAndDirection.Weight); var nPointer = _weightHandler.AddPathTree(_pathTree, nVertex, nWeight, cPointer); queue.Push(nPointer, _weightHandler.GetMetric(nWeight)); } } } } }
/// <summary> /// Expands a the shortest edge between the two given vertices. /// </summary> public static void ExpandEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, List <uint> vertices, bool inverted, bool forward) { var edgeEnumerator = graph.GetEdgeEnumerator(); edgeEnumerator.ExpandEdge(vertex1, vertex2, vertices, inverted, forward); }
/// <summary> /// Gets the shortest edge between two vertices. /// </summary> /// <returns></returns> public static MetaEdge GetShortestEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, Func <uint[], float?> getWeight) { var minWeight = float.MaxValue; var edges = graph.GetEdgeEnumerator(vertex1); MetaEdge edge = null; while (edges.MoveNext()) { if (edges.Neighbour == vertex2) { // the correct neighbour, get the weight. var data = edges.Data; var weight = getWeight(data); if (weight.HasValue && weight.Value < minWeight) { // weight is better. edge = new MetaEdge() { Data = data, Neighbour = vertex2, Id = edges.Id, MetaData = edges.MetaData }; minWeight = weight.Value; } } } return(edge); }
/// <summary> /// Updates the vertex info object with the given vertex. /// </summary> private void UpdateVertexInfo(uint v) { // update vertex info. _vertexInfo.Clear(); _vertexInfo.Vertex = v; var contracted = 0; _contractionCount.TryGetValue(v, out contracted); _vertexInfo.ContractedNeighbours = contracted; var depth = 0; _depth.TryGetValue(v, out depth); _vertexInfo.Depth = depth; // calculate shortcuts and witnesses. _vertexInfo.AddRelevantEdges(_graph.GetEdgeEnumerator()); _vertexInfo.BuildShortcuts(_weightHandler); _vertexInfo.Shortcuts.RemoveWitnessed(v, _witnessCalculator); }
public void TestRemoveEdge() { var graph = new DirectedMetaGraph(1, 1, 10); // add and remove edge. graph.AddEdge(0, 1, 10, 100); Assert.AreEqual(0, graph.RemoveEdge(1, 0)); Assert.AreEqual(1, graph.RemoveEdge(0, 1)); graph = new DirectedMetaGraph(1, 1, 10); // add and remove edge. graph.AddEdge(0, 1, 10, 100); graph.AddEdge(0, 1, 20, 200); Assert.AreEqual(2, graph.GetEdgeEnumerator(0).Count); Assert.AreEqual(0, graph.RemoveEdge(1, 0)); Assert.AreEqual(2, graph.RemoveEdge(0, 1)); Assert.AreEqual(0, graph.GetEdgeEnumerator(0).Count); graph = new DirectedMetaGraph(1, 1, 10); // add and remove edge. graph.AddEdge(0, 1, 10, 100); graph.AddEdge(0, 1, 20, 200); Assert.AreEqual(2, graph.GetEdgeEnumerator(0).Count); Assert.AreEqual(0, graph.RemoveEdge(1, 0)); Assert.AreEqual(2, graph.RemoveEdge(0, 1)); Assert.AreEqual(0, graph.GetEdgeEnumerator(0).Count); graph = new DirectedMetaGraph(1, 1, 10); // add and remove edge. graph.AddEdge(0, 1, 10, 100); graph.AddEdge(0, 2, 20, 200); graph.RemoveEdge(0, 1); var edges = graph.GetEdgeEnumerator(0); Assert.IsNotNull(edges); Assert.AreEqual(2, edges.First().Neighbour); }
public void TestDoubleContraction() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 2, 100, null, Constants.NO_VERTEX); graph.AddEdge(2, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(0, 3, 100, null, Constants.NO_VERTEX); graph.AddEdge(3, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 2, 200, null, Constants.NO_VERTEX); graph.AddEdge(2, 1, 200, null, Constants.NO_VERTEX); graph.AddEdge(1, 3, 200, null, Constants.NO_VERTEX); graph.AddEdge(3, 1, 200, null, Constants.NO_VERTEX); graph.Compress(); // contract graph. var priorityCalculator = new EdgeDifferencePriorityCalculator(graph, new DykstraWitnessCalculator(int.MaxValue)); priorityCalculator.DepthFactor = 0; priorityCalculator.ContractedFactor = 0; var hierarchyBuilder = new HierarchyBuilder(graph, priorityCalculator, new DykstraWitnessCalculator(int.MaxValue)); hierarchyBuilder.Run(); // check edges. var edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNotNull(edge); edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNotNull(edge); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNotNull(edge); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); }
/// <summary> /// Updates the vertex info object with the given vertex. /// </summary> /// <returns>True if succeeded, false if a witness calculation is required.</returns> private bool UpdateVertexInfo(uint v) { var contracted = 0; var depth = 0; // update vertex info. _vertexInfo.Clear(); _vertexInfo.Vertex = v; _contractionCount.TryGetValue(v, out contracted); _vertexInfo.ContractedNeighbours = contracted; _depth.TryGetValue(v, out depth); _vertexInfo.Depth = depth; // add neighbours. _vertexInfo.AddRelevantEdges(_graph.GetEdgeEnumerator()); // check if any of neighbours are in witness queue. if (_witnessQueue.Count > 0) { for (var i = 0; i < _vertexInfo.Count; i++) { var m = _vertexInfo[i]; if (_witnessQueue.Contains(m.Neighbour)) { //this.DoWitnessQueue(); //break; return(false); } } } // build shortcuts. _vertexInfo.BuildShortcuts(_weightHandler); // remove witnessed shortcuts. _vertexInfo.RemoveShortcuts(_witnessGraph, _weightHandler); return(true); }
public void Test2VerticesAgumented() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaAugmentedSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX, 50, 1000); graph.Compress(); // contract graph. var hierarchyBuilder = new Itinero.Algorithms.Contracted.Dual.HierarchyBuilder(graph, new DykstraWitnessCalculator(graph.Graph, int.MaxValue)); hierarchyBuilder.Run(); // check edges. var edges01 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges01); var edge10 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edge10); }
public void TestSerialize() { var graph = new DirectedMetaGraph(1, 1, 10); // add and compress. graph.AddEdge(0, 1, 1, 100); graph.Compress(); var expectedSize = 1 + 1 + 8 + 8 + 4 + 4 + // the header: two longs representing vertex and edge count and one int for edge size and one for vertex size. graph.VertexCount * 2 * 4 + // the bytes for the vertex-index: 2 uint's. graph.EdgeCount * 2 * 4 + // the bytes for the edges: one edge 1 uint. 4 + 4 + // the header for the meta-data: 2 uint for sizes. graph.EdgeCount * 4; // the bytes for the edges: one edge 1 uint. using (var stream = new System.IO.MemoryStream()) { Assert.AreEqual(expectedSize, graph.Serialize(stream)); Assert.AreEqual(expectedSize, stream.Position); } // verify all edges. var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Data[0]); Assert.AreEqual(1, edges.First().Neighbour); graph = new DirectedMetaGraph(1, 1, 10); // add and compress. graph.AddEdge(0, 1, 10, 100); graph.AddEdge(1, 2, 20, 200); graph.AddEdge(2, 3, 30, 300); graph.AddEdge(3, 4, 40, 400); graph.RemoveEdge(1, 2); graph.Compress(); expectedSize = 1 + 1 + 8 + 8 + 4 + 4 + // the header: two longs representing vertex and edge count and one int for edge size and one for vertex size. graph.VertexCount * 2 * 4 + // the bytes for the vertex-index: 2 uint's. graph.EdgeCount * 2 * 4 + // the bytes for the edges: one edge 1 uint. 4 + 4 + // the header for the meta-data: 2 uint for sizes. graph.EdgeCount * 4; // the bytes for the edges: one edge 1 uint. using (var stream = new System.IO.MemoryStream()) { Assert.AreEqual(expectedSize, graph.Serialize(stream)); Assert.AreEqual(expectedSize, stream.Position); } }
/// <summary> /// Initializes and resets. /// </summary> public void Initialize() { // algorithm always succeeds, it may be dealing with an empty network and there are no targets. this.HasSucceeded = true; // intialize dykstra data structures. _visits = new Dictionary <uint, EdgePath <T> >(); _heap = new BinaryHeap <EdgePath <T> >(); // queue all sources. foreach (var source in _sources) { _heap.Push(source, _weightHandler.GetMetric(source.Weight)); } // gets the edge enumerator. _edgeEnumerator = _graph.GetEdgeEnumerator(); }
/// <summary> /// Initializes and resets. /// </summary> public void Initialize() { // algorithm always succeeds, it may be dealing with an empty network and there are no targets. this.HasSucceeded = true; // intialize dykstra data structures. _pointerHeap = new BinaryHeap <uint>(); _pathTree = new PathTree(); _visited = new HashSet <uint>(); // queue source. if (_source.Vertex1 != Constants.NO_VERTEX) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex1, _source.Weight1, uint.MaxValue), 0); } if (_source.Vertex2 != Constants.NO_VERTEX) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex2, _source.Weight2, uint.MaxValue), 0); } // gets the edge enumerator. _edgeEnumerator = _graph.GetEdgeEnumerator(); }
/// <summary> /// Remove all witnessed edges. /// </summary> private void RemoveWitnessedEdges() { _logger.Log(TraceEventType.Information, "Removing witnessed edges..."); var witnessEdgeEnumerator = _witnessGraph.GetEdgeEnumerator(); var edgeEnumerator = _graph.GetEdgeEnumerator(); var edges = new List <MetaEdge>(); for (uint vertex = 0; vertex < _graph.VertexCount; vertex++) { // collect all relevant edges. edges.Clear(); if (witnessEdgeEnumerator.MoveTo(vertex) && edgeEnumerator.MoveTo(vertex)) { while (edgeEnumerator.MoveNext()) { if (vertex < edgeEnumerator.Neighbour) { // only check in on directions, all edges are added twice initially. edges.Add(edgeEnumerator.Current); } } } // check witness paths. for (var i = 0; i < edges.Count; i++) { var edge = edges[0]; while (witnessEdgeEnumerator.MoveNext()) { if (witnessEdgeEnumerator.Neighbour == edge.Neighbour) { // this edge is witnessed, figure out how. var forwardWitnessWeight = DirectedGraphExtensions.FromData(witnessEdgeEnumerator.Data0); var backwardWitnessWeight = DirectedGraphExtensions.FromData(witnessEdgeEnumerator.Data1); var weightAndDir = _weightHandler.GetEdgeWeight(edge); var weight = _weightHandler.GetMetric(weightAndDir.Weight); var witnessed = false; if (weightAndDir.Direction.F && weight > forwardWitnessWeight) { // witnessed in forward direction. weightAndDir.Direction = new Dir(false, weightAndDir.Direction.B); witnessed = true; } if (weightAndDir.Direction.B && weight > backwardWitnessWeight) { // witnessed in backward direction. weightAndDir.Direction = new Dir(weightAndDir.Direction.F, false); witnessed = true; } if (witnessed) { // edge was witnessed, do something. // remove the edge (in both directions) _graph.RemoveEdge(vertex, edge.Neighbour); _graph.RemoveEdge(edge.Neighbour, vertex); if (weightAndDir.Direction.B || weightAndDir.Direction.F) { // add it again if there is something relevant still left. _weightHandler.AddEdge(_graph, vertex, edge.Neighbour, Constants.NO_VERTEX, weightAndDir.Direction.AsNullableBool(), weightAndDir.Weight); weightAndDir.Direction.Reverse(); _weightHandler.AddEdge(_graph, edge.Neighbour, vertex, Constants.NO_VERTEX, weightAndDir.Direction.AsNullableBool(), weightAndDir.Weight); } } } } } } }
public void TestCompress() { var graph = new DirectedMetaGraph(1, 1, 10); // add and compress. graph.AddEdge(0, 1, 1, 100); graph.Compress(); // verify all edges. var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Data[0]); Assert.AreEqual(1, edges.First().Neighbour); graph = new DirectedMetaGraph(1, 1, 10); // add and compress. graph.AddEdge(0, 1, 10, 100); graph.AddEdge(1, 2, 20, 200); graph.AddEdge(2, 3, 30, 300); graph.AddEdge(3, 4, 40, 400); graph.RemoveEdge(1, 2); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(3, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(4, edges.First().Neighbour); // compress. graph.Compress(); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(3, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(4, edges.First().Neighbour); }
/// <summary> /// Calculates the priority of the given vertex. /// </summary> public float Calculate(BitArray32 contractedFlags, uint vertex) { var removed = 0; var added = 0; // get and keep edges. var edges = new List <Edge>(_graph.Graph.GetEdgeEnumerator(vertex)); // remove 'downward' edge to vertex. var i = 0; while (i < edges.Count) { var edgeEnumerator = _graph.GetEdgeEnumerator(edges[i].Neighbour); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == vertex) { removed++; } } if (contractedFlags[edges[i].Neighbour]) { // neighbour was already contracted, remove 'downward' edge and exclude it. edgeEnumerator.MoveTo(vertex); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == edges[i].Neighbour) { removed++; } } edges.RemoveAt(i); } else { // move to next edge. i++; } } // loop over all edge-pairs once. for (var j = 1; j < edges.Count; j++) { var edge1 = edges[j]; float edge1Weight; bool? edge1Direction; Data.Contracted.Edges.ContractedEdgeDataSerializer.Deserialize(edge1.Data[0], out edge1Weight, out edge1Direction); var edge1CanMoveForward = edge1Direction == null || edge1Direction.Value; var edge1CanMoveBackward = edge1Direction == null || !edge1Direction.Value; // figure out what witness paths to calculate. var forwardWitnesses = new bool[j]; var backwardWitnesses = new bool[j]; var targets = new List <uint>(j); var targetWeights = new List <float>(j); for (var k = 0; k < j; k++) { var edge2 = edges[k]; float edge2Weight; bool? edge2Direction; Data.Contracted.Edges.ContractedEdgeDataSerializer.Deserialize(edge2.Data[0], out edge2Weight, out edge2Direction); var edge2CanMoveForward = edge2Direction == null || edge2Direction.Value; var edge2CanMoveBackward = edge2Direction == null || !edge2Direction.Value; forwardWitnesses[k] = !(edge1CanMoveBackward && edge2CanMoveForward); backwardWitnesses[k] = !(edge1CanMoveForward && edge2CanMoveBackward); targets.Add(edge2.Neighbour); targetWeights.Add(edge1Weight + edge2Weight); } // calculate all witness paths. _witnessCalculator.Calculate(_graph.Graph, edge1.Neighbour, targets, targetWeights, ref forwardWitnesses, ref backwardWitnesses, vertex); // add contracted edges if needed. for (var k = 0; k < j; k++) { var edge2 = edges[k]; var removedLocal = 0; var addedLocal = 0; if (!forwardWitnesses[k] && !backwardWitnesses[k]) { // add bidirectional edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, targetWeights[k], null, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, targetWeights[k], null, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; } else if (!forwardWitnesses[k]) { // add forward edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, targetWeights[k], true, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, targetWeights[k], false, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; } else if (!backwardWitnesses[k]) { // add forward edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, targetWeights[k], false, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, targetWeights[k], true, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; } } } var contracted = 0; _contractionCount.TryGetValue(vertex, out contracted); var depth = 0; _depth.TryGetValue(vertex, out depth); return(this.DifferenceFactor * (added - removed) + (this.DepthFactor * depth) + (this.ContractedFactor * contracted)); }
public void TestAddEdge() { var graph = new DirectedMetaGraph(1, 1, 10); // add edge. graph.AddEdge(0, 1, 10, 100); // verify all edges. var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(0, edges.Count()); // add another edge. graph.AddEdge(1, 2, 20, 200); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(20, edges.First().Data[0]); Assert.AreEqual(200, edges.First().MetaData[0]); Assert.AreEqual(2, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); // add another edge. graph.AddEdge(1, 3, 30, 300); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(2, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(0, edges.Count()); // add another edge but in reverse. graph.AddEdge(3, 1, 30, 300); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(2, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); // add another edge and start a new island. graph.AddEdge(4, 5, 40, 400); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(2, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(5, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(5); Assert.AreEqual(0, edges.Count()); // connect the islands. graph.AddEdge(5, 3, 50, 500); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(2, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(5, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(5); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(50, edges.First().Data[0]); Assert.AreEqual(500, edges.First().MetaData[0]); Assert.AreEqual(3, edges.First().Neighbour); graph.AddEdge(1, 6, 60, 600); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(3, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 6)); Assert.AreEqual(60, edges.First(x => x.Neighbour == 6).Data[0]); Assert.AreEqual(600, edges.First(x => x.Neighbour == 6).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(5, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(5); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(50, edges.First().Data[0]); Assert.AreEqual(500, edges.First().MetaData[0]); Assert.AreEqual(3, edges.First().Neighbour); graph.AddEdge(1, 7, 70, 700); // verify all edges. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(10, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(4, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(30, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 6)); Assert.AreEqual(60, edges.First(x => x.Neighbour == 6).Data[0]); Assert.AreEqual(600, edges.First(x => x.Neighbour == 6).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 7)); Assert.AreEqual(70, edges.First(x => x.Neighbour == 7).Data[0]); Assert.AreEqual(700, edges.First(x => x.Neighbour == 7).MetaData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(0, edges.Count()); edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[0]); Assert.AreEqual(300, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(40, edges.First().Data[0]); Assert.AreEqual(400, edges.First().MetaData[0]); Assert.AreEqual(5, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(5); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(50, edges.First().Data[0]); Assert.AreEqual(500, edges.First().MetaData[0]); Assert.AreEqual(3, edges.First().Neighbour); }
public void TestGetEdgeEnumerator() { var graph = new DirectedMetaGraph(1, 1, 10); // add edges. graph.AddEdge(0, 1, 1, 100); graph.AddEdge(1, 2, 2, 200); graph.AddEdge(1, 3, 3, 300); graph.AddEdge(3, 4, 4, 400); graph.AddEdge(4, 1, 5, 500); graph.AddEdge(5, 1, 6, 600); // get empty edge enumerator. var edges = graph.GetEdgeEnumerator(); // move to vertices and test result. Assert.IsTrue(edges.MoveTo(0)); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Data[0]); Assert.AreEqual(100, edges.First().MetaData[0]); Assert.AreEqual(1, edges.First().Neighbour); Assert.IsTrue(edges.MoveTo(1)); Assert.AreEqual(2, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 2)); Assert.AreEqual(2, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).MetaData[0]); Assert.IsTrue(edges.Any(x => x.Neighbour == 3)); Assert.AreEqual(3, edges.First(x => x.Neighbour == 3).Data[0]); Assert.AreEqual(300, edges.First(x => x.Neighbour == 3).MetaData[0]); Assert.IsFalse(edges.MoveTo(2)); Assert.IsTrue(edges.MoveTo(3)); Assert.AreEqual(1, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 4)); Assert.AreEqual(4, edges.First(x => x.Neighbour == 4).Data[0]); Assert.AreEqual(400, edges.First(x => x.Neighbour == 4).MetaData[0]); Assert.IsTrue(edges.MoveTo(4)); Assert.AreEqual(1, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 1)); Assert.AreEqual(5, edges.First(x => x.Neighbour == 1).Data[0]); Assert.AreEqual(500, edges.First(x => x.Neighbour == 1).MetaData[0]); Assert.IsTrue(edges.MoveTo(5)); Assert.AreEqual(1, edges.Count()); Assert.IsTrue(edges.Any(x => x.Neighbour == 1)); Assert.AreEqual(6, edges.First(x => x.Neighbour == 1).Data[0]); Assert.AreEqual(600, edges.First(x => x.Neighbour == 1).MetaData[0]); graph = new DirectedMetaGraph(1, 1, 10); // add edge. graph.AddEdge(0, 1, 1, 100); graph.AddEdge(0, 11001, 1, 100); graph.AddEdge(0, 11001, 2, 200); edges = graph.GetEdgeEnumerator(); // move to vertices and test result. Assert.IsTrue(edges.MoveTo(0)); Assert.AreEqual(3, edges.Count()); }
public void TestAddOrUpdateEdge() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 99, null, Constants.NO_VERTEX); // check result. var edges = new List <MetaEdge>(graph.GetEdgeEnumerator(0).Where(x => x.Neighbour == 1)); Assert.AreEqual(1, edges.Count); Assert.AreEqual(1, edges[0].Neighbour); var edgeData = ContractedEdgeDataSerializer.Deserialize(edges[0].Data[0], edges[0].MetaData[0]); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 101, null, Constants.NO_VERTEX); // check result. edges = new List <MetaEdge>(graph.GetEdgeEnumerator(0).Where(x => x.Neighbour == 1)); Assert.AreEqual(1, edges.Count); Assert.AreEqual(1, edges[0].Neighbour); edgeData = ContractedEdgeDataSerializer.Deserialize(edges[0].Data[0], edges[0].MetaData[0]); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(100, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, true, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 99, true, Constants.NO_VERTEX); // check result. edges = new List <MetaEdge>(graph.GetEdgeEnumerator(0).Where(x => x.Neighbour == 1)); Assert.AreEqual(1, edges.Count); Assert.AreEqual(1, edges[0].Neighbour); edgeData = ContractedEdgeDataSerializer.Deserialize(edges[0].Data[0], edges[0].MetaData[0]); Assert.AreEqual(true, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 99, true, Constants.NO_VERTEX); // check result. var edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == false); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(100, edgeData.Weight); edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == true); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, false, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 99, true, Constants.NO_VERTEX); // check result. edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == false); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(100, edgeData.Weight); edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == true); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, false, Constants.NO_VERTEX); graph.AddEdge(0, 1, 99, true, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 98, null, Constants.NO_VERTEX); // check result. edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == null); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(98, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, false, Constants.NO_VERTEX); graph.AddEdge(0, 1, 98, true, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 1, 99, null, Constants.NO_VERTEX); // check result. edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == false); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == true); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(98, edgeData.Weight); // build graph. graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); // update. graph.AddOrUpdateEdge(0, 2, 99, null, Constants.NO_VERTEX); // check result. edge = graph.GetEdgeEnumerator(0).First(x => x.Neighbour == 2 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == null); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); Assert.AreEqual(99, edgeData.Weight); }
/// <summary> /// Tries adding or updating an edge and returns #added and #removed edges. /// </summary> /// <returns></returns> public static void TryAddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId, out int added, out int removed) { var hasExistingEdge = false; var hasExistingEdgeOnlySameDirection = true; var edgeCount = 0; var edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == vertex2) { edgeCount++; hasExistingEdge = true; if (ContractedEdgeDataSerializer.HasDirection(edgeEnumerator.Data0, direction)) { // has the same direction. if (weight < ContractedEdgeDataSerializer.DeserializeWeight(edgeEnumerator.Data0)) { // the weight is better, just update. added = 1; removed = 1; return; } hasExistingEdgeOnlySameDirection = false; } } } if (!hasExistingEdge) { // no edge exists yet. added = 1; removed = 0; return; } else if (hasExistingEdgeOnlySameDirection) { // there is an edge already but it has a better weight. added = 0; removed = 0; return; } else { // see what's there and update if needed. var forward = false; var forwardWeight = float.MaxValue; var forwardContractedId = uint.MaxValue; var backward = false; var backwardWeight = float.MaxValue; var backwardContractedId = uint.MaxValue; if (direction == null || direction.Value) { forward = true; forwardWeight = weight; forwardContractedId = contractedId; } if (direction == null || !direction.Value) { backward = true; backwardWeight = weight; backwardContractedId = contractedId; } edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == vertex2) { float localWeight; bool? localDirection; uint localContractedId; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, edgeEnumerator.MetaData0, out localWeight, out localDirection, out localContractedId); if (localDirection == null || localDirection.Value) { if (localWeight < forwardWeight) { forwardWeight = localWeight; forward = true; forwardContractedId = localContractedId; } } if (localDirection == null || !localDirection.Value) { if (localWeight < backwardWeight) { backwardWeight = localWeight; backward = true; backwardContractedId = localContractedId; } } } } removed = edgeCount; added = 0; if (forward && backward && forwardWeight == backwardWeight && forwardContractedId == backwardContractedId) { // add one bidirectional edge. added++; } else { // add two unidirectional edges if needed. if (forward) { // there is a forward edge. added++; } if (backward) { // there is a backward edge. added++; } } } }
/// <summary> /// Add or update edge. /// </summary> /// <returns></returns> public static void AddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId, float distance, float time) { var current = ContractedEdgeDataSerializer.Serialize(weight, direction); var hasExistingEdge = false; var hasExistingEdgeOnlySameDirection = true; if (graph.UpdateEdge(vertex1, vertex2, (data) => { hasExistingEdge = true; if (ContractedEdgeDataSerializer.HasDirection(data[0], direction)) { // has the same direction. if (weight < ContractedEdgeDataSerializer.DeserializeWeight(data[0])) { // the weight is better, just update. return(true); } return(false); } hasExistingEdgeOnlySameDirection = false; return(false); }, new uint[] { current }, ContractedEdgeDataSerializer.SerializeMetaAugmented(contractedId, distance, time)) != Constants.NO_EDGE) { // updating the edge succeeded. return; } if (!hasExistingEdge) { // no edge exists yet. graph.AddEdge(vertex1, vertex2, new uint[] { current }, ContractedEdgeDataSerializer.SerializeMetaAugmented( contractedId, distance, time)); return; } else if (hasExistingEdgeOnlySameDirection) { // there is an edge already but it has a better weight. return; } else { // see what's there and update if needed. var forward = false; var forwardWeight = float.MaxValue; var forwardContractedId = uint.MaxValue; var forwardTime = float.MaxValue; var forwardDistance = float.MaxValue; var backward = false; var backwardWeight = float.MaxValue; var backwardContractedId = uint.MaxValue; var backwardTime = float.MaxValue; var backwardDistance = float.MaxValue; if (direction == null || direction.Value) { forward = true; forwardWeight = weight; forwardContractedId = contractedId; forwardTime = time; forwardDistance = distance; } if (direction == null || !direction.Value) { backward = true; backwardWeight = weight; backwardContractedId = contractedId; backwardTime = time; backwardDistance = distance; } var edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if (edgeEnumerator.Neighbour == vertex2) { float localWeight; bool? localDirection; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out localWeight, out localDirection); uint localContractedId; float localTime; float localDistance; ContractedEdgeDataSerializer.DeserializeMetaAgumented(edgeEnumerator.MetaData, out localContractedId, out localDistance, out localTime); if (localDirection == null || localDirection.Value) { if (localWeight < forwardWeight) { forwardWeight = localWeight; forward = true; forwardContractedId = localContractedId; forwardTime = localTime; forwardDistance = localDistance; } } if (localDirection == null || !localDirection.Value) { if (localWeight < backwardWeight) { backwardWeight = localWeight; backward = true; backwardContractedId = localContractedId; backwardDistance = localDistance; backwardTime = localTime; } } } } graph.RemoveEdge(vertex1, vertex2); if (forward && backward && forwardWeight == backwardWeight && forwardContractedId == backwardContractedId) { // add one bidirectional edge. graph.AddEdge(vertex1, vertex2, forwardWeight, null, forwardContractedId, forwardDistance, forwardTime); //graph.AddEdge(vertex1, vertex2, // ContractedEdgeDataSerializer.Serialize(forwardWeight, null), forwardContractedId); } else { // add two unidirectional edges if needed. if (forward) { // there is a forward edge. graph.AddEdge(vertex1, vertex2, forwardWeight, true, forwardContractedId, forwardDistance, forwardTime); //graph.AddEdge(vertex1, vertex2, // ContractedEdgeDataSerializer.Serialize(forwardWeight, true), forwardContractedId); } if (backward) { // there is a backward edge. graph.AddEdge(vertex1, vertex2, backwardWeight, false, backwardContractedId, backwardDistance, backwardTime); } } } }
private BitArray32 _contractedFlags; // contains flags for contracted vertices. /// <summary> /// Excutes the actual run. /// </summary> protected override void DoRun() { _queue = new BinaryHeap <uint>((uint)_graph.VertexCount); _contractedFlags = new BitArray32(_graph.VertexCount); _missesQueue = new Queue <bool>(); // remove all edges that have witness paths, meaning longer than the shortest path // between the two ending vertices. this.RemoveWitnessedEdges(); // build queue. this.CalculateQueue(); var next = this.SelectNext(); var latestProgress = 0f; var current = 0; var total = _graph.VertexCount; while (next != null) { // contract... this.Contract(next.Value); // ... and select next. next = this.SelectNext(); // calculate and log progress. var progress = (float)(System.Math.Floor(((double)current / (double)total) * 10000) / 100.0); if (progress < 99) { progress = (float)(System.Math.Floor(((double)current / (double)total) * 100) / 1.0); } if (progress != latestProgress) { latestProgress = progress; int totaEdges = 0; int totalUncontracted = 0; int maxCardinality = 0; var neighbourCount = new Dictionary <uint, int>(); for (uint v = 0; v < _graph.VertexCount; v++) { if (!_contractedFlags[v]) { neighbourCount.Clear(); var edges = _graph.GetEdgeEnumerator(v); if (edges != null) { var edgesCount = edges.Count; totaEdges = edgesCount + totaEdges; if (maxCardinality < edgesCount) { maxCardinality = edgesCount; } } totalUncontracted++; } } var density = (double)totaEdges / (double)totalUncontracted; _logger.Log(TraceEventType.Information, "Preprocessing... {0}% [{1}/{2}] {3}q #{4} max {5}", progress, current, total, _queue.Count, density, maxCardinality); } current++; } }
public void TestDoubleContractionOneway() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 2, 100, true, Constants.NO_VERTEX); graph.AddEdge(2, 0, 100, false, Constants.NO_VERTEX); graph.AddEdge(0, 3, 10, false, Constants.NO_VERTEX); graph.AddEdge(3, 0, 10, true, Constants.NO_VERTEX); graph.AddEdge(1, 2, 1000, false, Constants.NO_VERTEX); graph.AddEdge(2, 1, 1000, true, Constants.NO_VERTEX); graph.AddEdge(1, 3, 10000, true, Constants.NO_VERTEX); graph.AddEdge(3, 1, 10000, false, Constants.NO_VERTEX); graph.Compress(); // contract graph. var priorityCalculator = new EdgeDifferencePriorityCalculator(graph, new DykstraWitnessCalculator(int.MaxValue)); priorityCalculator.ContractedFactor = 0; priorityCalculator.DepthFactor = 0; var hierarchyBuilder = new HierarchyBuilder(graph, priorityCalculator, new DykstraWitnessCalculator(int.MaxValue)); hierarchyBuilder.Run(); // check edges. var edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNotNull(edge); var edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(true, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(false, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(110, edgeData.Weight); Assert.AreEqual(false, edgeData.Direction); Assert.AreEqual(0, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(1000, edgeData.Weight); Assert.AreEqual(true, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edge); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == true); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(1110, edgeData.Weight); Assert.AreEqual(2, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1 && ContractedEdgeDataSerializer.Deserialize(x.Data[0], x.MetaData[0]).Direction == false); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], edge.MetaData[0]); Assert.AreEqual(10000, edgeData.Weight); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNull(edge); }
public void TestPentagonAugmented() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.DynamicAugmentedFixedSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(1, 2, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(2, 1, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(2, 3, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(3, 2, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(3, 4, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(4, 3, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(4, 0, 100, null, Constants.NO_VERTEX, 50, 1000); graph.AddEdge(0, 4, 100, null, Constants.NO_VERTEX, 50, 1000); graph.Compress(); // contract graph. var priorityCalculator = new EdgeDifferencePriorityCalculator(graph, new DykstraWitnessCalculator(int.MaxValue)); priorityCalculator.ContractedFactor = 0; priorityCalculator.DepthFactor = 0; var hierarchyBuilder = new HierarchyBuilder <Weight>(graph, priorityCalculator, new DykstraWitnessCalculator(int.MaxValue), new WeightHandler(null)); hierarchyBuilder.Run(); // check edges. var edges01 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges01); var edges10 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edges10); var edges12 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edges12); var edges21 = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges21); var edges23 = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edges23); var edges32 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edges32); var edges34 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNull(edges34); var edges43 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edges43); var edges40 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edges40); var edges04 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNotNull(edges04); var edges41 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges41); var edges14 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNull(edges14); var edges31 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges31); var edges13 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNull(edges13); }
public static void TryAddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId, out int added, out int removed) { bool flag1 = false; bool flag2 = true; int num1 = 0; DirectedMetaGraph.EdgeEnumerator edgeEnumerator1 = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator1.MoveNext()) { if ((int)edgeEnumerator1.Neighbour == (int)vertex2) { ++num1; flag1 = true; if (ContractedEdgeDataSerializer.HasDirection(edgeEnumerator1.Data0, direction)) { if ((double)weight < (double)ContractedEdgeDataSerializer.DeserializeWeight(edgeEnumerator1.Data0)) { added = 1; removed = 1; return; } flag2 = false; } } } if (!flag1) { added = 1; removed = 0; } else if (flag2) { added = 0; removed = 0; } else { bool flag3 = false; float num2 = float.MaxValue; uint num3 = uint.MaxValue; bool flag4 = false; float num4 = float.MaxValue; uint num5 = uint.MaxValue; if (!direction.HasValue || direction.Value) { flag3 = true; num2 = weight; num3 = contractedId; } if (!direction.HasValue || !direction.Value) { flag4 = true; num4 = weight; num5 = contractedId; } DirectedMetaGraph.EdgeEnumerator edgeEnumerator2 = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator2.MoveNext()) { if ((int)edgeEnumerator2.Neighbour == (int)vertex2) { float weight1; bool? direction1; uint contractedId1; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator2.Data0, edgeEnumerator2.MetaData0, out weight1, out direction1, out contractedId1); if ((!direction1.HasValue || direction1.Value) && (double)weight1 < (double)num2) { num2 = weight1; flag3 = true; num3 = contractedId1; } if ((!direction1.HasValue || !direction1.Value) && (double)weight1 < (double)num4) { num4 = weight1; flag4 = true; num5 = contractedId1; } } } removed = num1; added = 0; if (flag3 & flag4 && (double)num2 == (double)num4 && (int)num3 == (int)num5) { added = added + 1; } else { if (flag3) { added = added + 1; } if (!flag4) { return; } added = added + 1; } } }
public static void AddOrUpdateEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId) { uint data1 = ContractedEdgeDataSerializer.Serialize(weight, direction); bool hasExistingEdge = false; bool hasExistingEdgeOnlySameDirection = true; if ((int)graph.UpdateEdge(vertex1, vertex2, (Func <uint[], bool>)(data => { hasExistingEdge = true; if (ContractedEdgeDataSerializer.HasDirection(data[0], direction)) { return((double)weight < (double)ContractedEdgeDataSerializer.DeserializeWeight(data[0])); } hasExistingEdgeOnlySameDirection = false; return(false); }), new uint[1] { data1 }, contractedId) != -1) { return; } if (!hasExistingEdge) { int num1 = (int)graph.AddEdge(vertex1, vertex2, data1, contractedId); } else { if (hasExistingEdgeOnlySameDirection) { return; } bool flag1 = false; float weight1 = float.MaxValue; uint metaData1 = uint.MaxValue; bool flag2 = false; float weight2 = float.MaxValue; uint metaData2 = uint.MaxValue; if (!direction.HasValue || direction.Value) { flag1 = true; weight1 = weight; metaData1 = contractedId; } if (!direction.HasValue || !direction.Value) { flag2 = true; weight2 = weight; metaData2 = contractedId; } DirectedMetaGraph.EdgeEnumerator edgeEnumerator = graph.GetEdgeEnumerator(vertex1); while (edgeEnumerator.MoveNext()) { if ((int)edgeEnumerator.Neighbour == (int)vertex2) { float weight3; bool? direction1; uint contractedId1; ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, edgeEnumerator.MetaData0, out weight3, out direction1, out contractedId1); if ((!direction1.HasValue || direction1.Value) && (double)weight3 < (double)weight1) { weight1 = weight3; flag1 = true; metaData1 = contractedId1; } if ((!direction1.HasValue || !direction1.Value) && (double)weight3 < (double)weight2) { weight2 = weight3; flag2 = true; metaData2 = contractedId1; } } } graph.RemoveEdge(vertex1, vertex2); if (flag1 & flag2 && (double)weight1 == (double)weight2 && (int)metaData1 == (int)metaData2) { int num2 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight1, new bool?()), metaData1); } else { if (flag1) { int num3 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight1, new bool?(true)), metaData1); } if (!flag2) { return; } int num4 = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight2, new bool?(false)), metaData2); } } }
public void TestPentagonDirected() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, true, Constants.NO_VERTEX); graph.AddEdge(1, 0, 100, false, Constants.NO_VERTEX); graph.AddEdge(1, 2, 100, true, Constants.NO_VERTEX); graph.AddEdge(2, 1, 100, false, Constants.NO_VERTEX); graph.AddEdge(2, 3, 100, true, Constants.NO_VERTEX); graph.AddEdge(3, 2, 100, false, Constants.NO_VERTEX); graph.AddEdge(3, 4, 100, true, Constants.NO_VERTEX); graph.AddEdge(4, 3, 100, false, Constants.NO_VERTEX); graph.AddEdge(4, 0, 100, true, Constants.NO_VERTEX); graph.AddEdge(0, 4, 100, false, Constants.NO_VERTEX); graph.Compress(); // contract graph. var hierarchyBuilder = new Itinero.Algorithms.Contracted.Dual.HierarchyBuilder(graph, new DykstraWitnessCalculator(graph.Graph, int.MaxValue)); hierarchyBuilder.ContractedFactor = 0; hierarchyBuilder.DepthFactor = 0; hierarchyBuilder.Run(); // check edges. var edges01 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges01); var edges10 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edges10); var edges12 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edges12); var edges21 = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges21); var edges23 = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edges23); var edges32 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNull(edges32); var edges34 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNull(edges34); var edges43 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edges43); var edges40 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNull(edges40); var edges04 = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNotNull(edges04); var edges41 = graph.GetEdgeEnumerator(4).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges41); var edges14 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNull(edges14); var edges31 = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 1); Assert.IsNotNull(edges31); var edges13 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNull(edges13); }