public void Test3Vertices() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 100, null); graph.AddEdge(1, 0, 100, null); graph.AddEdge(1, 2, 100, null); graph.AddEdge(2, 1, 100, null); graph.Compress(); // contract graph. var hierarchyBuilder = new HierarchyBuilder(graph, new EdgeDifferencePriorityCalculator(graph, new DykstraWitnessCalculator(int.MaxValue)), new DykstraWitnessCalculator(int.MaxValue), (i) => Enumerable.Empty <uint[]>()); 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 TestDoubleContractionOneway() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 100, null); graph.AddEdge(1, 0, 100, null); graph.AddEdge(1, 2, 100, null); graph.AddEdge(2, 1, 100, null); graph.AddEdge(1, 3, 10, null); graph.AddEdge(3, 1, 10, null); graph.AddEdge(3, 2, 10, null); graph.AddEdge(2, 3, 10, null); 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), (i) => Enumerable.Empty <uint[]>()); 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], Constants.NO_VERTEX); Assert.AreEqual(110, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); 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], Constants.NO_VERTEX); 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], Constants.NO_VERTEX); Assert.AreEqual(10, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(Constants.NO_VERTEX, edgeData.ContractedId); }
public void TestOneEdgeAugmented() { // 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, FactorAndSpeed> getFactor = (x) => { return(new FactorAndSpeed() { Direction = 0, SpeedFactor = 1.0f / speed, Value = 1.0f / speed }); }; // convert graph. var directedGraph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicAugmentedFixedSize); var algorithm = new DirectedGraphBuilder <Weight>(graph, directedGraph, new WeightHandler(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.SerializeDynamicAugmented(100 * getFactor(1).Value, null, 100, 100 * getFactor(1).Value); Assert.AreEqual(data[0], edges.First().Data[0]); Assert.AreEqual(data[1], edges.First().Data[1]); Assert.AreEqual(data[2], edges.First().Data[2]); Assert.AreEqual(1, edges.First().Neighbour); edges = directedGraph.GetEdgeEnumerator(1); Assert.AreEqual(1, edges.Count()); data = ContractedEdgeDataSerializer.SerializeDynamicAugmented(100 * getFactor(1).Value, null, 100, 100 * getFactor(1).Value); Assert.AreEqual(data[0], edges.First().Data[0]); Assert.AreEqual(data[1], edges.First().Data[1]); Assert.AreEqual(data[2], edges.First().Data[2]); Assert.AreEqual(0, edges.First().Neighbour); }
public void TestRemoveEdge() { var graph = new DirectedDynamicGraph(); graph.AddEdge(1, 2, 0102, 010200); graph.AddEdge(1, 3, 0103); Assert.AreEqual(1, graph.RemoveEdge(1, 2)); Assert.AreEqual(1, graph.EdgeCount); var enumerator = graph.GetEdgeEnumerator(); Assert.IsTrue(enumerator.MoveTo(1)); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(3, enumerator.Neighbour); Assert.AreEqual(0103, enumerator.Data0); graph = new DirectedDynamicGraph(); graph.AddEdge(1, 2, 0102, 010200); graph.AddEdge(1, 3, 0103); graph.AddEdge(1, 4, 0104, 010400, 01040000); Assert.AreEqual(1, graph.RemoveEdge(1, 3)); enumerator = graph.GetEdgeEnumerator(); Assert.IsTrue(enumerator.MoveTo(1)); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(2, enumerator.Neighbour); Assert.AreEqual(0102, enumerator.Data0); Assert.AreEqual(010200, enumerator.DynamicData[0]); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(4, enumerator.Neighbour); Assert.AreEqual(0104, enumerator.Data0); Assert.AreEqual(010400, enumerator.DynamicData[0]); Assert.AreEqual(01040000, enumerator.DynamicData[1]); }
/// <summary> /// Called when a backward vertex was found. /// </summary> /// <returns></returns> protected virtual bool BackwardVertexFound(int i, uint vertex, LinkedEdgePath <T> backwardVisit) { Dictionary <int, LinkedEdgePath <T> > bucket; if (_buckets.TryGetValue(vertex, out bucket)) { var edgeEnumerator = _graph.GetEdgeEnumerator(); var originalBackwardVisit = backwardVisit; foreach (var pair in bucket) { var best = _weights[pair.Key][i]; var forwardVisit = pair.Value; while (forwardVisit != null) { var forwardCurrent = forwardVisit.Path; if (_weightHandler.IsLargerThan(forwardCurrent.Weight, best)) { forwardVisit = forwardVisit.Next; continue; } backwardVisit = originalBackwardVisit; while (backwardVisit != null) { var backwardCurrent = backwardVisit.Path; var totalCurrentWeight = _weightHandler.Add(forwardCurrent.Weight, backwardCurrent.Weight); if (_weightHandler.IsSmallerThan(totalCurrentWeight, best)) { // potentially a weight improvement. var allowed = true; // check u-turn. var sequence2Forward = backwardCurrent.GetSequence2(edgeEnumerator); var sequence2Current = forwardCurrent.GetSequence2(edgeEnumerator); if (sequence2Current != null && sequence2Current.Length > 0 && sequence2Forward != null && sequence2Forward.Length > 0) { if (sequence2Current[sequence2Current.Length - 1] == sequence2Forward[sequence2Forward.Length - 1]) { allowed = false; } } if (allowed) { best = totalCurrentWeight; } } backwardVisit = backwardVisit.Next; } forwardVisit = forwardVisit.Next; } _weights[pair.Key][i] = best; } } return(false); }
public void TestDoubleContraction() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 2, 100, null); graph.AddEdge(2, 0, 100, null); graph.AddEdge(0, 3, 100, null); graph.AddEdge(3, 0, 100, null); graph.AddEdge(1, 2, 200, null); graph.AddEdge(2, 1, 200, null); graph.AddEdge(1, 3, 200, null); graph.AddEdge(3, 1, 200, null); 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), (i) => Enumerable.Empty <uint[]>()); 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); }
public void TestGetSequence2() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); var e1 = graph.AddEdge(0, 1, 100, null); var e2 = graph.AddEdge(1, 2, 100, null); var e3 = graph.AddEdge(2, 6, 100, null, 4, new uint[] { 3 }, new uint[] { 5 }); var e4 = graph.AddEdge(6, 16, 100, null, 11, new uint[] { 7, 8, 9, 10 }, new uint[] { 12, 13, 14, 15 }); var enumerator = graph.GetEdgeEnumerator(); // build and test getting sequences from paths. var path = new EdgePath <float>(0); var s = path.GetSequence2(enumerator); Assert.IsNotNull(s); Assert.AreEqual(0, s.Length); path = new EdgePath <float>(1, 100, new EdgePath <float>(0)); s = path.GetSequence2(enumerator); Assert.IsNotNull(s); Assert.AreEqual(1, s.Length); Assert.AreEqual(0, s[0]); path = new EdgePath <float>(2, 200, e2 + 1, new EdgePath <float>(1, 100, new EdgePath <float>(0))); s = path.GetSequence2(enumerator); Assert.IsNotNull(s); Assert.AreEqual(2, s.Length); Assert.AreEqual(0, s[0]); Assert.AreEqual(1, s[1]); path = new EdgePath <float>(6, 300, e3 + 1, new EdgePath <float>(2, 200, e2 + 1, new EdgePath <float>(1, 100, new EdgePath <float>(0)))); s = path.GetSequence2(enumerator); Assert.IsNotNull(s); Assert.AreEqual(1, s.Length); Assert.AreEqual(5, s[0]); path = new EdgePath <float>(16, 400, e4 + 1, new EdgePath <float>(6, 300, e3 + 1, new EdgePath <float>(2, 200, e2 + 1, new EdgePath <float>(1, 100, new EdgePath <float>(0))))); s = path.GetSequence2(enumerator); Assert.IsNotNull(s); Assert.AreEqual(4, s.Length); Assert.AreEqual(12, s[0]); Assert.AreEqual(13, s[1]); Assert.AreEqual(14, s[2]); Assert.AreEqual(15, s[3]); }
/// <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, LinkedEdgePath <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(); }
public void TestSerialize() { var graph = new DirectedDynamicGraph(10, 1); // add and compress. graph.AddEdge(0, 1, 1); graph.Compress(); var expectedSize = 1 + 8 + 8 + 8 + 4 + // the header: version byte two longs representing vertex, edge count and the size of the edge array and one int for minimum edge size. graph.VertexCount * 1 * 4 + // the bytes for the vertex-index: 1 uint. graph.EdgeCount * 2 * 4; // the bytes for the edges: one edge 2 uint's. 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 DirectedDynamicGraph(10, 1); // add and compress. graph.AddEdge(0, 1, 10); graph.AddEdge(1, 2, 20); graph.AddEdge(2, 3, 30); graph.AddEdge(3, 4, 40); graph.RemoveEdge(1, 2); graph.Compress(); expectedSize = 1 + 8 + 8 + 8 + 4 + // the header: version bytes, three longs representing vertex and edge count and the size of the edge array and one int for fixed edge size. graph.VertexCount * 4 + // the bytes for the vertex-index: 2 uint's. graph.EdgeCount * 2 * 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); } }
public void TestAddEdge() { var graph = new DirectedDynamicGraph(); graph.AddEdge(1, 2, 0102); Assert.AreEqual(1, graph.EdgeCount); var enumerator = graph.GetEdgeEnumerator(); Assert.IsTrue(enumerator.MoveTo(1)); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(0102, enumerator.Data0); graph = new DirectedDynamicGraph(); graph.AddEdge(1, 2, 0102, 010200); Assert.AreEqual(1, graph.EdgeCount); enumerator = graph.GetEdgeEnumerator(); Assert.IsTrue(enumerator.MoveTo(1)); Assert.IsTrue(enumerator.MoveNext()); Assert.AreEqual(0102, enumerator.Data0); Assert.AreEqual(010200, enumerator.DynamicData[0]); }
public void TestAddMultipleEdges() { // a new graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 10, 100); graph.AddEdge(1, 0, 10, 100); graph.AddEdge(0, 2, 20, 200); graph.AddEdge(2, 0, 20, 200); var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(10, edges.First(x => x.Neighbour == 1).Data0); Assert.AreEqual(100, edges.First(x => x.Neighbour == 1).DynamicData[0]); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).DynamicData[0]); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(10, edges.First(x => x.Neighbour == 0).Data[0]); Assert.AreEqual(100, edges.First(x => x.Neighbour == 0).DynamicData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(20, edges.First(x => x.Neighbour == 0).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 0).DynamicData[0]); // a new graph. graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 10, 100); graph.AddEdge(0, 2, 20, 200); graph.AddEdge(1, 0, 10, 100); graph.AddEdge(2, 0, 20, 200); edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(10, edges.First(x => x.Neighbour == 1).Data0); Assert.AreEqual(100, edges.First(x => x.Neighbour == 1).DynamicData[0]); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 2).DynamicData[0]); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(10, edges.First(x => x.Neighbour == 0).Data[0]); Assert.AreEqual(100, edges.First(x => x.Neighbour == 0).DynamicData[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(20, edges.First(x => x.Neighbour == 0).Data[0]); Assert.AreEqual(200, edges.First(x => x.Neighbour == 0).DynamicData[0]); // a new graph. graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 10); graph.AddEdge(1, 0, 10); graph.AddEdge(0, 2, 20); graph.AddEdge(2, 0, 20); edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(10, edges.First(x => x.Neighbour == 1).Data0); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(10, edges.First(x => x.Neighbour == 0).Data[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(20, edges.First(x => x.Neighbour == 0).Data[0]); // a new graph. graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 10); graph.AddEdge(0, 2, 20); graph.AddEdge(1, 0, 10); graph.AddEdge(2, 0, 20); edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(10, edges.First(x => x.Neighbour == 1).Data0); Assert.AreEqual(20, edges.First(x => x.Neighbour == 2).Data[0]); edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(10, edges.First(x => x.Neighbour == 0).Data[0]); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(20, edges.First(x => x.Neighbour == 0).Data[0]); }
/// <summary> /// Calculates the priority of the given vertex. /// </summary> public float Calculate(BitArray32 contractedFlags, Func <uint, IEnumerable <uint[]> > getRestrictions, uint vertex) { var removed = 0; var added = 0; // get and keep edges. var edges = new List <DynamicEdge>(_graph.GetEdgeEnumerator(vertex)); // check if this vertex has a potential restrictions. var restrictions = getRestrictions(vertex); var hasRestrictions = restrictions != null && restrictions.Any(); // 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]; bool?edge1Direction; var edge1Weight = _weightHandler.GetEdgeWeight(edge1, out edge1Direction); var edge1CanMoveForward = edge1Direction == null || edge1Direction.Value; var edge1CanMoveBackward = edge1Direction == null || !edge1Direction.Value; // figure out what witness paths to calculate. var forwardWitnesses = new EdgePath <T> [j]; var backwardWitnesses = new EdgePath <T> [j]; var targets = new List <uint>(j); var targetWeights = new List <T>(j); for (var k = 0; k < j; k++) { var edge2 = edges[k]; bool?edge2Direction; var edge2Weight = _weightHandler.GetEdgeWeight(edge2, out edge2Direction); var edge2CanMoveForward = edge2Direction == null || edge2Direction.Value; var edge2CanMoveBackward = edge2Direction == null || !edge2Direction.Value; if (!(edge1CanMoveBackward && edge2CanMoveForward)) { forwardWitnesses[k] = new EdgePath <T>(); } if (!(edge1CanMoveForward && edge2CanMoveBackward)) { backwardWitnesses[k] = new EdgePath <T>(); } targets.Add(edge2.Neighbour); if (hasRestrictions) { // weight can potentially be bigger. targetWeights.Add(_weightHandler.Infinite); } else { // weight can max be the sum of the two edges. targetWeights.Add(_weightHandler.Add(edge1Weight, edge2Weight)); } } // calculate all witness paths. _witnessCalculator.Calculate(_graph, getRestrictions, edge1.Neighbour, targets, targetWeights, ref forwardWitnesses, ref backwardWitnesses, Constants.NO_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].HasVertex(vertex) && backwardWitnesses[k].HasVertex(vertex)) { // add bidirectional edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, _weightHandler.GetMetric(targetWeights[k]), null, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, _weightHandler.GetMetric(targetWeights[k]), null, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; } else if (forwardWitnesses[k].HasVertex(vertex)) { // add forward edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, _weightHandler.GetMetric(targetWeights[k]), true, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, _weightHandler.GetMetric(targetWeights[k]), false, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; } else if (backwardWitnesses[k].HasVertex(vertex)) { // add forward edge. _graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, _weightHandler.GetMetric(targetWeights[k]), false, vertex, out addedLocal, out removedLocal); added += addedLocal; removed += removedLocal; _graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, _weightHandler.GetMetric(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)); }
/// <summary> /// Calculates witness paths with just one hop. /// </summary> public void ExistsOneHop(DirectedDynamicGraph graph, uint source, List <uint> targets, List <T> weights, ref EdgePath <T>[] forwardExists, ref EdgePath <T>[] backwardExists) { var targetsToCalculate = new HashSet <uint>(); var maxWeight = _weightHandler.Zero; for (int idx = 0; idx < weights.Count; idx++) { if (forwardExists[idx] == null || backwardExists[idx] == null) { targetsToCalculate.Add(targets[idx]); if (_weightHandler.IsSmallerThan(maxWeight, weights[idx])) { maxWeight = weights[idx]; } } if (forwardExists[idx] == null) { forwardExists[idx] = new EdgePath <T>(); } if (backwardExists[idx] == null) { backwardExists[idx] = new EdgePath <T>(); } } if (targetsToCalculate.Count > 0) { var edgeEnumerator = graph.GetEdgeEnumerator(source); while (edgeEnumerator.MoveNext()) { var neighbour = edgeEnumerator.Neighbour; if (targetsToCalculate.Contains(neighbour)) { // ok, this is a to-edge. var index = targets.IndexOf(neighbour); targetsToCalculate.Remove(neighbour); bool?neighbourDirection; var neighbourWeight = _weightHandler.GetEdgeWeight(edgeEnumerator.Current, out neighbourDirection); var neighbourCanMoveForward = neighbourDirection == null || neighbourDirection.Value; var neighbourCanMoveBackward = neighbourDirection == null || !neighbourDirection.Value; if (neighbourCanMoveForward && _weightHandler.IsSmallerThan(neighbourWeight, weights[index])) { forwardExists[index] = new EdgePath <T>(neighbour, neighbourWeight, edgeEnumerator.IdDirected(), new EdgePath <T>(source)); } if (neighbourCanMoveBackward && _weightHandler.IsSmallerThan(neighbourWeight, weights[index])) { backwardExists[index] = new EdgePath <T>(neighbour, neighbourWeight, edgeEnumerator.IdDirected(), new EdgePath <T>(source));; } if (targetsToCalculate.Count == 0) { break; } } } } }
public void TestRestrictedNetwork2() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 100, null); graph.AddEdge(1, 0, 100, null); graph.AddEdge(1, 2, 100, null); graph.AddEdge(2, 1, 100, null); graph.AddEdge(1, 3, 100, null); graph.AddEdge(3, 1, 100, null); graph.AddEdge(1, 4, 100, null); graph.AddEdge(4, 1, 100, null); graph.AddEdge(2, 3, 100, null); graph.AddEdge(3, 2, 100, null); 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); priorities.Add(4, 4); var hierarchyBuilder = new HierarchyBuilder(graph, new MockPriorityCalculator(priorities), new DykstraWitnessCalculator(int.MaxValue), (i) => { if (i == 0 || i == 1 || i == 4) { return(new uint[][] { new uint[] { 0, 1, 4 } }); } return(null); }); hierarchyBuilder.Run(); // check all edges. ContractedEdgeData edgeData; var edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => { if (x.Neighbour == 4) { edgeData = ContractedEdgeDataSerializer.Deserialize(x.Data[0], Constants.NO_VERTEX); return(edgeData.Direction == true); } return(false); }); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(500, edgeData.Weight); Assert.AreEqual(true, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => { if (x.Neighbour == 4) { edgeData = ContractedEdgeDataSerializer.Deserialize(x.Data[0], Constants.NO_VERTEX); return(edgeData.Direction == false); } return(false); }); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(200, edgeData.Weight); Assert.AreEqual(false, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(200, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(0).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(200, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 0); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(null, edge.GetContracted()); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 2); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(null, edge.GetContracted()); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(null, edge.GetContracted()); edge = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(null, edge.GetContracted()); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(100, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(null, edge.GetContracted()); edge = graph.GetEdgeEnumerator(2).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(200, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); edge = graph.GetEdgeEnumerator(3).FirstOrDefault(x => x.Neighbour == 4); Assert.IsNotNull(edge); edgeData = ContractedEdgeDataSerializer.Deserialize(edge.Data[0], Constants.NO_VERTEX); Assert.AreEqual(200, edgeData.Weight); Assert.AreEqual(null, edgeData.Direction); Assert.AreEqual(1, edge.GetContracted()); }
/// <summary> /// Calculates witness paths. /// </summary> public void Calculate(DirectedDynamicGraph graph, Func <uint, IEnumerable <uint[]> > getRestrictions, uint source, List <uint> targets, List <T> weights, ref EdgePath <T>[] forwardWitness, ref EdgePath <T>[] backwardWitness, uint vertexToSkip) { if (_hopLimit == 1) { this.ExistsOneHop(graph, source, targets, weights, ref forwardWitness, ref backwardWitness); return; } // creates the settled list. var s = new List <uint>(); var backwardSettled = new HashSet <EdgePath <T> >(); var forwardSettled = new HashSet <EdgePath <T> >(); var backwardTargets = new HashSet <uint>(); var forwardTargets = new HashSet <uint>(); T forwardMaxWeight = _weightHandler.Zero, backwardMaxWeight = _weightHandler.Zero; for (int idx = 0; idx < weights.Count; idx++) { if (forwardWitness[idx] == null) { forwardWitness[idx] = new EdgePath <T>(); forwardTargets.Add(targets[idx]); if (_weightHandler.IsSmallerThan(forwardMaxWeight, weights[idx])) { forwardMaxWeight = weights[idx]; } } if (backwardWitness[idx] == null) { backwardWitness[idx] = new EdgePath <T>(); backwardTargets.Add(targets[idx]); if (_weightHandler.IsSmallerThan(backwardMaxWeight, weights[idx])) { backwardMaxWeight = weights[idx]; } } } if (_weightHandler.GetMetric(forwardMaxWeight) == 0 && _weightHandler.GetMetric(backwardMaxWeight) == 0) { // no need to search! return; } // creates the priorty queue. var forwardMinWeight = new Dictionary <EdgePath <T>, T>(); var backwardMinWeight = new Dictionary <EdgePath <T>, T>(); _heap.Clear(); _heap.Push(new SettledEdge(new EdgePath <T>(source), 0, _weightHandler.GetMetric(forwardMaxWeight) > 0, _weightHandler.GetMetric(backwardMaxWeight) > 0), 0); // keep looping until the queue is empty or the target is found! var edgeEnumerator = graph.GetEdgeEnumerator(); while (_heap.Count > 0) { // pop the first customer. var current = _heap.Pop(); if (current.Hops + 1 < _hopLimit) { if (current.Path.Vertex == vertexToSkip) { // this is the vertex being contracted. continue; } var forwardWasSettled = forwardSettled.Contains(current.Path); var backwardWasSettled = backwardSettled.Contains(current.Path); if (forwardWasSettled && backwardWasSettled) { // both are already settled. continue; } if (current.Forward) { // this is a forward settle. forwardSettled.Add(current.Path); forwardMinWeight.Remove(current.Path); if (forwardTargets.Contains(current.Path.Vertex)) { for (var i = 0; i < targets.Count; i++) { if (targets[i] == current.Path.Vertex && _weightHandler.IsSmallerThanOrEqual(current.Path.Weight, weights[i])) { // TODO: check if this is a proper stop condition. if (forwardWitness[i] == null || forwardWitness[i].Vertex == Constants.NO_VERTEX || _weightHandler.IsSmallerThan(current.Path.Weight, forwardWitness[i].Weight)) { forwardWitness[i] = current.Path; forwardTargets.Remove(current.Path.Vertex); } } } } } if (current.Backward) { // this is a backward settle. backwardSettled.Add(current.Path); backwardMinWeight.Remove(current.Path); if (backwardTargets.Contains(current.Path.Vertex)) { for (var i = 0; i < targets.Count; i++) { if (targets[i] == current.Path.Vertex && _weightHandler.IsSmallerThanOrEqual(current.Path.Weight, weights[i])) { // TODO: check if this is a proper stop condition. if (backwardWitness[i] == null || backwardWitness[i].Vertex == Constants.NO_VERTEX || _weightHandler.IsSmallerThan(current.Path.Weight, backwardWitness[i].Weight)) { backwardWitness[i] = current.Path; backwardTargets.Remove(current.Path.Vertex); } } } } } if (forwardTargets.Count == 0 && backwardTargets.Count == 0) { // there is nothing left to check. break; } if (forwardSettled.Count >= _maxSettles && backwardSettled.Count >= _maxSettles) { // do not continue searching. break; } var doForward = current.Forward && forwardTargets.Count > 0 && !forwardWasSettled; var doBackward = current.Backward && backwardTargets.Count > 0 && !backwardWasSettled; if (doForward || doBackward) { // get the neighbours. // check for a restriction and if need build the original sequence. var restrictions = getRestrictions(current.Path.Vertex); var sequence = current.Path.GetSequence2(edgeEnumerator, int.MaxValue, s); sequence = sequence.Append(current.Path.Vertex); // move to the current vertex. edgeEnumerator.MoveTo(current.Path.Vertex); //uint neighbour, data0, data1; while (edgeEnumerator.MoveNext()) { // move next. var neighbour = edgeEnumerator.Neighbour; //edgeEnumerator.GetData(out neighbour, out data0, out data1); bool?neighbourDirection; var neighbourWeight = _weightHandler.GetEdgeWeight(edgeEnumerator, out neighbourDirection); var neighbourCanMoveForward = neighbourDirection == null || neighbourDirection.Value; var neighbourCanMoveBackward = neighbourDirection == null || !neighbourDirection.Value; var totalNeighbourWeight = _weightHandler.Add(current.Path.Weight, neighbourWeight); var neighbourPath = new EdgePath <T>(neighbour, totalNeighbourWeight, edgeEnumerator.IdDirected(), current.Path); var doNeighbourForward = doForward && neighbourCanMoveForward && _weightHandler.IsSmallerThanOrEqual(totalNeighbourWeight, forwardMaxWeight) && !forwardSettled.Contains(neighbourPath); var doNeighbourBackward = doBackward && neighbourCanMoveBackward && _weightHandler.IsSmallerThanOrEqual(totalNeighbourWeight, backwardMaxWeight) && !backwardSettled.Contains(neighbourPath); if (doNeighbourBackward || doNeighbourForward) { T existingWeight; uint[] sequenceAlongNeighbour = null; if ((doNeighbourBackward || doNeighbourForward) && sequence.Length > 0) { if (edgeEnumerator.IsOriginal()) { if (sequence.Length > 1 && sequence[sequence.Length - 2] == neighbour) { // a t-turn! continue; } sequenceAlongNeighbour = sequence.Append(neighbour); } else { var sequence1Length = edgeEnumerator.GetSequence1(ref _sequence1); //var neighbourSequence = edgeEnumerator.GetSequence1(); if (sequence.Length > 1 && sequence[sequence.Length - 2] == _sequence1[0]) { // a t-turn! continue; } sequenceAlongNeighbour = sequence.Append(_sequence1, sequence1Length); } } if (doNeighbourForward) { if (sequence.Length == 0 || restrictions.IsSequenceAllowed(sequenceAlongNeighbour)) { // restrictions ok. if (forwardMinWeight.TryGetValue(neighbourPath, out existingWeight)) { if (_weightHandler.IsSmallerThanOrEqual(existingWeight, totalNeighbourWeight)) { doNeighbourForward = false; } else { forwardMinWeight[neighbourPath] = totalNeighbourWeight; } } else { forwardMinWeight[neighbourPath] = totalNeighbourWeight; } } else { doNeighbourForward = false; } } if (doNeighbourBackward) { if (sequenceAlongNeighbour != null) { sequenceAlongNeighbour.Reverse(); } if (sequence.Length == 0 || restrictions.IsSequenceAllowed(sequenceAlongNeighbour)) { // restrictions ok. if (backwardMinWeight.TryGetValue(neighbourPath, out existingWeight)) { if (_weightHandler.IsSmallerThanOrEqual(existingWeight, totalNeighbourWeight)) { doNeighbourBackward = false; } else { backwardMinWeight[neighbourPath] = totalNeighbourWeight; } } else { backwardMinWeight[neighbourPath] = totalNeighbourWeight; } } else { doNeighbourBackward = false; } } if (doNeighbourBackward || doNeighbourForward) { // add to heap. var newSettle = new SettledEdge(neighbourPath, current.Hops + 1, doNeighbourForward, doNeighbourBackward); _heap.Push(newSettle, _weightHandler.GetMetric(neighbourPath.Weight)); } } } } } } }
public void TestCompress() { var graph = new DirectedDynamicGraph(10, 1); // add and compress. graph.AddEdge(0, 1, 1); graph.Compress(); // verify all edges. var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.First().Data[0]); Assert.AreEqual(1, edges.First().Neighbour); graph = new DirectedDynamicGraph(10, 1); // add and compress. graph.AddEdge(0, 1, 10); graph.AddEdge(1, 2, 20); graph.AddEdge(2, 3, 30); graph.AddEdge(3, 4, 40); 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(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.IsFalse(edges.MoveNext()); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[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(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(1, edges.First().Neighbour); edges = graph.GetEdgeEnumerator(1); Assert.IsFalse(edges.MoveNext()); edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(30, edges.First().Data[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(4, edges.First().Neighbour); }
public void TestPentagonDirected() { // build graph. var graph = new DirectedDynamicGraph(ContractedEdgeDataSerializer.DynamicFixedSize); graph.AddEdge(0, 1, 100, true); graph.AddEdge(1, 0, 100, false); graph.AddEdge(1, 2, 100, true); graph.AddEdge(2, 1, 100, false); graph.AddEdge(2, 3, 100, true); graph.AddEdge(3, 2, 100, false); graph.AddEdge(3, 4, 100, true); graph.AddEdge(4, 3, 100, false); graph.AddEdge(4, 0, 100, true); graph.AddEdge(0, 4, 100, false); 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), (i) => Enumerable.Empty <uint[]>()); 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 s1 = edges41.GetSequence1(); var s2 = edges41.GetSequence2(); Assert.AreEqual(1, s1.Length); Assert.AreEqual(0, s1[0]); Assert.AreEqual(1, s2.Length); Assert.AreEqual(0, s2[0]); 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); s1 = edges31.GetSequence1(); s2 = edges31.GetSequence2(); Assert.AreEqual(1, s1.Length); Assert.AreEqual(4, s1[0]); Assert.AreEqual(1, s2.Length); Assert.AreEqual(0, s2[0]); var edges13 = graph.GetEdgeEnumerator(1).FirstOrDefault(x => x.Neighbour == 3); Assert.IsNull(edges13); }
public void TestAddSmallNetwork1AndContract() { // build graph. var graph = new DirectedDynamicGraph(5, 1); graph.AddEdge(0, 1, 100, null); graph.AddEdge(1, 0, 101, null); graph.AddEdge(1, 2, 102, null); graph.AddEdge(2, 1, 103, null); graph.AddEdge(1, 3, 104, null); graph.AddEdge(3, 1, 105, null); graph.AddEdge(1, 4, 106, null); graph.AddEdge(4, 1, 107, null); graph.AddEdge(2, 3, 108, null); graph.AddEdge(3, 2, 109, null); Assert.AreEqual(5, graph.VertexCount); // verify all edges for 0. var edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Neighbour); Assert.AreEqual(null, edges.First().Direction()); Assert.AreEqual(100, edges.First().Weight()); // verify all edges for 1. edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(4, edges.Count()); var edge = edges.First(e => e.Neighbour == 0); Assert.AreEqual(0, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(101, edge.Weight()); edge = edges.First(e => e.Neighbour == 0); Assert.AreEqual(0, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(101, edge.Weight()); edge = edges.First(e => e.Neighbour == 2); Assert.AreEqual(2, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(102, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(104, edge.Weight()); edge = edges.First(e => e.Neighbour == 4); Assert.AreEqual(4, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(106, edge.Weight()); // verify all edges for 2. edges = graph.GetEdgeEnumerator(2); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(103, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(108, edge.Weight()); // verify all edges for 3. edges = graph.GetEdgeEnumerator(3); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(105, edge.Weight()); edge = edges.First(e => e.Neighbour == 2); Assert.AreEqual(2, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(109, edge.Weight()); // verify all edges for 4. edges = graph.GetEdgeEnumerator(4); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(107, edge.Weight()); // remove 3->2 and 1->2. graph.RemoveEdge(3, 2); graph.RemoveEdge(1, 2); // verify all edges for 0. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Neighbour); Assert.AreEqual(null, edges.First().Direction()); Assert.AreEqual(100, edges.First().Weight()); // verify all edges for 1. edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(3, edges.Count()); edge = edges.First(e => e.Neighbour == 0); Assert.AreEqual(0, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(101, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(104, edge.Weight()); edge = edges.First(e => e.Neighbour == 4); Assert.AreEqual(4, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(106, edge.Weight()); // verify all edges for 2. edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(2, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(103, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(108, edge.Weight()); // verify all edges for 3. edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(105, edge.Weight()); // verify all edges for 4. edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(107, edge.Weight()); // remove 1->0. graph.RemoveEdge(1, 0); // verify all edges for 0. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Neighbour); Assert.AreEqual(null, edges.First().Direction()); Assert.AreEqual(100, edges.First().Weight()); // verify all edges for 1. edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(2, edges.Count()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(104, edge.Weight()); edge = edges.First(e => e.Neighbour == 4); Assert.AreEqual(4, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(106, edge.Weight()); // verify all edges for 2. edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(2, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(103, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(108, edge.Weight()); // verify all edges for 3. edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(105, edge.Weight()); // verify all edges for 4. edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(107, edge.Weight()); // remove 1->4. graph.RemoveEdge(1, 4); // verify all edges for 0. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Neighbour); Assert.AreEqual(null, edges.First().Direction()); Assert.AreEqual(100, edges.First().Weight()); // verify all edges for 1. edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(104, edge.Weight()); // verify all edges for 2. edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(2, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(103, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(108, edge.Weight()); // verify all edges for 3. edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(105, edge.Weight()); // verify all edges for 4. edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(107, edge.Weight()); // remove 1->3. graph.RemoveEdge(1, 3); // verify all edges for 0. edges = graph.GetEdgeEnumerator(0); Assert.AreEqual(1, edges.Count()); Assert.AreEqual(1, edges.First().Neighbour); Assert.AreEqual(null, edges.First().Direction()); Assert.AreEqual(100, edges.First().Weight()); // verify all edges for 1. edges = graph.GetEdgeEnumerator(1); Assert.AreEqual(0, edges.Count()); // verify all edges for 2. edges = graph.GetEdgeEnumerator(2); Assert.AreEqual(2, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(103, edge.Weight()); edge = edges.First(e => e.Neighbour == 3); Assert.AreEqual(3, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(108, edge.Weight()); // verify all edges for 3. edges = graph.GetEdgeEnumerator(3); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(105, edge.Weight()); // verify all edges for 4. edges = graph.GetEdgeEnumerator(4); Assert.AreEqual(1, edges.Count()); edge = edges.First(e => e.Neighbour == 1); Assert.AreEqual(1, edge.Neighbour); Assert.AreEqual(null, edge.Direction()); Assert.AreEqual(107, edge.Weight()); }
/// <summary> /// Expands all edges in the given edge path. /// </summary> public static EdgePath <T> Expand <T>(this EdgePath <T> edgePath, DirectedDynamicGraph graph, WeightHandler <T> weightHandler) where T : struct { return(edgePath.Expand(graph.GetEdgeEnumerator(), weightHandler)); }
private BitArray32 _restrictionFlags; // contains flags for restricted vertices. /// <summary> /// Excutes the actual run. /// </summary> protected override void DoRun() { _queue = new BinaryHeap <uint>((uint)_graph.VertexCount); _contractedFlags = new BitArray32(_graph.VertexCount); _restrictionFlags = new BitArray32(_graph.VertexCount); _missesQueue = new Queue <bool>(); // build restrictions flags. for (uint i = 0; i < _graph.VertexCount; i++) { var restrictions = _getRestrictions(i); if (restrictions != null && restrictions.Any()) { _restrictionFlags[i] = true; } } // 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++; } }