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); }
protected override void DoRun() { bool?nullable = new bool?(); Dictionary <ushort, Factor> dictionary = new Dictionary <ushort, Factor>(); Graph.EdgeEnumerator edgeEnumerator = this._source.GetEdgeEnumerator(); for (uint vertex = 0; vertex < this._source.VertexCount; ++vertex) { edgeEnumerator.MoveTo(vertex); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { float distance; ushort profile; EdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out distance, out profile); Factor factor = Factor.NoFactor; if (!dictionary.TryGetValue(profile, out factor)) { factor = this._getFactor(profile); dictionary[profile] = factor; } if ((double)factor.Value != 0.0) { bool?direction = new bool?(); if ((int)factor.Direction == 1) { direction = new bool?(true); if (edgeEnumerator.DataInverted) { direction = new bool?(false); } } else if ((int)factor.Direction == 2) { direction = new bool?(false); if (edgeEnumerator.DataInverted) { direction = new bool?(true); } } uint data = ContractedEdgeDataSerializer.Serialize(distance * factor.Value, direction); int num = (int)this._target.AddEdge(edgeEnumerator.From, edgeEnumerator.To, data, 4294967294U); } } } this.HasSucceeded = true; }
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 static void AddEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId) { int num = (int)graph.AddEdge(vertex1, vertex2, ContractedEdgeDataSerializer.Serialize(weight, direction), contractedId); }
/// <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); } } } }
/// <summary> /// Add edge. /// </summary> /// <returns></returns> public static void AddEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, float weight, bool?direction, uint contractedId, float distance, float time) { graph.AddEdge(vertex1, vertex2, new uint[] { ContractedEdgeDataSerializer.Serialize( weight, direction) }, ContractedEdgeDataSerializer.SerializeMetaAugmented(contractedId, distance, time)); }