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 #2
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++;
                    }
                }
            }
        }
        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;
                }
            }
        }
Beispiel #4
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);
                    }
                }
            }
        }