/// <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; }
/// <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); } } } } } } }
/// <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]); } } } }