示例#1
0
        public ComponentInfo GetComponentInfo(ConnVertex vertex)
        {
            long iteration = ++_iteration;

            var info = EnsureInfo(vertex);

            info.iteration = iteration;

            int    size  = 1;
            var    queue = new Queue <VertexInfo>(new[] { info });
            object aug   = info.aug;

            while (queue.Count > 0)
            {
                var vert = queue.Dequeue();
                foreach (var next in vert.edges)
                {
                    if (next.iteration == iteration)
                    {
                        continue;
                    }

                    size++;
                    aug            = _augmentation.Combine(aug, info.aug);
                    next.iteration = iteration;
                    queue.Enqueue(next);
                }
            }
            return(new ComponentInfo(vertex, aug, size));
        }
示例#2
0
        public bool IsConnected(ConnVertex vertex1, ConnVertex vertex2)
        {
            long iteration = ++_iteration;

            var info1 = EnsureInfo(vertex1);
            var info2 = EnsureInfo(vertex2);

            info1.iteration = iteration;
            info2.iteration = iteration;
            info1.direction = false;
            info2.direction = true;

            var queue = new Queue <VertexInfo>(new[] { info1, info2 });

            while (queue.Count > 0)
            {
                var vert = queue.Dequeue();
                foreach (var next in vert.edges)
                {
                    if (next.iteration == iteration)
                    {
                        if (next.direction != vert.direction)
                        {
                            return(true);
                        }
                        continue;
                    }

                    next.direction = vert.direction;
                    next.iteration = iteration;
                    queue.Enqueue(next);
                }
            }
            return(false);
        }
示例#3
0
        public bool RemoveEdge(ConnVertex vertex1, ConnVertex vertex2)
        {
            var info1 = EnsureInfo(vertex1);
            var info2 = EnsureInfo(vertex2);

            RemoveEdge(info1, info2);
            return(RemoveEdge(info2, info1));
        }
示例#4
0
        public bool AddEdge(ConnVertex connVertex1, ConnVertex connVertex2)
        {
            var info1 = EnsureInfo(connVertex1);
            var info2 = EnsureInfo(connVertex2);

            info1.edges.Add(info2);
            return(info2.edges.Add(info1));
        }
示例#5
0
        public object RemoveVertexAugmentation(ConnVertex connVertex)
        {
            var info = EnsureInfo(connVertex);
            var old  = info.aug;

            info.aug = null;
            return(old);
        }
示例#6
0
        public object SetVertexAugmentation(ConnVertex connVertex, object vertexAugmentation)
        {
            var info = EnsureInfo(connVertex);
            var old  = info.aug;

            info.aug = vertexAugmentation;
            return(old);
        }
示例#7
0
 public ICollection <ConnVertex> AdjacentVertices(ConnVertex vertex)
 {
     if (_info.TryGetValue(vertex, out var info))
     {
         return(info.edges.Select(x => x.vertex).ToArray());
     }
     else
     {
         return(new ConnVertex[0]);
     }
 }
示例#8
0
        private VertexInfo EnsureInfo(ConnVertex vertex)
        {
            if (_info.TryGetValue(vertex, out var existingInfo))
            {
                return(existingInfo);
            }

            var newInfo = new VertexInfo(vertex);

            _info[vertex] = newInfo;
            return(newInfo);
        }
示例#9
0
 public ComponentInfo(ConnVertex vertex, object augmentation, int size)
 {
     this.vertex       = vertex;
     this.augmentation = augmentation;
     this.size         = size;
 }
        public void TestBenchmark(int nV, int nE, int nQ, int nO, int seed, int queryType = 0, bool naive = false, int type = 1)
        {
            if (seed == 0)
            {
                seed = new Random().Next();
            }

            var swA  = new PerformanceMeasurement(10);
            var swD  = new PerformanceMeasurement(10);
            var swQ  = new PerformanceMeasurement(1);
            int hash = 0;

            int nD   = nO / 2;  // number of deletions
            int nA   = nO - nD; // number of additions
            int maxE = nV * (nV - 1) / 2;

            var rand  = new Random(seed);
            var rand2 = new Random(seed + 31);

            IConnGraph graph;

            swA.Start();
            if (naive)
            {
                graph = new NaiveConnGraph(SumAndMax.AUGMENTATION);
            }
            else
            {
                graph = new ConnGraph(SumAndMax.AUGMENTATION, (ConnGraphComponentStorageType)type);
            }
            swA.Stop();

            var V = new ConnVertex[nV];

            for (int i = 0; i < nV; i++)
            {
                V[i] = new ConnVertex(rand2);
                graph.SetVertexAugmentation(V[i], new SumAndMax(1, 1));
            }

            var E     = new HashSet <Pii>();
            var EList = new List <Pii>(nE);

            // for (int i = 1; i < nV; i++)
            // {
            //     graph.AddEdge(V[i - 1], V[i]);
            // }
            for (int i = 0; i < nE; i++)
            {
                AddRandomEdge();
            }
            // swA.Start();
            // graph.Optimize();
            // swA.Stop();
            _log.WriteLine($"Init time:   {swA}\n");
            swA.Reset();

            char[] O = new char[nO + nQ];
            for (int i = 0; i < nA; i++)
            {
                O[i] = 'a';
            }
            for (int i = nA; i < nO; i++)
            {
                O[i] = 'd';
            }
            for (int i = nO; i < nO + nQ; i++)
            {
                O[i] = 'q';
            }
            Shuffle(O, rand);

            foreach (char o in O)
            {
                switch (o)
                {
                case 'a':
                    AddRandomEdge();
                    break;

                case 'd':
                    DeleteRandomEdge();
                    break;

                case 'q':
                    switch (queryType)
                    {
                    case 0:
                        Query0();
                        break;

                    case 1:
                        Query1();
                        break;

                    case 2:
                        Query2();
                        break;
                    }
                    break;
                }
            }
            _log.WriteLine($"Add time:    {swA}");
            _log.WriteLine($"Delete time: {swD}");
            _log.WriteLine($"Query time:  {swQ}");
            _log.WriteLine("");
            _log.WriteLine($"hash: {hash}");

            void AddRandomEdge()
            {
                if (EList.Count == maxE)
                {
                    return;
                }

                while (true)
                {
                    int a1  = rand.Next(1, nV);
                    int b1  = rand.Next(0, a1);
                    var pii = new Pii(a1, b1);
                    if (E.Add(pii))
                    {
                        EList.Add(pii);
                        swA.Start();
                        graph.AddEdge(V[a1], V[b1]);
                        swA.Stop();
                        return;
                    }
                }
            }

            void DeleteRandomEdge()
            {
                int count = EList.Count;

                if (count == 0)
                {
                    return;
                }
                int i1  = rand.Next(0, count);
                var pii = EList[i1];

                E.Remove(pii);
                EList[i1] = EList[count - 1];
                EList.RemoveAt(count - 1);
                swD.Start();
                graph.RemoveEdge(V[pii.a], V[pii.b]);
                swD.Stop();
            }

            void Query0()
            {
                int a1 = rand.Next(1, nV);
                int b1 = rand.Next(0, a1);

                swQ.Start();
                bool result = graph.IsConnected(V[a1], V[b1]);

                swQ.Stop();

                hash = hash * 31 + (result ? 402653189 : 786433);
            }

            void Query1()
            {
                int a1 = rand.Next(0, nV);

                swQ.Start();
                var info = graph.GetComponentInfo(V[a1]);

                swQ.Stop();
                int result = ((SumAndMax)info.augmentation).sum;

                Assert.True(info.size == result);

                hash = hash * 31 + result;
            }

            void Query2()
            {
                swQ.Start();
                var components = graph.GetAllComponents();

                swQ.Stop();
                foreach (var component in components.OrderBy(x => x.size))
                {
                    // hash += component.size;
                    hash = hash * 31 + component.size;
                }
            }
        }
示例#11
0
 public VertexInfo(ConnVertex vertex)
 {
     this.vertex = vertex ?? throw new ArgumentNullException();
 }
示例#12
0
 public bool ComponentHasAugmentation(ConnVertex vertex)
 {
     return(this.GetComponentAugmentation(vertex) != null);
 }
示例#13
0
        public bool VertexHasAugmentation(ConnVertex vertex)
        {
            var info = EnsureInfo(vertex);

            return(info.aug != null);
        }
示例#14
0
        public object GetVertexAugmentation(ConnVertex vertex)
        {
            var info = EnsureInfo(vertex);

            return(info.aug);
        }