Ejemplo n.º 1
0
        /// <summary>
        /// Contracts the given vertex.
        /// </summary>
        private void Contract()
        {
            var vertex     = _vertexInfo.Vertex;
            var enumerator = _graph.GetEdgeEnumerator();

            // remove 'downward' edge to vertex.
            var i = 0;

            while (i < _vertexInfo.Count)
            {
                var edge = _vertexInfo[i];

                _graph.RemoveEdge(edge.Neighbour, vertex);
                i++;
            }

            // add shortcuts.
            foreach (var s in _vertexInfo.Shortcuts)
            {
                var shortcut       = s.Value;
                var edge           = s.Key;
                var forwardMetric  = _weightHandler.GetMetric(shortcut.Forward);
                var backwardMetric = _weightHandler.GetMetric(shortcut.Backward);

                if (forwardMetric > 0 && forwardMetric < float.MaxValue &&
                    backwardMetric > 0 && backwardMetric < float.MaxValue &&
                    System.Math.Abs(backwardMetric - forwardMetric) < HierarchyBuilder <float> .E)
                { // forward and backward and identical weights.
                    _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                   vertex, null, shortcut.Forward);
                    _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                   vertex, null, shortcut.Backward);
                }
                else
                {
                    if (forwardMetric > 0 && forwardMetric < float.MaxValue)
                    {
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                       vertex, true, shortcut.Forward);
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                       vertex, false, shortcut.Forward);
                    }
                    if (backwardMetric > 0 && backwardMetric < float.MaxValue)
                    {
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                       vertex, false, shortcut.Backward);
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                       vertex, true, shortcut.Backward);
                    }
                }
            }

            _contractedFlags[vertex] = true;
            this.NotifyContracted(vertex);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        public void TestEdgeCount()
        {
            var graph = new DirectedMetaGraph(1, 1, 10);

            // add edge.
            graph.AddEdge(0, 1, 1, 100);
            Assert.AreEqual(1, graph.EdgeCount);

            graph = new DirectedMetaGraph(1, 1, 10);

            // add edge.
            graph.AddEdge(0, 1, 1, 100);
            graph.AddEdge(0, 11001, 1, 100);
            Assert.AreEqual(2, graph.EdgeCount);

            graph.AddEdge(0, 11001, 2, 200);
            Assert.AreEqual(3, graph.EdgeCount);

            graph.RemoveEdge(0, 11001);
            Assert.AreEqual(1, graph.EdgeCount);

            graph.RemoveEdge(0, 1);
            Assert.AreEqual(0, graph.EdgeCount);
        }
Ejemplo n.º 4
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);
            }
        }
        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);
                }
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
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);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Contracts the given vertex.
        /// </summary>
        protected virtual void Contract()
        {
            var vertex = _vertexInfo.Vertex;

            // remove 'downward' edge to vertex.
            var i = 0;

            while (i < _vertexInfo.Count)
            {
                var edge = _vertexInfo[i];

                _graph.RemoveEdge(edge.Neighbour, vertex);
                i++;

                // TOOD: what to do when stuff is only removed, is nothing ok?
                //_witnessQueue.Add(edge.Neighbour);
            }

            // add shortcuts.
            foreach (var s in _vertexInfo.Shortcuts)
            {
                var shortcut = s.Value;
                var edge     = s.Key;

                if (edge.Vertex1 == edge.Vertex2)
                { // TODO: figure out how this is possible, it shouldn't!
                    continue;
                }

                var forwardMetric  = _weightHandler.GetMetric(shortcut.Forward);
                var backwardMetric = _weightHandler.GetMetric(shortcut.Backward);

                if (forwardMetric > 0 && forwardMetric < float.MaxValue &&
                    backwardMetric > 0 && backwardMetric < float.MaxValue &&
                    System.Math.Abs(backwardMetric - forwardMetric) < FastHierarchyBuilder <float> .E)
                { // forward and backward and identical weights.
                    _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                   vertex, null, shortcut.Forward);
                    _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                   vertex, null, shortcut.Backward);
                    _witnessQueue.Add(edge.Vertex1);
                    _witnessQueue.Add(edge.Vertex2);
                }
                else
                {
                    if (forwardMetric > 0 && forwardMetric < float.MaxValue)
                    {
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                       vertex, true, shortcut.Forward);
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                       vertex, false, shortcut.Forward);
                        _witnessQueue.Add(edge.Vertex1);
                        _witnessQueue.Add(edge.Vertex2);
                    }
                    if (backwardMetric > 0 && backwardMetric < float.MaxValue)
                    {
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex1, edge.Vertex2,
                                                       vertex, false, shortcut.Backward);
                        _weightHandler.AddOrUpdateEdge(_graph, edge.Vertex2, edge.Vertex1,
                                                       vertex, true, shortcut.Backward);
                        _witnessQueue.Add(edge.Vertex1);
                        _witnessQueue.Add(edge.Vertex2);
                    }
                }
            }

            _contractedFlags[vertex] = true;
            this.NotifyContracted(vertex);
        }
Ejemplo n.º 9
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);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Remove all witnessed edges.
        /// </summary>
        private void RemoveWitnessedEdges()
        {
            _logger.Log(TraceEventType.Information, "Removing witnessed edges...");

            var edges   = new List <MetaEdge>();
            var weights = new List <T>();
            var metrics = new List <float>();
            var targets = new List <uint>();

            for (uint vertex = 0; vertex < _graph.VertexCount; vertex++)
            {
                edges.Clear();
                weights.Clear();
                metrics.Clear();
                targets.Clear();

                edges.AddRange(_graph.GetEdgeEnumerator(vertex));

                var forwardWitnesses  = new bool[edges.Count];
                var backwardWitnesses = new bool[edges.Count];
                for (var i = 0; i < edges.Count; i++)
                {
                    var edge = edges[i];

                    bool?edgeDirection;
                    var  edgeWeight = _weightHandler.GetEdgeWeight(edge, out edgeDirection);

                    var edgeCanMoveForward  = edgeDirection == null || edgeDirection.Value;
                    var edgeCanMoveBackward = edgeDirection == null || !edgeDirection.Value;

                    forwardWitnesses[i]  = !edgeCanMoveForward;
                    backwardWitnesses[i] = !edgeCanMoveBackward;
                    weights.Add(edgeWeight);
                    metrics.Add(_weightHandler.GetMetric(edgeWeight));
                    targets.Add(edge.Neighbour);
                }

                // calculate all witness paths.
                _witnessCalculator.Calculate(_graph.Graph, vertex, targets, metrics,
                                             ref forwardWitnesses, ref backwardWitnesses, uint.MaxValue);

                // check witness paths.
                for (var i = 0; i < edges.Count; i++)
                {
                    if (forwardWitnesses[i] && backwardWitnesses[i])
                    { // in both directions the edge does not represent the shortest path.
                        _graph.RemoveEdge(vertex, targets[i]);
                    }
                    else if (forwardWitnesses[i])
                    { // only in forward direction is this edge useless.
                        _graph.RemoveEdge(vertex, targets[i]);
                        _weightHandler.AddEdge(_graph, vertex, targets[i], Constants.NO_VERTEX, false, weights[i]);
                        //_graph.AddEdge(vertex, targets[i], weights[i], false, Constants.NO_VERTEX);
                    }
                    else if (backwardWitnesses[i])
                    { // only in backward direction is this edge useless.
                        _graph.RemoveEdge(vertex, targets[i]);
                        _weightHandler.AddEdge(_graph, vertex, targets[i], Constants.NO_VERTEX, true, weights[i]);
                    }
                }
            }
        }