Esempio n. 1
0
        /// <summary>
        /// Calculates the edge-difference if u would be contracted.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            short contracted = 0;

            _contraction_count.TryGetValue(vertex, out contracted);

            // get the neighbours.
            var neighbours = _data.GetEdges(vertex);

            // simulate the construction of new edges.
            int new_edges = 0;
            int removed   = neighbours.Length;

            // loop over all neighbours and check for witnesses.
            foreach (KeyValuePair <uint, CHEdgeData> from in neighbours)
            { // loop over all incoming neighbours
                if (!from.Value.Backward)
                {
                    continue;
                }
                foreach (KeyValuePair <uint, CHEdgeData> to in neighbours)
                { // loop over all outgoing neighbours
                    if (to.Key != from.Key &&
                        to.Value.Forward)
                    { // the neighbours point to different vertices.
                        // a new edge is needed.
                        if (!_witness_calculator.Exists(_data, from.Key, to.Key, vertex,
                                                        (float)from.Value.Weight + (float)to.Value.Weight, 1000))
                        { // no witness exists.
                            new_edges++;
                        }
                    }
                }
            }

            // get the depth.
            long depth = 0;

            _depth.TryGetValue(vertex, out depth);
            return((((new_edges) - removed)) + (2 * contracted));
            //return (new_edges - removed) + depth;
        }
Esempio n. 2
0
        /// <summary>
        /// Calculates the edge-difference if u would be contracted.
        /// </summary>
        /// <param name="vertex"></param>
        /// <returns></returns>
        public float Calculate(uint vertex)
        {
            // get the neighbours.
            var neighbours = _data.GetEdges(vertex);

            // simulate the construction of new edges.
            int newEdges             = 0;
            int removed              = 0;
            var edgesForContractions = new List <KeyValuePair <uint, CHEdgeData> >(neighbours.Length);

            foreach (var neighbour in neighbours)
            {
                if (!neighbour.Value.ToLower && !neighbour.Value.ToHigher)
                {
                    edgesForContractions.Add(neighbour);
                    removed++;
                }
            }

            // loop over all neighbours and check for witnesses.
            foreach (var from in edgesForContractions)
            {     // loop over all incoming neighbours
                foreach (var to in edgesForContractions)
                { // loop over all outgoing neighbours
                    if (to.Key != from.Key &&
                        to.Value.Forward && from.Value.Backward)
                    { // the neighbours point to different vertices.
                        // a new edge is needed.
                        if (!_witnessCalculator.Exists(_data, from.Key, to.Key, vertex,
                                                       (float)from.Value.Weight + (float)to.Value.Weight, 1000))
                        { // no witness exists.
                            newEdges++;
                        }
                    }
                }
            }
            return((2 * newEdges) - removed);
        }
Esempio n. 3
0
        /// <summary>
        /// Contracts the given vertex.
        /// </summary>
        /// <param name="vertex"></param>
        public void Contract(uint vertex)
        {
            if (_contracted.Length > vertex && _contracted[vertex])
            {
                throw new Exception("Is already contracted!");
            }

            // keep the neighbours.
            var neighbours = new HashSet <KeyValuePair <uint, CHEdgeData> >();

            // get all information from the source.
            var edges = _target.GetEdges(vertex);

            // report the before contraction event.
            this.OnBeforeContraction(vertex, edges);

            // replace the adjacent edges with edges that are point up.
            var edgesForContractions = new List <KeyValuePair <uint, CHEdgeData> >(edges.Length);

            foreach (var edge in edges)
            {
                if (!edge.Value.ToLower && !edge.Value.ToHigher)
                { // the edge is not to lower or higher.
                    // use this edge for contraction.
                    edgesForContractions.Add(edge);

                    // overwrite the old edge making it point 'to higher' only.
                    _target.AddEdge(vertex, edge.Key,
                                    new CHEdgeData(edge.Value.Weight, edge.Value.Forward, edge.Value.Backward, true, edge.Value.ContractedVertexId, edge.Value.Tags), null);
                }
            }

            // loop over each combination of edges just once.
            for (int x = 1; x < edgesForContractions.Count; x++)
            { // loop over all elements first.
                var xEdge = edgesForContractions[x];

                for (int y = 0; y < x; y++)
                { // loop over all elements.
                    var yEdge = edgesForContractions[y];

                    // calculate the total weight.
                    var weight = xEdge.Value.Weight + yEdge.Value.Weight;

                    // add the combinations of these edges.
                    if (((xEdge.Value.Backward && yEdge.Value.Forward) ||
                         (yEdge.Value.Backward && xEdge.Value.Forward)) &&
                        (xEdge.Key != yEdge.Key))
                    { // there is a connection from x to y and there is no witness path.
                        var witnessXToY = _contractionWitnessCalculator.Exists(_target, xEdge.Key,
                                                                               yEdge.Key, vertex, weight, int.MaxValue);
                        var witnessYToX = _contractionWitnessCalculator.Exists(_target, yEdge.Key,
                                                                               xEdge.Key, vertex, weight, int.MaxValue);

                        // create x-to-y data and edge.
                        var dataXToY = new CHEdgeData();
                        var forward  = (xEdge.Value.Backward && yEdge.Value.Forward) &&
                                       !witnessXToY;
                        var backward = (yEdge.Value.Backward && xEdge.Value.Forward) &&
                                       !witnessYToX;
                        if ((forward || backward) ||
                            !_target.ContainsEdge(xEdge.Key, yEdge.Key))
                        { // add the edge if there is usefull info or if there needs to be a neighbour relationship.
                            dataXToY.SetDirection(forward, backward);
                            dataXToY.Weight             = weight;
                            dataXToY.ContractedVertexId = vertex;

                            _target.AddEdge(xEdge.Key, yEdge.Key, dataXToY, null, _comparer);
                        }
                    }
                }
            }

            // mark the vertex as contracted.
            this.MarkContracted(vertex);

            // notify a contracted neighbour.
            _calculator.NotifyContracted(vertex);

            // report the after contraction event.
            this.OnAfterContraction(vertex, edges);
        }