public void TestLiveEdgeDynamicGraphEdge() { IDynamicGraph <LiveEdge> graph = this.CreateGraph(); uint vertex1 = graph.AddVertex(51, 1); uint vertex2 = graph.AddVertex(51, 2); graph.AddArc(vertex1, vertex2, new LiveEdge() { Forward = true, Tags = 0 }, null); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex2, arcs[0].Key); graph.AddArc(vertex2, vertex1, new LiveEdge() { Forward = true, Tags = 0 }, null); arcs = graph.GetArcs(vertex2); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex1, arcs[0].Key); }
public void TestLiveEdgeDynamicGraphEdge10000() { int count = 10000; IDynamicGraph <LiveEdge> graph = this.CreateGraph(); uint vertex1 = graph.AddVertex(51, 1); while (count > 0) { uint vertex2 = graph.AddVertex(51, 1); graph.AddArc(vertex1, vertex2, new LiveEdge() { Tags = 0, Forward = false }, null); KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1); Assert.AreEqual(10000 - count + 1, arcs.Length); graph.AddArc(vertex2, vertex1, new LiveEdge() { Tags = 0, Forward = false }, null); arcs = graph.GetArcs(vertex2); Assert.AreEqual(1, arcs.Length); Assert.AreEqual(0, arcs[0].Value.Tags); Assert.AreEqual(vertex1, arcs[0].Key); count--; } }
/// <summary> /// Adds an edge. /// </summary> /// <param name="forward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="tags"></param> private bool AddRoadEdge(TagsCollection tags, bool forward, uint from, uint to) { float latitude; float longitude; GeoCoordinate fromCoordinate = null; if (_dynamicGraph.GetVertex(from, out latitude, out longitude)) { // fromCoordinate = new GeoCoordinate(latitude, longitude); } GeoCoordinate toCoordinate = null; if (_dynamicGraph.GetVertex(to, out latitude, out longitude)) { // toCoordinate = new GeoCoordinate(latitude, longitude); } if (fromCoordinate != null && toCoordinate != null) { // calculate the edge data. TEdgeData edgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, forward, fromCoordinate, toCoordinate); _dynamicGraph.AddArc(from, to, edgeData, _edgeComparer); } return(false); }
/// <summary> /// Adds all downward edges. /// </summary> /// <param name="graph"></param> public static void AddDownwardEdges(this IDynamicGraph <CHEdgeData> graph) { // add the reverse edges to get a easy depth-first search. for (uint vertexId = 1; vertexId < graph.VertexCount; vertexId++) { List <KeyValuePair <uint, CHEdgeData> > arcs = new List <KeyValuePair <uint, CHEdgeData> >(graph.GetArcs(vertexId)); foreach (KeyValuePair <uint, CHEdgeData> arc in arcs) { if (arc.Value.ToHigher) { // create severse edge. CHEdgeData reverseEdge = new CHEdgeData(); reverseEdge.SetDirection(arc.Value.Backward, arc.Value.Forward, false); reverseEdge.Weight = arc.Value.Weight; graph.AddArc(arc.Key, vertexId, reverseEdge, null); } } } }
/// <summary> /// Adds a new arc. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="data"></param> /// <param name="comparer"></param> public void AddArc(uint from, uint to, TEdgeData data, IDynamicGraphEdgeComparer <TEdgeData> comparer) { _graph.AddArc(from, to, data, comparer); }
/// <summary> /// Contracts the given vertex. /// </summary> /// <param name="vertex"></param> public void Contract(uint vertex) { if (_contracted.Length > vertex && _contracted[vertex]) { throw new Exception("Is already contracted!"); } // keep the neighbours. HashSet <uint> neighbours = new HashSet <uint>(); // get all information from the source. KeyValuePair <uint, CHEdgeData>[] edges = _target.GetArcs(vertex); // report the before contraction event. this.OnBeforeContraction(vertex, edges); // remove the edges from the neighbours to the target. foreach (KeyValuePair <uint, CHEdgeData> edge in edges) { // remove the edge. _target.DeleteArc(edge.Key, vertex); // keep the neighbour. neighbours.Add(edge.Key); } // loop over each combination of edges just once. for (int x = 1; x < edges.Length; x++) { // loop over all elements first. KeyValuePair <uint, CHEdgeData> xEdge = edges[x]; for (int y = 0; y < x; y++) { // loop over all elements. KeyValuePair <uint, CHEdgeData> yEdge = edges[y]; // calculate the total weight. float weight = xEdge.Value.Weight + yEdge.Value.Weight; // add the combinations of these edges. if (((xEdge.Value.Backward && yEdge.Value.Forward) || (yEdge.Value.Backward && xEdge.Value.Forward)) && (xEdge.Key != yEdge.Key)) { // there is a connection from x to y and there is no witness path. bool witnessXToY = _witnessCalculator.Exists(xEdge.Key, yEdge.Key, vertex, weight, 100); bool witnessYToX = _witnessCalculator.Exists(yEdge.Key, xEdge.Key, vertex, weight, 100); // create x-to-y data and edge. CHEdgeData dataXToY = new CHEdgeData(); bool forward = (xEdge.Value.Backward && yEdge.Value.Forward) && !witnessXToY; bool backward = (yEdge.Value.Backward && xEdge.Value.Forward) && !witnessYToX; dataXToY.SetDirection(forward, backward, true); dataXToY.Weight = weight; dataXToY.ContractedVertexId = vertex; if ((dataXToY.Forward || dataXToY.Backward) || !_target.HasNeighbour(xEdge.Key, yEdge.Key)) { // add the edge if there is usefull info or if there needs to be a neighbour relationship. _target.AddArc(xEdge.Key, yEdge.Key, dataXToY, _comparer); } // create y-to-x data and edge. CHEdgeData dataYToX = new CHEdgeData(); forward = (yEdge.Value.Backward && xEdge.Value.Forward) && !witnessYToX; backward = (xEdge.Value.Backward && yEdge.Value.Forward) && !witnessXToY; dataYToX.SetDirection(forward, backward, true); dataYToX.Weight = weight; dataYToX.ContractedVertexId = vertex; if ((dataYToX.Forward || dataYToX.Backward) || !_target.HasNeighbour(yEdge.Key, xEdge.Key)) { // add the edge if there is usefull info or if there needs to be a neighbour relationship. _target.AddArc(yEdge.Key, xEdge.Key, dataYToX, _comparer); } } } } // mark the vertex as contracted. this.MarkContracted(vertex); // notify a contracted neighbour. _calculator.NotifyContracted(vertex); // report the after contraction event. this.OnAfterContraction(vertex, edges); }