public PartialSolution(PartialSolution parent) { G = parent.G; VertexSubset = (int[])parent.VertexSubset.Clone(); SeparatorSubset = (int[])parent.SeparatorSubset.Clone(); SeparatorSize = parent.SeparatorSize; DepthBelow = parent.DepthBelow; }
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); }
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); }
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); }