Esempio n. 1
0
        public Vector <uint>[] GetColumn(PartialSolution s)
        {
            // Generate cuts
            for (int j = 0; j < tempArray.Length; j++)
            {
                tempArray[j] = 0;
            }

            if (vertices.Length <= 1)
            {
                tempArray[0] = 1;
            }
            else
            {
                GenerateCuts(0, 1, s, tempArray, vertices);
            }

            // Copy to SIMD vector
            Vector <uint>[] column = GetArray();
            for (int j = 0; j < rowCountVector; j++)
            {
                column[j] = new Vector <uint>(tempArray, j * Vector <uint> .Count);
            }

            Program.GenerateCount++;

            return(column);
        }
Esempio n. 2
0
        public bool AddSolution(PartialSolution s, Vector <uint>[] currentColumn)
        {
            // Do elimination
            for (int j = 0; j < elimCount; j++)
            {
                //if (GetBit(currentColumn, elimOrder[j]) != 0)
                if ((currentColumn[orderEpos[j]][orderErem[j]] & orderEmask[j]) != 0)
                {
                    XOR(currentColumn, basisColumns[elimOrder[j]], currentColumn, rowCountVector);
                }
            }

            int zeroPos = FirstNonZero(currentColumn, rowCountVector);

            // Column was redundant
            if (zeroPos == -1)
            {
                return(false);
            }

            // Do precomputation of (expensive) GetBit to speed things up *a lot*
            orderEpos[elimCount]  = zeroPos / VectorLength;
            orderErem[elimCount]  = (zeroPos % VectorLength) >> 5;
            orderEmask[elimCount] = 1u << ((zeroPos % VectorLength) & 31);

            // Add to basis
            elimOrder[elimCount++] = zeroPos;
            basisColumns[zeroPos]  = currentColumn;

            return(true);
        }
Esempio n. 3
0
        // Old, slower, recursive method of generating a cut
        void GenerateCuts_old(int cutIndex, int pos, PartialSolution solution, uint[] column, Vertex[] vertices)
        {
            if (pos >= vertices.Length)
            {
                column[cutIndex >> 5] |= 1u << (cutIndex & 31);
                return;
            }

            bool canGoLeft = true, canGoRight = true;

            if (solution.Find(vertices[0].Color) == solution.Find(vertices[pos].Color))
            {
                canGoRight = false;
            }

            for (int i = 1; i < pos; i++)
            {
                if (solution.Find(vertices[i].Color) == solution.Find(vertices[pos].Color))
                {
                    if ((cutIndex & (1 << (i - 1))) > 0)
                    {
                        canGoLeft = false;
                    }
                    else
                    {
                        canGoRight = false;
                    }
                }
            }

            if (canGoLeft)
            {
                GenerateCuts_old(cutIndex, pos + 1, solution, column, vertices);
            }
            if (canGoRight)
            {
                GenerateCuts_old(cutIndex | (1 << (pos - 1)), pos + 1, solution, column, vertices);
            }
        }
Esempio n. 4
0
        static uint[] VerticesInPartition = new uint[33]; // One senitel element
        static void GenerateCuts(int cutIndex, int pos, PartialSolution solution, uint[] column, Vertex[] vertices)
        {
            int partitionChecker = 0; int partitionCount = 0; int zeroID = solution.Find(vertices[0].Color);

            for (int i = 1; i < vertices.Length; i++)
            {
                int id = solution.Find(vertices[i].Color);
                if (id == zeroID)
                {
                    continue;               // The connected component containing vertex 0 is fixed (representative is always lowest vertex)
                }
                int mask = 1 << id;
                if ((partitionChecker & mask) == 0)
                {
                    partitionChecker |= mask;
                    RootIndex[id]     = partitionCount++;
                    VerticesInPartition[RootIndex[id]] = 1u << (i - 1);
                }
                else
                {
                    VerticesInPartition[RootIndex[id]] |= 1u << (i - 1);
                }
            }

            uint cut = 0;

            for (uint i = 0; i < (1 << partitionCount); i++)
            {
                uint delta = i ^ (i + 1);
                column[cut >> 5] |= 1u << (int)(cut & 31);
                int j = 0;
                while (delta != 0)
                {
                    cut ^= VerticesInPartition[j];
                    j++;
                    delta >>= 1;
                }
            }
        }
Esempio n. 5
0
        public PartialSolution(VertexSubset subset, PartialSolution parent)
        {
            Subset    = subset;
            UnionFind = new byte[subset == null ? 0 : subset.ParentBag.ParentDecomposition.Width];
            for (byte i = 0; i < UnionFind.Length; i++)
            {
                UnionFind[i] = parent.UnionFind == null ? i : parent.UnionFind[i];
            }
            hashCode = 0;

            // Check if any vertices have been forgotten
            if (parent.Subset == null || ((subset.LocalSubset ^ parent.Subset.LocalSubset) & parent.Subset.LocalSubset) == 0)
            {
                return;
            }

            // Rework union-find to fix forgotten vertices
            for (byte i = 0; i < UnionFind.Length; i++)
            {
                if ((Subset.LocalSubset & (1 << i)) != 0 && (parent.Subset.LocalSubset & (1 << i)) != 0)
                {
                    byte rep = Find(i);
                    if ((Subset.LocalSubset & (1 << rep)) == 0)
                    {
                        UnionFind[rep] = i;
                        UnionFind[i]   = i;
                    }
                }
            }

            for (byte i = 0; i < UnionFind.Length; i++)
            {
                if ((Subset.LocalSubset & (1 << i)) == 0)
                {
                    UnionFind[i] = i;
                }
            }
        }
Esempio n. 6
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            PartialSolution objSol = (PartialSolution)obj;

            if (Subset.LocalSubset != objSol.Subset.LocalSubset)
            {
                return(false);
            }

            for (int i = 0; i < UnionFind.Length; i++)
            {
                if (Find(i) != objSol.Find(i))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 7
0
        static void Main(string[] args)
        {
            int seed = 4321;

            // Prescribed method of initializing randomness
            if (Array.IndexOf(args, "-s") < args.Length - 1)
            {
                try
                {
                    seed = int.Parse(args[Array.IndexOf(args, "-s") + 1]);
                }
                catch { }
            }

            Stopwatch sw = new Stopwatch();

            //StreamWriter outSW = new StreamWriter("output.txt");
            //Console.SetOut(outSW);

            //for (int i = 79; i < 200; i += 2)
            {
                r = new Random(seed);

                //outSW.Flush();
                //if (i == 79) continue; // This testcase is very large and slow
                sw.Restart();

                //if (Debug) Console.Write(i.ToString().PadLeft(3, '0') + " ");
                StreamReader sr = null;
                //sr = new StreamReader(String.Format("../../../../../instances/instance{0}.gr", i.ToString().PadLeft(3, '0')));

                g             = Graph.Parse(sr ?? Console.In);
                decomposition = TreeDecomposition.Parse(sr ?? Console.In, g);

                InitUF(g);

                List <Edge> forcedEdges = new List <Edge>();

                // Find edges that are forced because they are between two terminals and there is no path with lighter bottleneck
                foreach (Edge e in g.Edges.OrderBy((e) => e.Weight).ThenBy((e) => e.To.IsTerminal && e.From.IsTerminal ? 0 : 1))
                {
                    if (Find(e.From.Id) == Find(e.To.Id))
                    {
                        continue;
                    }
                    if (e.To.IsTerminal && e.From.IsTerminal)
                    {
                        forcedEdges.Add(e);
                    }
                    Union(e.From.Id, e.To.Id);
                }

                if (Debug)
                {
                    Console.WriteLine("Forced: " + forcedEdges.Count);
                }

                // Use Dreyfus-Wagner or Erickson-Monma-Veinott if FPT (in nubmer of terminals) is faster than treewidth DP
                if (Math.Pow(5.0, decomposition.Width - Math.Log(1000000, 5.0)) > Math.Pow(3.0, g.Vertices.Where((v) => v.IsTerminal).Count() - forcedEdges.Count - Math.Log(1000000, 3.0)))
                {
                    foreach (Edge e in forcedEdges)
                    {
                        if (e.From.IsTerminal)
                        {
                            e.From.IsTerminal = false;
                        }
                        else
                        {
                            e.To.IsTerminal = false;
                        }
                        e.From.Adj.Add(new Edge(e.From, e.To, 0));
                        e.To.Adj.Add(new Edge(e.To, e.From, 0));
                    }

                    //new DreyfusWagner(g, forcedEdges).Solve();
                    new EricksonMonmaVeinott(g, forcedEdges).Solve();

                    if (Debug)
                    {
                        Console.WriteLine(sw.ElapsedMilliseconds);
                        //continue; // Should be commented out when Debug is false
                    }

                    return;
                }

                XORCount = 0; TableCount = 0; GenerateCount = 0;

                // Actually run the DP algorithm
                decomposition.FindOptimalRoot();
                SteinerAlgorithm algo = new SteinerAlgorithm();
                Dictionary <int, Dictionary <PartialSolution, int> > result = decomposition.Compute(algo);
                if (Debug)
                {
                    algo.Diagnostics();
                }

                // Find best solution
                int bestVal = int.MaxValue; PartialSolution bestSol = new PartialSolution();
                foreach (Dictionary <PartialSolution, int> table in result.Values)
                {
                    foreach (KeyValuePair <PartialSolution, int> kvp in table)
                    {
                        if (kvp.Value >= bestVal || kvp.Key.CountComponents() > 1)
                        {
                            continue;
                        }

                        bestVal = kvp.Value;
                        bestSol = kvp.Key;
                    }
                }

                if (bestVal == int.MaxValue)
                {
                    Console.WriteLine("Impossible");
                }
                else
                {
                    if (Debug)
                    {
                        Console.Write(Math.Round(sw.ElapsedMilliseconds / 1000.0, 1) + "s\tSolutions: {0}\tRows Generated: {1}\tXORCount: {2}\t", TableCount, GenerateCount, XORCount);
                    }

                    Console.WriteLine("VALUE " + bestVal);

                    if (Debug)
                    {
                        Console.WriteLine();
                    }

                    // Reconstruct subset of vertices
                    HashSet <int>        solution = new HashSet <int>();
                    Stack <VertexSubset> subsets  = new Stack <VertexSubset>();
                    subsets.Push(bestSol.Subset);
                    while (subsets.Count > 0)
                    {
                        VertexSubset subset = subsets.Pop();
                        if (subset == null || subset.ParentBag == null)
                        {
                            continue;
                        }
                        subsets.Push(subset.Left); subsets.Push(subset.Right);

                        foreach (Vertex v in subset.ParentBag.Bag)
                        {
                            if ((subset.LocalSubset & (1 << v.Color)) != 0)
                            {
                                solution.Add(v.Id);
                            }
                        }
                    }

                    InitUF(g);

                    // Compute MST on vertex set
                    int total = 0; int count = 0;
                    foreach (Edge e in g.Edges.OrderBy((e) => e.Weight).ThenBy((e) => Math.Min(e.To.Id, e.From.Id)).ThenBy((e) => Math.Max(e.To.Id, e.From.Id)))
                    {
                        if (!solution.Contains(e.To.Id) || !solution.Contains(e.From.Id))
                        {
                            continue;
                        }
                        if (Find(e.To.Id) == Find(e.From.Id))
                        {
                            continue;
                        }
                        Union(e.To.Id, e.From.Id);
                        if (!Debug)
                        {
                            Console.WriteLine(Math.Min((e.From.Id + 1), (e.To.Id + 1)) + " " + Math.Max((e.From.Id + 1), (e.To.Id + 1)));
                        }
                        total += e.Weight;
                        count++;
                    }
                }
            }

            if (Debug)
            {
                Console.ReadLine();
            }
        }
Esempio n. 8
0
 public bool AddSolution(PartialSolution s)
 {
     return(AddSolution(s, GetColumn(s)));
 }