Beispiel #1
0
 /// <summary>
 /// Creates a new edge keeping the current state of the given enumerator.
 /// </summary>
 internal MetaEdge(DirectedMetaGraph.EdgeEnumerator enumerator)
 {
     this.Neighbour = enumerator.Neighbour;
     this.Data      = enumerator.Data;
     this.MetaData  = enumerator.MetaData;
     this.Id        = enumerator.Id;
 }
        /// <summary>
        /// Expands a the shortest edge between the two given vertices.
        /// </summary>
        public static void ExpandEdge(this DirectedMetaGraph.EdgeEnumerator edgeEnumerator, uint vertex1, uint vertex2, List <uint> vertices, bool inverted,
                                      bool forward)
        {
            // check if expansion is needed.
            var edgeContractedId = edgeEnumerator.GetShortestEdgeContractedId(vertex1, vertex2, forward);

            if (edgeContractedId == null)
            { // no edge found!
                throw new Exception(string.Format("No edge found from {0} to {1}.", vertex1, vertex2));
            }
            if (edgeContractedId != Constants.NO_VERTEX)
            { // further expansion needed.
                if (inverted)
                {
                    edgeEnumerator.ExpandEdge(edgeContractedId.Value, vertex1, vertices, false, !forward);
                    vertices.Add(edgeContractedId.Value);
                    edgeEnumerator.ExpandEdge(edgeContractedId.Value, vertex2, vertices, true, forward);
                }
                else
                {
                    edgeEnumerator.ExpandEdge(edgeContractedId.Value, vertex2, vertices, false, forward);
                    vertices.Add(edgeContractedId.Value);
                    edgeEnumerator.ExpandEdge(edgeContractedId.Value, vertex1, vertices, true, !forward);
                }
            }
        }
        /// <summary>
        /// Gets the contracted id for the shortest edge between two vertices.
        /// </summary>
        /// <returns></returns>
        public static uint?GetShortestEdgeContractedId(this DirectedMetaGraph.EdgeEnumerator edgeEnumerator, uint vertex1, uint vertex2, bool forward)
        {
            var minWeight = float.MaxValue;

            edgeEnumerator.MoveTo(vertex1);
            uint?contractedId = null;

            while (edgeEnumerator.MoveNext())
            {
                if (edgeEnumerator.Neighbour == vertex2)
                { // the correct neighbour, get the weight.
                    float weight;
                    bool? direction;
                    ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0, out weight, out direction);
                    if (direction == null || direction.Value == forward)
                    {
                        if (weight < minWeight)
                        { // weight is better.
                            contractedId = edgeEnumerator.GetContractedId();
                            minWeight    = weight;
                        }
                    }
                }
            }
            return(contractedId);
        }
        public void NotifyContracted(uint vertex)
        {
            this._contractionCount.Remove(vertex);
            DirectedMetaGraph.EdgeEnumerator edgeEnumerator = this._graph.GetEdgeEnumerator(vertex);
            edgeEnumerator.Reset();
            while (edgeEnumerator.MoveNext())
            {
                uint neighbour = edgeEnumerator.Neighbour;
                int  num;
                this._contractionCount[neighbour] = this._contractionCount.TryGetValue(neighbour, out num) ? num++ : 1;
            }
            int num1 = 0;

            this._depth.TryGetValue((long)vertex, out num1);
            this._depth.Remove((long)vertex);
            int num2 = num1 + 1;

            edgeEnumerator.Reset();
            while (edgeEnumerator.MoveNext())
            {
                uint neighbour = edgeEnumerator.Neighbour;
                int  num3      = 0;
                this._depth.TryGetValue((long)neighbour, out num3);
                if (num2 >= num3)
                {
                    this._depth[(long)neighbour] = num2;
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Gets the weight from the given edge and sets the direction.
        /// </summary>
        public sealed override float GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge, out bool?direction)
        {
            float weight;

            Data.Contracted.Edges.ContractedEdgeDataSerializer.Deserialize(edge.Data0,
                                                                           out weight, out direction);
            return(weight);
        }
Beispiel #6
0
        /// <summary>
        /// Notifies this calculator that the given vertex was contracted.
        /// </summary>
        public void NotifyContracted(uint vertex)
        {
            // removes the contractions count.
            _contractionCount.Remove(vertex);

            // loop over all neighbours.
            if (_edgeEnumerator == null)
            {
                _edgeEnumerator = _graph.GetEdgeEnumerator();
            }
            _edgeEnumerator.MoveTo(vertex);

            int vertexDepth = 0;

            _depth.TryGetValue(vertex, out vertexDepth);
            _depth.Remove(vertex);
            vertexDepth++;

            // store the depth.
            _edgeEnumerator.Reset();
            while (_edgeEnumerator.MoveNext())
            {
                var neighbour = _edgeEnumerator.Neighbour;

                int depth = 0;
                _depth.TryGetValue(neighbour, out depth);
                if (vertexDepth >= depth)
                {
                    _depth[neighbour] = vertexDepth;
                }

                int count;
                if (!_contractionCount.TryGetValue(neighbour, out count))
                {
                    _contractionCount[neighbour] = 1;
                }
                else
                {
                    count++;
                    _contractionCount[neighbour] = count;
                }

                if (_witnessGraph.VertexCount > vertex &&
                    _witnessGraph.VertexCount > neighbour)
                {
                    _witnessGraph.RemoveEdge(neighbour, vertex);
                }
            }

            if (_witnessGraph.VertexCount > vertex)
            {
                _witnessGraph.RemoveEdges(vertex);
            }
        }
Beispiel #7
0
        protected override void DoRun()
        {
            this._queue           = new BinaryHeap <uint>((uint)this._graph.VertexCount);
            this._contractedFlags = (ILongIndex) new OsmSharp.Collections.LongIndex.LongIndex.LongIndex();
            this._missesQueue     = new Queue <bool>();
            this.RemoveWitnessedEdges();
            this.CalculateQueue();
            uint? nullable    = this.SelectNext();
            float num1        = 0.0f;
            int   num2        = 0;
            long  vertexCount = this._graph.VertexCount;

            while (nullable.HasValue)
            {
                this.Contract(nullable.Value);
                nullable = this.SelectNext();
                float num3 = (float)(System.Math.Floor((double)num2 / (double)vertexCount * 10000.0) / 100.0);
                if ((double)num3 < 99.0)
                {
                    num3 = (float)(System.Math.Floor((double)num2 / (double)vertexCount * 100.0) / 1.0);
                }
                if ((double)num3 != (double)num1)
                {
                    num1 = num3;
                    int num4 = 0;
                    int num5 = 0;
                    int num6 = 0;
                    Dictionary <uint, int> dictionary = new Dictionary <uint, int>();
                    for (uint vertex = 0; (long)vertex < this._graph.VertexCount; ++vertex)
                    {
                        if (!this._contractedFlags.Contains((long)vertex))
                        {
                            dictionary.Clear();
                            DirectedMetaGraph.EdgeEnumerator edgeEnumerator = this._graph.GetEdgeEnumerator(vertex);
                            if (edgeEnumerator != null)
                            {
                                int count = edgeEnumerator.Count;
                                num4 = count + num4;
                                if (num6 < count)
                                {
                                    num6 = count;
                                }
                            }
                            ++num5;
                        }
                    }
                    double num7 = (double)num4 / (double)num5;
                    Log.TraceEvent("HierarchyBuilder", TraceEventType.Information, "Preprocessing... {0}% [{1}/{2}] {3}q #{4} max {5}", (object)num3, (object)num2, (object)vertexCount, (object)this._queue.Count, (object)num7, (object)num6);
                }
                ++num2;
            }
        }
Beispiel #8
0
        /// <summary>
        /// Adds edges relevant for contraction to the given vertex info, assuming it's empty.
        /// </summary>
        public static void AddRelevantEdges <T>(this VertexInfo <T> vertexInfo, DirectedMetaGraph.EdgeEnumerator enumerator)
            where T : struct
        {
            System.Diagnostics.Debug.Assert(vertexInfo.Count == 0);

            var vertex = vertexInfo.Vertex;

            enumerator.MoveTo(vertex);
            while (enumerator.MoveNext())
            {
                if (enumerator.Neighbour == vertex)
                {
                    continue;
                }

                vertexInfo.Add(enumerator.Current);
            }
        }
Beispiel #9
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();
        }
Beispiel #10
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.
            _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();
        }
Beispiel #11
0
 /// <summary>
 /// Gets the weight from a meta-edge.
 /// </summary>
 public abstract T GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge, out bool?direction);
Beispiel #12
0
 /// <summary>
 /// Gets the weight from the given edge and sets the direction.
 /// </summary>
 public sealed override WeightAndDir <float> GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge)
 {
     return(Data.Contracted.Edges.ContractedEdgeDataSerializer.Deserialize(edge.Data0));
 }
        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 float Calculate(ILongIndex contractedFlags, uint vertex)
        {
            int         num1     = 0;
            int         num2     = 0;
            List <Edge> edgeList = new List <Edge>((IEnumerable <Edge>) this._graph.Graph.GetEdgeEnumerator(vertex));
            int         index1   = 0;

            while (index1 < edgeList.Count)
            {
                DirectedMetaGraph.EdgeEnumerator edgeEnumerator = this._graph.GetEdgeEnumerator(edgeList[index1].Neighbour);
                edgeEnumerator.Reset();
                while (edgeEnumerator.MoveNext())
                {
                    if ((int)edgeEnumerator.Neighbour == (int)vertex)
                    {
                        ++num1;
                    }
                }
                if (contractedFlags.Contains((long)edgeList[index1].Neighbour))
                {
                    edgeEnumerator.MoveTo(vertex);
                    edgeEnumerator.Reset();
                    while (edgeEnumerator.MoveNext())
                    {
                        if ((int)edgeEnumerator.Neighbour == (int)edgeList[index1].Neighbour)
                        {
                            ++num1;
                        }
                    }
                    edgeList.RemoveAt(index1);
                }
                else
                {
                    ++index1;
                }
            }
            for (int capacity = 1; capacity < edgeList.Count; ++capacity)
            {
                Edge  edge1 = edgeList[capacity];
                float weight1;
                bool? direction1;
                ContractedEdgeDataSerializer.Deserialize(edge1.Data[0], out weight1, out direction1);
                bool         flag1           = !direction1.HasValue || direction1.Value;
                bool         flag2           = !direction1.HasValue || !direction1.Value;
                bool[]       forwardWitness  = new bool[capacity];
                bool[]       backwardWitness = new bool[capacity];
                List <uint>  targets         = new List <uint>(capacity);
                List <float> weights         = new List <float>(capacity);
                for (int index2 = 0; index2 < capacity; ++index2)
                {
                    Edge  edge2 = edgeList[index2];
                    float weight2;
                    bool? direction2;
                    ContractedEdgeDataSerializer.Deserialize(edge2.Data[0], out weight2, out direction2);
                    bool flag3 = !direction2.HasValue || direction2.Value;
                    bool flag4 = !direction2.HasValue || !direction2.Value;
                    forwardWitness[index2]  = !(flag2 & flag3);
                    backwardWitness[index2] = !(flag1 & flag4);
                    targets.Add(edge2.Neighbour);
                    weights.Add(weight1 + weight2);
                }
                this._witnessCalculator.Calculate(this._graph.Graph, edge1.Neighbour, targets, weights, ref forwardWitness, ref backwardWitness, vertex);
                for (int index2 = 0; index2 < capacity; ++index2)
                {
                    Edge edge2   = edgeList[index2];
                    int  removed = 0;
                    int  added   = 0;
                    if (!forwardWitness[index2] && !backwardWitness[index2])
                    {
                        this._graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, weights[index2], new bool?(), vertex, out added, out removed);
                        int num3 = num2 + added;
                        int num4 = num1 + removed;
                        this._graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, weights[index2], new bool?(), vertex, out added, out removed);
                        num2 = num3 + added;
                        num1 = num4 + removed;
                    }
                    else if (!forwardWitness[index2])
                    {
                        this._graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, weights[index2], new bool?(true), vertex, out added, out removed);
                        int num3 = num2 + added;
                        int num4 = num1 + removed;
                        this._graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, weights[index2], new bool?(false), vertex, out added, out removed);
                        num2 = num3 + added;
                        num1 = num4 + removed;
                    }
                    else if (!backwardWitness[index2])
                    {
                        this._graph.TryAddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour, weights[index2], new bool?(false), vertex, out added, out removed);
                        int num3 = num2 + added;
                        int num4 = num1 + removed;
                        this._graph.TryAddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour, weights[index2], new bool?(true), vertex, out added, out removed);
                        num2 = num3 + added;
                        num1 = num4 + removed;
                    }
                }
            }
            int num5 = 0;

            this._contractionCount.TryGetValue(vertex, out num5);
            int num6 = 0;

            this._depth.TryGetValue((long)vertex, out num6);
            return((float)(this.DifferenceFactor * (num2 - num1) + this.DepthFactor * num6 + this.ContractedFactor * num5));
        }
Beispiel #15
0
 /// <summary>
 /// Gets the weight from a meta-edge.
 /// </summary>
 public abstract WeightAndDir <T> GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge);
Beispiel #16
0
 /// <summary>
 /// Gets contracted id.
 /// </summary>
 /// <returns></returns>
 public static uint GetContractedId(this DirectedMetaGraph.EdgeEnumerator edge)
 {
     return(edge.MetaData0);
 }
Beispiel #17
0
 public override float GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge, out bool?direction)
 {
     throw new NotImplementedException();
 }
        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);
                }
            }
        }
Beispiel #19
0
 public override WeightAndDir <float> GetEdgeWeight(DirectedMetaGraph.EdgeEnumerator edge)
 {
     throw new NotImplementedException();
 }