예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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));
                        }
                    }
                }
            }
        }
예제 #6
0
        /// <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));
                        }
                    }
                }
            }
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
            }
        }
예제 #15
0
        /// <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();
        }
예제 #16
0
파일: Dykstra.cs 프로젝트: amseet/Orion
        /// <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();
        }
예제 #17
0
        /// <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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #18
0
        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));
        }
예제 #20
0
        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);
        }
예제 #21
0
        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());
        }
예제 #22
0
        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);
        }
예제 #23
0
        /// <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++;
                    }
                }
            }
        }
예제 #24
0
        /// <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);
                    }
                }
            }
        }
예제 #25
0
        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++;
            }
        }
예제 #26
0
        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);
        }
예제 #27
0
        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);
                }
            }
        }
예제 #30
0
        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);
        }