Пример #1
0
        public PartialSolution(PartialSolution parent)
        {
            G               = parent.G;
            VertexSubset    = (int[])parent.VertexSubset.Clone();
            SeparatorSubset = (int[])parent.SeparatorSubset.Clone();

            SeparatorSize = parent.SeparatorSize;
            DepthBelow    = parent.DepthBelow;
        }
Пример #2
0
        public PartialSolution AddVertex(Vertex v)
        {
            PartialSolution result = new PartialSolution(this);

            if (Contains(v))
            {
                return(result);
            }

            result.VertexSubset[v.Id / 32] |= (1 << (v.Id % 32));
            result.DepthBelow++;

            result.RootVertexID = v.Id;
            //result.Child = this;
            result.Left = this;

            if (IsSep(v))
            {
                result.SeparatorSubset[v.Id / 32] &= ~(1 << (v.Id % 32));
                result.SeparatorSize--;
            }

            foreach (Vertex u in v.Nb)
            {
                if (!Contains(u) && !IsSep(u))
                {
                    if (u.Adj.Count == 1 && v.Adj.Count != 1)
                    {
                        return(null);
                    }

                    result.SeparatorSize++;
                    result.SeparatorSubset[u.Id / 32] |= 1 << (u.Id % 32);
                }
            }

            if (result.LowerBound > Graph.UB)
            {
                return(null);
            }

            return(result);
        }
Пример #3
0
        public PartialSolution Join(PartialSolution other)
        {
            int newSepSize = 0;

            for (int i = 0; i < VertexSubset.Length; i++)
            {
                if ((this.VertexSubset[i] & other.VertexSubset[i]) != 0)
                {
                    return(null);
                }
                newSepSize += (this.SeparatorSubset[i] | other.SeparatorSubset[i]).BitCount();
            }

            if (newSepSize == SeparatorSize + other.SeparatorSize)
            {
                return(null);
            }

            if (newSepSize + Math.Max(DepthBelow, other.DepthBelow) > Graph.UB)
            {
                return(null);
            }

            PartialSolution result = new PartialSolution(other);

            result.Left  = this;
            result.Right = other;

            // Copy subsets
            for (int i = 0; i < VertexSubset.Length; i++)
            {
                result.VertexSubset[i] |= this.VertexSubset[i];
            }

            for (int i = 0; i < SeparatorSubset.Length; i++)
            {
                result.SeparatorSubset[i] |= this.SeparatorSubset[i];
            }

            result.SeparatorSize = newSepSize;
            result.DepthBelow    = Math.Max(DepthBelow, other.DepthBelow);

            foreach (Vertex v in result.Separator)
            {
                if (!v.Nb.Any((u) => !result.Contains(u) && !result.IsSep(u)))
                {
                    PartialSolution resultChild = new PartialSolution(result);
                    resultChild.RootVertexID = result.RootVertexID;
                    resultChild.Left         = result.Left; resultChild.Right = result.Right;
                    result.Left         = resultChild; result.Right = null;
                    result.RootVertexID = v.Id;

                    result.SeparatorSubset[v.Id / 32] &= ~(1 << (v.Id % 32));
                    result.VertexSubset[v.Id / 32]    |= 1 << (v.Id % 32);
                    result.SeparatorSize--;
                    result.DepthBelow++;
                }
            }

            return(result);
        }
Пример #4
0
        public bool TrySolve()
        {
            PriorityQueue <PartialSolution> q         = new PriorityQueue <PartialSolution>();
            HashSet <PartialSolution>       processed = new HashSet <PartialSolution>();

            foreach (Vertex v in Vertices)
            {
                PartialSolution ps = new PartialSolution(this);
                ps = ps.AddVertex(v);
                if (ps == null)
                {
                    continue;
                }
                q.Enqueue(ps, ps.DepthBelow);
            }

            while (q.Count > 0)// && sw.ElapsedMilliseconds < 1000 * 60 * 3)
            {
                PartialSolution ps = q.Dequeue();

                if (processed.Contains(ps))
                {
                    continue;
                }

                int count = ps.Vertices.Count() + ps.Separator.Count();

                if (count == Vertices.Length)
                {
                    //Console.WriteLine("Solution: " + ps.LowerBound);

                    //Console.WriteLine();

                    PartialSolution result = ps;
                    foreach (Vertex v in ps.Separator)
                    {
                        result = result.AddVertex(v);
                        throw new Exception("Unexpected condition");
                    }
                    result.Print();

                    return(true);
                }

                foreach (Vertex v in ps.Separator)
                {
                    PartialSolution newPS = ps.AddVertex(v);
                    if (newPS == null)
                    {
                        continue;
                    }
                    q.Enqueue(newPS, newPS.DepthBelow);

                    int             scount = newPS.Separator.Count();
                    PartialSolution key    = new PartialSolution(this);
                    key.VertexSubset = newPS.SeparatorSubset;
                }

                List <PartialSolution> toAdd = new List <PartialSolution>();

                foreach (PartialSolution mergeCandidate in processed)
                {
                    PartialSolution newPS = ps.Join(mergeCandidate);
                    if (newPS == null)
                    {
                        continue;
                    }
                    toAdd.Add(newPS);
                }

                foreach (PartialSolution newPS in toAdd)
                {
                    q.Enqueue(newPS, newPS.DepthBelow);

                    int             scount = newPS.Separator.Count();
                    PartialSolution key    = new PartialSolution(this);
                    key.VertexSubset = newPS.SeparatorSubset;
                }

                processed.Add(ps);
            }

            /*if(sw.ElapsedMilliseconds >= 1000 * 60 * 3)
             * {
             *  Console.WriteLine("Time out at: " + UB);
             *
             *  return true;
             * }*/

            return(false);
        }