예제 #1
0
        /// <summary>
        /// Executes the actual run.
        /// </summary>
        protected override void DoRun()
        {
            float  distance;
            ushort edgeProfile;
            bool?  direction = null;

            var factors        = new Dictionary <ushort, Factor>();
            var edgeEnumerator = _source.GetEdgeEnumerator();

            for (uint vertex = 0; vertex < _source.VertexCount; vertex++)
            {
                edgeEnumerator.MoveTo(vertex);
                edgeEnumerator.Reset();
                while (edgeEnumerator.MoveNext())
                {
                    EdgeDataSerializer.Deserialize(edgeEnumerator.Data0,
                                                   out distance, out edgeProfile);
                    Factor factor;
                    var    weight = _weightHandler.Calculate(edgeProfile, distance, out factor);

                    if (factor.Value != 0)
                    {
                        direction = null;
                        if (factor.Direction == 1)
                        {
                            direction = true;
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = false;
                            }
                        }
                        else if (factor.Direction == 2)
                        {
                            direction = false;
                            if (edgeEnumerator.DataInverted)
                            {
                                direction = true;
                            }
                        }

                        _weightHandler.AddEdge(_target, edgeEnumerator.From, edgeEnumerator.To, direction, weight);
                    }
                }
            }

            this.HasSucceeded = true;
        }
예제 #2
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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #3
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]);
                    }
                }
            }
        }