Esempio n. 1
0
        public void TestLiveEdgeDynamicGraphEdge10000()
        {
            int count = 10000;
            IDynamicGraph <LiveEdge> graph = this.CreateGraph();
            uint vertex1 = graph.AddVertex(51, 1);

            while (count > 0)
            {
                uint vertex2 = graph.AddVertex(51, 1);

                graph.AddArc(vertex1, vertex2, new LiveEdge()
                {
                    Tags    = 0,
                    Forward = false
                }, null);

                KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1);
                Assert.AreEqual(10000 - count + 1, arcs.Length);

                graph.AddArc(vertex2, vertex1, new LiveEdge()
                {
                    Tags    = 0,
                    Forward = false
                }, null);

                arcs = graph.GetArcs(vertex2);
                Assert.AreEqual(1, arcs.Length);
                Assert.AreEqual(0, arcs[0].Value.Tags);
                Assert.AreEqual(vertex1, arcs[0].Key);

                count--;
            }
        }
Esempio n. 2
0
        public void TestLiveEdgeDynamicGraphEdge()
        {
            IDynamicGraph <LiveEdge> graph = this.CreateGraph();
            uint vertex1 = graph.AddVertex(51, 1);
            uint vertex2 = graph.AddVertex(51, 2);

            graph.AddArc(vertex1, vertex2, new LiveEdge()
            {
                Forward = true,
                Tags    = 0
            }, null);

            KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex1);
            Assert.AreEqual(1, arcs.Length);
            Assert.AreEqual(0, arcs[0].Value.Tags);
            Assert.AreEqual(vertex2, arcs[0].Key);

            graph.AddArc(vertex2, vertex1, new LiveEdge()
            {
                Forward = true,
                Tags    = 0
            }, null);

            arcs = graph.GetArcs(vertex2);
            Assert.AreEqual(1, arcs.Length);
            Assert.AreEqual(0, arcs[0].Value.Tags);
            Assert.AreEqual(vertex1, arcs[0].Key);
        }
Esempio n. 3
0
        /// <summary>
        /// Calculates the edge-difference if u would be contracted.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            // get the neighbours.
            KeyValuePair <uint, CHEdgeData>[] neighbours = _data.GetArcs(vertex);

            // simulate the construction of new edges.
            int new_edges = 0;
            int removed   = neighbours.Length;

            // loop over all neighbours and check for witnesses.
            foreach (KeyValuePair <uint, CHEdgeData> from in neighbours)
            {         // loop over all incoming neighbours
                foreach (KeyValuePair <uint, CHEdgeData> to in neighbours)
                {     // loop over all outgoing neighbours
                    if (to.Key != from.Key)
                    { // the neighbours point to different vertices.
                        // a new edge is needed.
                        if (!_witness_calculator.Exists(from.Key, to.Key, vertex,
                                                        (float)from.Value.Weight + (float)to.Value.Weight, int.MaxValue))
                        { // no witness exists.
                            new_edges++;
                        }
                    }
                }
            }
            return(new_edges - removed);
        }
Esempio n. 4
0
        /// <summary>
        /// Calculates the ordering.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            KeyValuePair <uint, CHEdgeData>[] neighbours = _data.GetArcs(vertex);

            // check the proper conditions.
            if (neighbours.Length == 2)
            {
                return(-1);
            }
            return(float.MaxValue);
        }
Esempio n. 5
0
        /// <summary>
        /// Calculates the ordering.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            KeyValuePair <uint, CHEdgeData>[] neighbours = _data.GetArcs(vertex);

            // remove all informative edges.
            neighbours = neighbours.RemoveInformativeEdges();

            // check the proper conditions.
            if (neighbours.Length == 2)
            {
                return(-1);
            }
            return(float.MaxValue);
        }
        /// <summary>
        /// Calculates the edge-difference if u would be contracted.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            short contracted = 0;

            _contraction_count.TryGetValue(vertex, out contracted);

            // get the neighbours.
            KeyValuePair <uint, CHEdgeData>[] neighbours = _data.GetArcs(vertex);

            // simulate the construction of new edges.
            int new_edges = 0;
            int removed   = neighbours.Length;

            // loop over all neighbours and check for witnesses.
            foreach (KeyValuePair <uint, CHEdgeData> from in neighbours)
            {         // loop over all incoming neighbours
                foreach (KeyValuePair <uint, CHEdgeData> to in neighbours)
                {     // loop over all outgoing neighbours
                    if (to.Key != from.Key)
                    { // the neighbours point to different vertices.
                        // a new edge is needed.
                        if (!_witness_calculator.Exists(from.Key, to.Key, vertex,
                                                        (float)from.Value.Weight + (float)to.Value.Weight, 50))
                        { // no witness exists.
                            new_edges++;
                        }
                    }
                }
            }

            // get the depth.
            long depth = 0;

            _depth.TryGetValue(vertex, out depth);
            return((3 * (new_edges - removed)) + (2 * contracted));// +depth;
            //return (new_edges - removed) + depth;
        }
Esempio n. 7
0
        public void TestLiveEdgeDynamicGraphVertex()
        {
            IDynamicGraph <LiveEdge> graph = this.CreateGraph();
            uint vertex = graph.AddVertex(51, 4);

            float latitude, longitude;

            graph.GetVertex(vertex, out latitude, out longitude);

            Assert.AreEqual(51, latitude);
            Assert.AreEqual(4, longitude);

            KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex);
            Assert.AreEqual(0, arcs.Length);
        }
Esempio n. 8
0
        /// <summary>
        /// Moves to the next item.
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (_current == null)
            {
                _current = this.FindHighest();
                _index.Add(_current.Vertex);
                _currentCount = 1;
                return(_current != null);
            }

            // search for the next arc.
            KeyValuePair <uint, CHEdgeData>[] edges = _graph.GetArcs(_current.Vertex);
            int arcIdx = _current.ArcIdx;

            arcIdx++;
            while (arcIdx < edges.Length)
            { // check if it is 'lower'.
                if (!edges[arcIdx].Value.ToHigher &&
                    !_index.Contains(edges[arcIdx].Key))
                {                             // yes the arc is 'lower' take it!
                    _current.ArcIdx = arcIdx; // move the arcIdx.

                    Position newPosition = new Position();
                    newPosition.Parent = _current;
                    newPosition.ArcIdx = -1;
                    newPosition.Vertex = edges[arcIdx].Key;
                    newPosition.Depth  = _current.Depth + 1;
                    _current           = newPosition;

                    _index.Add(_current.Vertex);
                    _currentCount++;
                    return(true);
                }
                arcIdx++; // move to the next arc.
            }

            // move to parent.
            if (_current.Parent != null)
            { // set parent as current and move next.
                _current = _current.Parent;
                return(this.MoveNext());
            }

            // also enumerate all the other 'islands' of vertices unconnected to the current vertices.
            return(this.MoveToNextIsland());
        }
Esempio n. 9
0
        /// <summary>
        /// Returns the arcs that point to lower vertices.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="vertexId"></param>
        /// <returns></returns>
        public static KeyValuePair <uint, CHEdgeData>[] GetArcsLower(this IDynamicGraph <CHEdgeData> graph,
                                                                     uint vertexId)
        {
            KeyValuePair <uint, CHEdgeData>[] arcs       = graph.GetArcs(vertexId);
            KeyValuePair <uint, CHEdgeData>[] higherArcs = new KeyValuePair <uint, CHEdgeData> [arcs.Length];
            int higherIdx = 0;

            for (int idx = 0; idx < arcs.Length; idx++)
            {
                if (!arcs[idx].Value.ToHigher)
                {
                    higherArcs[higherIdx] = arcs[idx];
                    higherIdx++;
                }
            }
            Array.Resize(ref higherArcs, higherIdx);
            return(higherArcs);
        }
Esempio n. 10
0
        /// <summary>
        /// Adds all downward edges.
        /// </summary>
        /// <param name="graph"></param>
        public static void AddDownwardEdges(this IDynamicGraph <CHEdgeData> graph)
        { // add the reverse edges to get a easy depth-first search.
            for (uint vertexId = 1; vertexId < graph.VertexCount; vertexId++)
            {
                List <KeyValuePair <uint, CHEdgeData> > arcs =
                    new List <KeyValuePair <uint, CHEdgeData> >(graph.GetArcs(vertexId));
                foreach (KeyValuePair <uint, CHEdgeData> arc in arcs)
                {
                    if (arc.Value.ToHigher)
                    {
                        // create severse edge.
                        CHEdgeData reverseEdge = new CHEdgeData();
                        reverseEdge.SetDirection(arc.Value.Backward, arc.Value.Forward, false);
                        reverseEdge.Weight = arc.Value.Weight;

                        graph.AddArc(arc.Key, vertexId, reverseEdge, null);
                    }
                }
            }
        }
Esempio n. 11
0
        public void TestLiveEdgeDynamicGraphVertex10000()
        {
            IDynamicGraph <LiveEdge> graph = this.CreateGraph();
            int count = 10000;

            while (count > 0)
            {
                uint vertex = graph.AddVertex(51, 4);

                float latitude, longitude;
                graph.GetVertex(vertex, out latitude, out longitude);

                Assert.AreEqual(51, latitude);
                Assert.AreEqual(4, longitude);

                KeyValuePair <uint, LiveEdge>[] arcs = graph.GetArcs(vertex);
                Assert.AreEqual(0, arcs.Length);

                count--;
            }

            Assert.AreEqual((uint)10000, graph.VertexCount);
        }
Esempio n. 12
0
 /// <summary>
 /// Returns all arcs starting at a given vertex.
 /// </summary>
 /// <param name="vertexId"></param>
 /// <returns></returns>
 public KeyValuePair <uint, TEdgeData>[] GetArcs(uint vertexId)
 {
     return(_graph.GetArcs(vertexId));
 }
        /// <summary>
        /// Does the v2 serialization.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        /// <returns></returns>
        protected override void DoSerialize(LimitedStream stream,
                                            DynamicGraphRouterDataSource <CHEdgeData> graph)
        {
            // sort the graph.
            IDynamicGraph <CHEdgeData> sortedGraph = CHEdgeDataDataSourceSerializer.SortGraph(graph);

            // create the regions.
            SortedDictionary <ulong, List <uint> > regions = new SortedDictionary <ulong, List <uint> >();

            for (uint newVertexId = 1; newVertexId < sortedGraph.VertexCount + 1; newVertexId++)
            {
                // add to the CHRegions.
                float latitude, longitude;
                sortedGraph.GetVertex(newVertexId, out latitude, out longitude);
                Tile tile = Tile.CreateAroundLocation(new GeoCoordinate(
                                                          latitude, longitude), RegionZoom);
                List <uint> regionVertices;
                if (!regions.TryGetValue(tile.Id, out regionVertices))
                {
                    regionVertices = new List <uint>();
                    regions.Add(tile.Id, regionVertices);
                }
                regionVertices.Add(newVertexId);
            }

            // serialize the sorted graph.
            // [START_OF_BLOCKS][[SIZE_OF_REGION_INDEX][REGION_INDEX][REGIONS]][[SIZE_OF_BLOCK_INDEX][BLOCK_INDEX][BLOCKS]]
            // STRART_OF_BLOCKS:        4bytes

            // SIZE_OF_REGION_INDEX:    4bytes
            // REGION_INDEX:            see SIZE_OF_REGION_INDEX
            // REGIONS:                 see START_OF_BLOCKS - 4bytes

            // SIZE_OF_BLOCK_INDEX:     4bytes
            // BLOCK_INDEX:             see SIZE_OF_BLOCK_INDEX.
            // BLOCKS:                  from START_OF_BLOCKS + 4bytes + SIZE_OF_BLOCKS_INDEX until END.

            // serialize regions and build their index.
            CHVertexRegionIndex chRegionIndex = new CHVertexRegionIndex();

            chRegionIndex.LocationIndex = new int[regions.Count];
            chRegionIndex.RegionIds     = new ulong[regions.Count];
            var memoryStream = new MemoryStream();
            int regionIdx    = 0;

            foreach (KeyValuePair <ulong, List <uint> > region in regions)
            {
                // serialize.
                CHVertexRegion chRegion = new CHVertexRegion();
                chRegion.Vertices = region.Value.ToArray();
                _runtimeTypeModel.Serialize(memoryStream, chRegion);

                // set index.
                chRegionIndex.LocationIndex[regionIdx] = (int)memoryStream.Position;
                chRegionIndex.RegionIds[regionIdx]     = region.Key;
                regionIdx++;
            }
            stream.Seek(8, SeekOrigin.Begin);                   // move to beginning of [REGION_INDEX]
            _runtimeTypeModel.Serialize(stream, chRegionIndex); // write region index.
            int sizeRegionIndex = (int)(stream.Position - 8);   // now at beginning of [REGIONS]

            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.WriteTo(stream);                               // write regions.
            memoryStream.Dispose();
            int startOfBlocks = (int)stream.Position;                   // now at beginning of [SIZE_OF_BLOCK_INDEX]

            stream.Seek(0, SeekOrigin.Begin);                           // move to beginning
            stream.Write(BitConverter.GetBytes(startOfBlocks), 0, 4);   // write start position of blocks. Now at [SIZE_OF_REGION_INDEX]
            stream.Write(BitConverter.GetBytes(sizeRegionIndex), 0, 4); // write size of blocks index.

            // serialize the blocks and build their index.
            memoryStream = new MemoryStream();
            List <int> blockLocations = new List <int>();
            uint       vertexId       = 1;

            while (vertexId < sortedGraph.VertexCount)
            {
                uint            blockId       = vertexId;
                List <CHArc>    blockArcs     = new List <CHArc>();
                List <CHVertex> blockVertices = new List <CHVertex>();
                while (vertexId < blockId + BlockVertexSize &&
                       vertexId < sortedGraph.VertexCount + 1)
                { // create this block.
                    CHVertex chVertex = new CHVertex();
                    float    latitude, longitude;
                    sortedGraph.GetVertex(vertexId, out latitude, out longitude);
                    chVertex.Latitude  = latitude;
                    chVertex.Longitude = longitude;
                    chVertex.ArcIndex  = (ushort)(blockArcs.Count);
                    foreach (KeyValuePair <uint, CHEdgeData> sortedArc in sortedGraph.GetArcs(vertexId))
                    {
                        CHArc chArc = new CHArc();
                        chArc.TargetId   = sortedArc.Key;
                        chArc.ShortcutId = sortedArc.Value.ContractedVertexId;
                        chArc.Weight     = sortedArc.Value.Weight;
                        chArc.Direction  = sortedArc.Value.Direction;
                        blockArcs.Add(chArc);
                    }
                    chVertex.ArcCount = (ushort)(blockArcs.Count - chVertex.ArcIndex);
                    blockVertices.Add(chVertex);

                    vertexId++; // move to the next vertex.
                }

                // create block.
                CHBlock block = new CHBlock();
                block.Arcs     = blockArcs.ToArray();
                block.Vertices = blockVertices.ToArray(); // TODO: get rid of the list and create an array to begin with.

                // write blocks.
                _runtimeTypeModel.Serialize(memoryStream, block);
                blockLocations.Add((int)memoryStream.Position);
            }
            CHBlockIndex blockIndex = new CHBlockIndex();

            blockIndex.LocationIndex = blockLocations.ToArray();

            stream.Seek(startOfBlocks + 4, SeekOrigin.Begin);                  // move to beginning of [BLOCK_INDEX]
            _runtimeTypeModel.Serialize(stream, blockIndex);                   // write region index.
            int sizeBlockIndex = (int)(stream.Position - (startOfBlocks + 4)); // now at beginning of [BLOCKS]

            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.WriteTo(stream);                              // write blocks.
            memoryStream.Dispose();
            stream.Seek(startOfBlocks, SeekOrigin.Begin);              // move to [SIZE_OF_BLOCK_INDEX]
            stream.Write(BitConverter.GetBytes(sizeBlockIndex), 0, 4); // write start position of blocks. Now at [SIZE_OF_REGION_INDEX]
            stream.Flush();
        }
Esempio n. 14
0
        /// <summary>
        /// Returns a topologically sorted version of the given graph.
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        public IDynamicGraph <CHEdgeData> SortGraph(IDynamicGraph <CHEdgeData> graph)
        {
            // also add all downward edges.
            graph.AddDownwardEdges();

            // sort the topologically ordered vertices into bins representing a certain height range.
            List <uint>[] heightBins = new List <uint> [1000];
            foreach (var vertexDepth in new CHDepthFirstEnumerator(graph))
            { // enumerates all vertixes depth-first.
                int binIdx = (int)(vertexDepth.Depth / _heightBinSize);
                if (heightBins.Length < binIdx)
                { // resize bin array if needed.
                    Array.Resize(ref heightBins, System.Math.Max(heightBins.Length + 1000, binIdx + 1));
                }

                // add to the current bin.
                List <uint> bin = heightBins[binIdx];
                if (bin == null)
                { // create new bin.
                    bin = new List <uint>();
                    heightBins[binIdx] = bin;
                }
                bin.Add(vertexDepth.VertexId);
            }

            // temp test.
            MemoryDynamicGraph <CHEdgeData> sortedGraph   = new MemoryDynamicGraph <CHEdgeData>();
            Dictionary <uint, uint>         currentBinIds = new Dictionary <uint, uint>();
            uint newVertexId;

            for (int idx = 0; idx < heightBins.Length; idx++)
            {
                List <uint> bin = heightBins[idx];
                if (bin != null)
                { // translate ids.
                    // fill current bin ids and add vertices to the new graph.
                    foreach (uint binVertexId in bin)
                    {
                        float latitude, longitude;
                        graph.GetVertex(binVertexId, out latitude, out longitude);
                        newVertexId = sortedGraph.AddVertex(latitude, longitude);

                        currentBinIds.Add(binVertexId, newVertexId); // add to the current bin index.
                    }
                }
            }

            // rebuild the CH graph based on the new ordering and build the CHRegions.
            newVertexId = 0;
            for (int idx = 0; idx < heightBins.Length; idx++)
            {
                List <uint> bin = heightBins[idx];
                if (bin != null)
                { // translate ids.
                    foreach (uint binVertexId in bin)
                    {
                        currentBinIds.TryGetValue(binVertexId, out newVertexId);

                        // get the higher arcs and convert their ids.
                        //KeyValuePair<uint, CHEdgeData>[] arcs = graph.GetArcsHigher(binVertexId);
                        KeyValuePair <uint, CHEdgeData>[] arcs = graph.GetArcs(binVertexId);
                        foreach (KeyValuePair <uint, CHEdgeData> arc in arcs)
                        {
                            if (arc.Value.IsInformative || arc.Value.ToHigher)
                            {
                                // get target vertex.
                                uint nextVertexArcId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Key, currentBinIds, heightBins);
                                // convert edge.
                                CHEdgeData newEdge = new CHEdgeData();
                                newEdge.Direction = arc.Value.Direction;
                                if (arc.Value.HasContractedVertex)
                                { // contracted info.
                                    newEdge.ContractedVertexId = CHEdgeDataDataSourceSerializer.SearchVertex(arc.Value.ContractedVertexId, currentBinIds, heightBins);
                                }
                                else
                                { // no contracted info.
                                    newEdge.ContractedVertexId = 0;
                                }
                                newEdge.Tags   = arc.Value.Tags;
                                newEdge.Weight = arc.Value.Weight;
                                sortedGraph.AddArc(newVertexId, nextVertexArcId, newEdge, null);
                            }
                        }
                    }
                }
            }
            return(sortedGraph);
        }
Esempio n. 15
0
        /// <summary>
        /// Contracts the given vertex.
        /// </summary>
        /// <param name="vertex"></param>
        public void Contract(uint vertex)
        {
            if (_contracted.Length > vertex && _contracted[vertex])
            {
                throw new Exception("Is already contracted!");
            }

            // keep the neighbours.
            HashSet <uint> neighbours = new HashSet <uint>();

            // get all information from the source.
            KeyValuePair <uint, CHEdgeData>[] edges = _target.GetArcs(vertex);

            // report the before contraction event.
            this.OnBeforeContraction(vertex, edges);

            // remove the edges from the neighbours to the target.
            foreach (KeyValuePair <uint, CHEdgeData> edge in edges)
            { // remove the edge.
                _target.DeleteArc(edge.Key, vertex);

                // keep the neighbour.
                neighbours.Add(edge.Key);
            }

            // loop over each combination of edges just once.
            for (int x = 1; x < edges.Length; x++)
            { // loop over all elements first.
                KeyValuePair <uint, CHEdgeData> xEdge = edges[x];

                for (int y = 0; y < x; y++)
                { // loop over all elements.
                    KeyValuePair <uint, CHEdgeData> yEdge = edges[y];

                    // calculate the total weight.
                    float weight = xEdge.Value.Weight + yEdge.Value.Weight;

                    // add the combinations of these edges.
                    if (((xEdge.Value.Backward && yEdge.Value.Forward) ||
                         (yEdge.Value.Backward && xEdge.Value.Forward)) &&
                        (xEdge.Key != yEdge.Key))
                    { // there is a connection from x to y and there is no witness path.
                        bool witnessXToY = _witnessCalculator.Exists(xEdge.Key, yEdge.Key, vertex, weight, 100);
                        bool witnessYToX = _witnessCalculator.Exists(yEdge.Key, xEdge.Key, vertex, weight, 100);

                        // create x-to-y data and edge.
                        CHEdgeData dataXToY = new CHEdgeData();
                        bool       forward  = (xEdge.Value.Backward && yEdge.Value.Forward) &&
                                              !witnessXToY;
                        bool backward = (yEdge.Value.Backward && xEdge.Value.Forward) &&
                                        !witnessYToX;
                        dataXToY.SetDirection(forward, backward, true);
                        dataXToY.Weight             = weight;
                        dataXToY.ContractedVertexId = vertex;
                        if ((dataXToY.Forward || dataXToY.Backward) ||
                            !_target.HasNeighbour(xEdge.Key, yEdge.Key))
                        { // add the edge if there is usefull info or if there needs to be a neighbour relationship.
                            _target.AddArc(xEdge.Key, yEdge.Key, dataXToY, _comparer);
                        }

                        // create y-to-x data and edge.
                        CHEdgeData dataYToX = new CHEdgeData();
                        forward = (yEdge.Value.Backward && xEdge.Value.Forward) &&
                                  !witnessYToX;
                        backward = (xEdge.Value.Backward && yEdge.Value.Forward) &&
                                   !witnessXToY;
                        dataYToX.SetDirection(forward, backward, true);
                        dataYToX.Weight             = weight;
                        dataYToX.ContractedVertexId = vertex;
                        if ((dataYToX.Forward || dataYToX.Backward) ||
                            !_target.HasNeighbour(yEdge.Key, xEdge.Key))
                        { // add the edge if there is usefull info or if there needs to be a neighbour relationship.
                            _target.AddArc(yEdge.Key, xEdge.Key, dataYToX, _comparer);
                        }
                    }
                }
            }

            // mark the vertex as contracted.
            this.MarkContracted(vertex);

            // notify a contracted neighbour.
            _calculator.NotifyContracted(vertex);

            // report the after contraction event.
            this.OnAfterContraction(vertex, edges);
        }