예제 #1
0
        public void TestRemoveEdge()
        {
            var graph = new DirectedDynamicGraph();

            graph.AddEdge(1, 2, 0102, 010200);
            graph.AddEdge(1, 3, 0103);

            Assert.AreEqual(1, graph.RemoveEdge(1, 2));

            Assert.AreEqual(1, graph.EdgeCount);
            var enumerator = graph.GetEdgeEnumerator();

            Assert.IsTrue(enumerator.MoveTo(1));
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(3, enumerator.Neighbour);
            Assert.AreEqual(0103, enumerator.Data0);

            graph = new DirectedDynamicGraph();
            graph.AddEdge(1, 2, 0102, 010200);
            graph.AddEdge(1, 3, 0103);
            graph.AddEdge(1, 4, 0104, 010400, 01040000);

            Assert.AreEqual(1, graph.RemoveEdge(1, 3));
            enumerator = graph.GetEdgeEnumerator();
            Assert.IsTrue(enumerator.MoveTo(1));
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Neighbour);
            Assert.AreEqual(0102, enumerator.Data0);
            Assert.AreEqual(010200, enumerator.DynamicData[0]);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(4, enumerator.Neighbour);
            Assert.AreEqual(0104, enumerator.Data0);
            Assert.AreEqual(010400, enumerator.DynamicData[0]);
            Assert.AreEqual(01040000, enumerator.DynamicData[1]);
        }
예제 #2
0
        public void TestSerialize()
        {
            var graph = new DirectedDynamicGraph(10, 1);

            // add and compress.
            graph.AddEdge(0, 1, 1);
            graph.Compress();
            var expectedSize = 1 + 8 + 8 + 8 + 4 +         // the header: version byte two longs representing vertex, edge count and the size of the edge array and one int for minimum edge size.
                               graph.VertexCount * 1 * 4 + // the bytes for the vertex-index: 1 uint.
                               graph.EdgeCount * 2 * 4;    // the bytes for the edges: one edge 2 uint's.

            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 DirectedDynamicGraph(10, 1);

            // add and compress.
            graph.AddEdge(0, 1, 10);
            graph.AddEdge(1, 2, 20);
            graph.AddEdge(2, 3, 30);
            graph.AddEdge(3, 4, 40);
            graph.RemoveEdge(1, 2);
            graph.Compress();
            expectedSize = 1 + 8 + 8 + 8 + 4 +      // the header: version bytes, three longs representing vertex and edge count and the size of the edge array and one int for fixed edge size.
                           graph.VertexCount * 4 +  // the bytes for the vertex-index: 2 uint's.
                           graph.EdgeCount * 2 * 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);
            }
        }
예제 #3
0
        /// <summary>
        /// Contracts the given vertex.
        /// </summary>
        private void Contract(uint vertex)
        {
            // get and keep edges.
            var enumerator = _graph.GetEdgeEnumerator(vertex);
            var edges      = new List <DynamicEdge>(enumerator);

            // check if this vertex has a potential restrictions.
            var hasRestrictions = _restrictionFlags[vertex];

            // loop over all edge-pairs once.
            for (var j = 1; j < edges.Count; j++)
            {
                var edge1          = edges[j];
                var edge1Sequence2 = edges[j].GetSequence2();
                if (edge1Sequence2.Length == 0)
                {
                    edge1Sequence2 = new uint[] { vertex };
                }

                bool?edge1Direction;
                var  edge1Weight          = _weightHandler.GetEdgeWeight(edge1, out edge1Direction);
                var  edge1CanMoveForward  = edge1Direction == null || edge1Direction.Value;
                var  edge1CanMoveBackward = edge1Direction == null || !edge1Direction.Value;

                // figure out what witness paths to calculate.
                var forwardWitnesses  = new EdgePath <T> [j];
                var backwardWitnesses = new EdgePath <T> [j];
                var targets           = new List <uint>(j);
                var targetWeights     = new List <T>(j);
                for (var k = 0; k < j; k++)
                {
                    var edge2 = edges[k];

                    bool?edge2Direction;
                    var  edge2Weight          = _weightHandler.GetEdgeWeight(edge2, out edge2Direction);
                    var  edge2CanMoveForward  = edge2Direction == null || edge2Direction.Value;
                    var  edge2CanMoveBackward = edge2Direction == null || !edge2Direction.Value;

                    // use witness flags to represent impossible routes.
                    if (!(edge1CanMoveBackward && edge2CanMoveForward))
                    {
                        forwardWitnesses[k] = new EdgePath <T>();
                    }
                    if (!(edge1CanMoveForward && edge2CanMoveBackward))
                    {
                        backwardWitnesses[k] = new EdgePath <T>();
                    }

                    targets.Add(edge2.Neighbour);
                    if (hasRestrictions)
                    {
                        targetWeights.Add(_weightHandler.Infinite);
                    }
                    else
                    {
                        targetWeights.Add(_weightHandler.Add(edge1Weight, edge2Weight));
                    }
                }

                // calculate all witness paths.
                _witnessCalculator.Calculate(_graph, _getRestrictions, edge1.Neighbour, targets, targetWeights, ref forwardWitnesses,
                                             ref backwardWitnesses, Constants.NO_VERTEX);

                // get all sequences where needed.
                var s1forward  = new uint[forwardWitnesses.Length][];
                var s2forward  = new uint[forwardWitnesses.Length][];
                var s1backward = new uint[backwardWitnesses.Length][];
                var s2backward = new uint[backwardWitnesses.Length][];
                for (var k = 0; k < j; k++)
                {
                    var edge2Sequence2 = edges[k].GetSequence2();
                    if (edge2Sequence2.Length == 0)
                    {
                        edge2Sequence2 = new uint[] { vertex };
                    }

                    if (forwardWitnesses[k].HasVertex(vertex))
                    { // get forward sequences.
                        s1forward[k] = forwardWitnesses[k].GetSequence1(enumerator, 1);
                        s2forward[k] = forwardWitnesses[k].GetSequence2(enumerator, 1);

                        if (!s1forward[k].IsSequenceIdentical(edge1Sequence2) ||
                            !s2forward[k].IsSequenceIdentical(edge2Sequence2))
                        { // start and end sequences of shortest paths need to match.
                            s1forward[k] = null;
                            s2forward[k] = null;
                        }
                    }
                    if (backwardWitnesses[k].HasVertex(vertex))
                    { // get backward sequences.
                        s1backward[k] = backwardWitnesses[k].GetSequence1(enumerator, 1);
                        s2backward[k] = backwardWitnesses[k].GetSequence2(enumerator, 1);

                        if (!s1backward[k].IsSequenceIdentical(edge1Sequence2) ||
                            !s2backward[k].IsSequenceIdentical(edge2Sequence2))
                        { // start and end sequences of shortest paths need to match.
                            s1backward[k] = null;
                            s2backward[k] = null;
                        }
                    }
                }

                // add contracted edges if needed.
                for (var k = 0; k < j; k++)
                {
                    var edge2 = edges[k];

                    if (edge1.Neighbour == edge2.Neighbour)
                    { // do not try to add a shortcut between identical vertices.
                        continue;
                    }

                    //if (s1forward[k] != null && s1backward[k] != null &&
                    //    System.Math.Abs(_weightHandler.GetMetric(forwardWitnesses[k].Weight) - _weightHandler.GetMetric(backwardWitnesses[k].Weight)) < E)
                    //{ // paths in both direction are possible and with the same weight, add just one edge in each direction.
                    //    s1backward[k].Reverse();
                    //    s2backward[k].Reverse();
                    //    _weightHandler.AddOrUpdateEdge(_graph, edge1.Neighbour, edge2.Neighbour, vertex, null,
                    //        forwardWitnesses[k].Weight, s1forward[k], s2forward[k]);
                    //    //_graph.AddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour,
                    //    //    forwardWitnesses[k].Weight, null, vertex, s1forward[k], s2forward[k]);
                    //    _weightHandler.AddOrUpdateEdge(_graph, edge2.Neighbour, edge1.Neighbour, vertex, null,
                    //        backwardWitnesses[k].Weight, s2backward[k], s1backward[k]);
                    //    //_graph.AddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour,
                    //    //    backwardWitnesses[k].Weight, null, vertex, s2backward[k], s1backward[k]);
                    //}
                    //else
                    //{ // add two edge per direction.
                    if (s1forward[k] != null)
                    {     // add forward edge.
                        _weightHandler.AddOrUpdateEdge(_graph, edge1.Neighbour, edge2.Neighbour, vertex, true,
                                                       forwardWitnesses[k].Weight, s1forward[k], s2forward[k]);
                        //_graph.AddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour,
                        //    forwardWitnesses[k].Weight, true, vertex, s1forward[k], s2forward[k]);
                        s1forward[k].Reverse();
                        s2forward[k].Reverse();
                        _weightHandler.AddOrUpdateEdge(_graph, edge2.Neighbour, edge1.Neighbour, vertex, false,
                                                       forwardWitnesses[k].Weight, s2forward[k], s1forward[k]);
                        //_graph.AddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour,
                        //    forwardWitnesses[k].Weight, false, vertex, s2forward[k], s1forward[k]);
                    }
                    if (s1backward[k] != null)
                    {     // add forward edge.
                        _weightHandler.AddOrUpdateEdge(_graph, edge1.Neighbour, edge2.Neighbour, vertex, false,
                                                       backwardWitnesses[k].Weight, s1backward[k], s2backward[k]);
                        //_graph.AddOrUpdateEdge(edge1.Neighbour, edge2.Neighbour,
                        //    backwardWitnesses[k].Weight, false, vertex, s2backward[k], s1backward[k]);
                        s1backward[k].Reverse();
                        s2backward[k].Reverse();
                        _weightHandler.AddOrUpdateEdge(_graph, edge2.Neighbour, edge1.Neighbour, vertex, true,
                                                       backwardWitnesses[k].Weight, s2backward[k], s1backward[k]);
                        //_graph.AddOrUpdateEdge(edge2.Neighbour, edge1.Neighbour,
                        //    backwardWitnesses[k].Weight, true, vertex, s1backward[k], s2backward[k]);
                    }
                    //}
                }
            }

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

            while (i < edges.Count)
            {
                _graph.RemoveEdge(edges[i].Neighbour, vertex);

                if (_contractedFlags[edges[i].Neighbour])
                { // neighbour was already contracted, remove 'downward' edge and exclude it.
                    _graph.RemoveEdge(vertex, edges[i].Neighbour);
                    edges.RemoveAt(i);
                }
                else
                { // move to next edge.
                    i++;
                }
            }

            _contractedFlags[vertex] = true;
            _priorityCalculator.NotifyContracted(vertex);
        }
예제 #4
0
        public void TestAddSmallNetwork1AndContract()
        {
            // build graph.
            var graph = new DirectedDynamicGraph(5, 1);

            graph.AddEdge(0, 1, 100, null);
            graph.AddEdge(1, 0, 101, null);
            graph.AddEdge(1, 2, 102, null);
            graph.AddEdge(2, 1, 103, null);
            graph.AddEdge(1, 3, 104, null);
            graph.AddEdge(3, 1, 105, null);
            graph.AddEdge(1, 4, 106, null);
            graph.AddEdge(4, 1, 107, null);
            graph.AddEdge(2, 3, 108, null);
            graph.AddEdge(3, 2, 109, null);

            Assert.AreEqual(5, graph.VertexCount);

            // verify all edges for 0.
            var edges = graph.GetEdgeEnumerator(0);

            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(1, edges.First().Neighbour);
            Assert.AreEqual(null, edges.First().Direction());
            Assert.AreEqual(100, edges.First().Weight());

            // verify all edges for 1.
            edges = graph.GetEdgeEnumerator(1);
            Assert.AreEqual(4, edges.Count());
            var edge = edges.First(e => e.Neighbour == 0);

            Assert.AreEqual(0, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(101, edge.Weight());
            edge = edges.First(e => e.Neighbour == 0);
            Assert.AreEqual(0, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(101, edge.Weight());
            edge = edges.First(e => e.Neighbour == 2);
            Assert.AreEqual(2, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(102, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(104, edge.Weight());
            edge = edges.First(e => e.Neighbour == 4);
            Assert.AreEqual(4, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(106, edge.Weight());

            // verify all edges for 2.
            edges = graph.GetEdgeEnumerator(2);
            edge  = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(103, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(108, edge.Weight());

            // verify all edges for 3.
            edges = graph.GetEdgeEnumerator(3);
            edge  = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(105, edge.Weight());
            edge = edges.First(e => e.Neighbour == 2);
            Assert.AreEqual(2, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(109, edge.Weight());

            // verify all edges for 4.
            edges = graph.GetEdgeEnumerator(4);
            edge  = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(107, edge.Weight());

            // remove 3->2 and 1->2.
            graph.RemoveEdge(3, 2);
            graph.RemoveEdge(1, 2);

            // verify all edges for 0.
            edges = graph.GetEdgeEnumerator(0);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(1, edges.First().Neighbour);
            Assert.AreEqual(null, edges.First().Direction());
            Assert.AreEqual(100, edges.First().Weight());

            // verify all edges for 1.
            edges = graph.GetEdgeEnumerator(1);
            Assert.AreEqual(3, edges.Count());
            edge = edges.First(e => e.Neighbour == 0);
            Assert.AreEqual(0, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(101, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(104, edge.Weight());
            edge = edges.First(e => e.Neighbour == 4);
            Assert.AreEqual(4, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(106, edge.Weight());

            // verify all edges for 2.
            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(2, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(103, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(108, edge.Weight());

            // verify all edges for 3.
            edges = graph.GetEdgeEnumerator(3);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(105, edge.Weight());

            // verify all edges for 4.
            edges = graph.GetEdgeEnumerator(4);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(107, edge.Weight());

            // remove 1->0.
            graph.RemoveEdge(1, 0);

            // verify all edges for 0.
            edges = graph.GetEdgeEnumerator(0);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(1, edges.First().Neighbour);
            Assert.AreEqual(null, edges.First().Direction());
            Assert.AreEqual(100, edges.First().Weight());

            // verify all edges for 1.
            edges = graph.GetEdgeEnumerator(1);
            Assert.AreEqual(2, edges.Count());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(104, edge.Weight());
            edge = edges.First(e => e.Neighbour == 4);
            Assert.AreEqual(4, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(106, edge.Weight());

            // verify all edges for 2.
            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(2, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(103, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(108, edge.Weight());

            // verify all edges for 3.
            edges = graph.GetEdgeEnumerator(3);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(105, edge.Weight());

            // verify all edges for 4.
            edges = graph.GetEdgeEnumerator(4);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(107, edge.Weight());

            // remove 1->4.
            graph.RemoveEdge(1, 4);

            // verify all edges for 0.
            edges = graph.GetEdgeEnumerator(0);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(1, edges.First().Neighbour);
            Assert.AreEqual(null, edges.First().Direction());
            Assert.AreEqual(100, edges.First().Weight());

            // verify all edges for 1.
            edges = graph.GetEdgeEnumerator(1);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(104, edge.Weight());

            // verify all edges for 2.
            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(2, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(103, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(108, edge.Weight());

            // verify all edges for 3.
            edges = graph.GetEdgeEnumerator(3);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(105, edge.Weight());

            // verify all edges for 4.
            edges = graph.GetEdgeEnumerator(4);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(107, edge.Weight());

            // remove 1->3.
            graph.RemoveEdge(1, 3);

            // verify all edges for 0.
            edges = graph.GetEdgeEnumerator(0);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(1, edges.First().Neighbour);
            Assert.AreEqual(null, edges.First().Direction());
            Assert.AreEqual(100, edges.First().Weight());

            // verify all edges for 1.
            edges = graph.GetEdgeEnumerator(1);
            Assert.AreEqual(0, edges.Count());

            // verify all edges for 2.
            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(2, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(103, edge.Weight());
            edge = edges.First(e => e.Neighbour == 3);
            Assert.AreEqual(3, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(108, edge.Weight());

            // verify all edges for 3.
            edges = graph.GetEdgeEnumerator(3);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(105, edge.Weight());

            // verify all edges for 4.
            edges = graph.GetEdgeEnumerator(4);
            Assert.AreEqual(1, edges.Count());
            edge = edges.First(e => e.Neighbour == 1);
            Assert.AreEqual(1, edge.Neighbour);
            Assert.AreEqual(null, edge.Direction());
            Assert.AreEqual(107, edge.Weight());
        }
예제 #5
0
        public void TestCompress()
        {
            var graph = new DirectedDynamicGraph(10, 1);

            // add and compress.
            graph.AddEdge(0, 1, 1);
            graph.Compress();

            // verify all edges.
            var edges = graph.GetEdgeEnumerator(0);

            Assert.AreEqual(1, edges.First().Data[0]);
            Assert.AreEqual(1, edges.First().Neighbour);

            graph = new DirectedDynamicGraph(10, 1);

            // add and compress.
            graph.AddEdge(0, 1, 10);
            graph.AddEdge(1, 2, 20);
            graph.AddEdge(2, 3, 30);
            graph.AddEdge(3, 4, 40);
            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(1, edges.First().Neighbour);

            edges = graph.GetEdgeEnumerator(1);
            Assert.IsFalse(edges.MoveNext());

            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(30, edges.First().Data[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(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(1, edges.First().Neighbour);

            edges = graph.GetEdgeEnumerator(1);
            Assert.IsFalse(edges.MoveNext());

            edges = graph.GetEdgeEnumerator(2);
            Assert.AreEqual(1, edges.Count());
            Assert.AreEqual(30, edges.First().Data[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(4, edges.First().Neighbour);
        }