public void TestExpandEdgeContracted() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(1, 0, 100, null, Constants.NO_VERTEX); graph.AddEdge(1, 2, 100, null, Constants.NO_VERTEX); graph.AddEdge(0, 2, 100, null, 1); // expand edge. var vertices = new List <uint>(); graph.ExpandEdge(0, 2, vertices, true, true); // check result. Assert.AreEqual(1, vertices.Count); Assert.AreEqual(1, vertices[0]); // expand edge. vertices = new List <uint>(); graph.ExpandEdge(0, 2, vertices, false, true); // check result. Assert.AreEqual(1, vertices.Count); Assert.AreEqual(1, vertices[0]); }
/// <summary> /// Gets the paths. /// </summary> public EdgePath <T> GetPath(int source, int target) { this.CheckHasRunAndHasSucceeded(); var solution = _paths[source][target]; if (solution.Path != null) { return(solution.Path); } if (solution.Path1 == null || solution.Path2 == null) { return(null); } var vertices = new List <uint>(); var fromSource = solution.Path1; var toTarget = solution.Path2; // add vertices from source. vertices.Add(fromSource.Vertex); while (fromSource.From != null) { if (fromSource.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (fromSource.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(fromSource.From.Vertex, fromSource.Vertex, vertices, false, true); } } vertices.Add(fromSource.From.Vertex); fromSource = fromSource.From; } vertices.Reverse(); // and add vertices to target. while (toTarget.From != null) { if (toTarget.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (toTarget.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(toTarget.From.Vertex, toTarget.Vertex, vertices, false, false); } } vertices.Add(toTarget.From.Vertex); toTarget = toTarget.From; } return(_routerDb.BuildEdgePath(_weightHandler, _sources[source], _targets[target], vertices)); }
/// <summary> /// Returns the path. /// </summary> /// <returns></returns> public List <uint> GetPath() { this.CheckHasRunAndHasSucceeded(); EdgePath <T> fromSource; EdgePath <T> toTarget; if (_forwardVisits.TryGetValue(_best.Item1, out fromSource) && _backwardVisits.TryGetValue(_best.Item1, out toTarget)) { var vertices = new List <uint>(); // add vertices from source. vertices.Add(fromSource.Vertex); while (fromSource.From != null) { if (fromSource.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (fromSource.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(fromSource.From.Vertex, fromSource.Vertex, vertices, false, true); } } vertices.Add(fromSource.From.Vertex); fromSource = fromSource.From; } vertices.Reverse(); // and add vertices to target. while (toTarget.From != null) { if (toTarget.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (toTarget.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(toTarget.From.Vertex, toTarget.Vertex, vertices, false, false); } } vertices.Add(toTarget.From.Vertex); toTarget = toTarget.From; } return(vertices); } throw new InvalidOperationException("No path could be found to/from source/target."); }
public static void ExpandEdge(this DirectedMetaGraph graph, uint vertex1, uint vertex2, List <uint> vertices, bool inverted, bool forward) { MetaEdge shortestEdge = graph.GetShortestEdge(vertex1, vertex2, (Func <uint[], float?>)(data => { float weight; bool?direction; ContractedEdgeDataSerializer.Deserialize(data[0], out weight, out direction); if (!direction.HasValue || direction.Value == forward) { return(new float?(weight)); } return(new float?()); })); if (shortestEdge == null) { throw new Exception(string.Format("No edge found from {0} to {1}.", new object[2] { (object)vertex1, (object)vertex2 })); } uint contractedId = shortestEdge.GetContractedId(); if ((int)contractedId == -2) { return; } if (inverted) { graph.ExpandEdge(contractedId, vertex1, vertices, false, !forward); vertices.Add(contractedId); graph.ExpandEdge(contractedId, vertex2, vertices, true, forward); } else { graph.ExpandEdge(contractedId, vertex2, vertices, false, forward); vertices.Add(contractedId); graph.ExpandEdge(contractedId, vertex1, vertices, true, !forward); } }
/// <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) { // check if expansion is needed. var edge = graph.GetShortestEdge(vertex1, vertex2, data => { float weight; bool?direction; ContractedEdgeDataSerializer.Deserialize(data[0], out weight, out direction); if (direction == null || direction.Value == forward) { return(weight); } return(null); }); if (edge == null) { // no edge found! throw new Exception(string.Format("No edge found from {0} to {1}.", vertex1, vertex2)); } var edgeContractedId = edge.GetContractedId(); if (edgeContractedId != Constants.NO_VERTEX) { // further expansion needed. if (inverted) { graph.ExpandEdge(edgeContractedId, vertex1, vertices, false, !forward); vertices.Add(edgeContractedId); graph.ExpandEdge(edgeContractedId, vertex2, vertices, true, forward); } else { graph.ExpandEdge(edgeContractedId, vertex2, vertices, false, forward); vertices.Add(edgeContractedId); graph.ExpandEdge(edgeContractedId, vertex1, vertices, true, !forward); } } }
public void TestExpandNonExistingEdge() { // build graph. var graph = new DirectedMetaGraph(ContractedEdgeDataSerializer.Size, ContractedEdgeDataSerializer.MetaSize); graph.AddEdge(0, 1, 100, null, Constants.NO_VERTEX); // expand edge. Assert.Catch <System.Exception>(() => { graph.ExpandEdge(1, 2, new List <uint>(), true, true); }); }
/// <summary> /// Gets the weights. /// </summary> public EdgePath <T> GetPath(int source, int target) { this.CheckHasRunAndHasSucceeded(); var solution = _solutions[source][target]; if (solution.Path == null) { if (solution.Path1 == null || solution.Path2 == null) { return(null); } if (solution.Path != null) { return(solution.Path); } var fromSource = solution.Path1; var toTarget = solution.Path2; var vertices = new List <uint>(); // add vertices from source. vertices.Add(fromSource.Vertex); while (fromSource.From != null) { if (fromSource.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (fromSource.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(fromSource.From.Vertex, fromSource.Vertex, vertices, false, true); } } vertices.Add(fromSource.From.Vertex); fromSource = fromSource.From; } vertices.Reverse(); // and add vertices to target. while (toTarget.From != null) { if (toTarget.From.Vertex != Constants.NO_VERTEX) { // this should be the end of the path. if (toTarget.Edge == Constants.NO_EDGE) { // only expand when there is no edge id. _graph.ExpandEdge(toTarget.From.Vertex, toTarget.Vertex, vertices, false, false); } } vertices.Add(toTarget.From.Vertex); toTarget = toTarget.From; } var path = new EdgePath <T>(vertices[0]); for (var i = 1; i < vertices.Count; i++) { path = new EdgePath <T>(vertices[i], default(T), path); } solution.Path = path; } return(solution.Path); }