Exemple #1
0
        // Parses a tree decomposition for a graph g, reading the input from a specific streamreader sr
        public static TreeDecomposition Parse(TextReader sr, Graph g)
        {
            TreeDecomposition td = null;

            for (string line = sr.ReadLine(); line != "END"; line = sr.ReadLine())
            {
                string[] cf = line.Split();
                if (cf[0] == "s")
                {
                    td = new TreeDecomposition(int.Parse(cf[2]), int.Parse(cf[3]));
                }
                else if (cf[0] == "b")
                {
                    TDNode newNode = new TDNode(cf.Length - 2, td, td.Width);
                    for (int i = 2; i < cf.Length; i++)
                    {
                        newNode.Bag[i - 2] = g.Vertices[int.Parse(cf[i]) - 1];
                    }
                    td.Nodes[int.Parse(cf[1]) - 1] = newNode;
                }
                else
                {
                    try
                    {
                        int a = int.Parse(cf[0]);
                        int b = int.Parse(cf[1]);
                        td.Nodes[a - 1].Adj.Add(td.Nodes[b - 1]);
                        td.Nodes[b - 1].Adj.Add(td.Nodes[a - 1]);
                    }
                    catch
                    { }
                }
            }

            td.ParentGraph = g;

            td.Nodes[0].ColorVertices();

            if (Program.Debug)
            {
                Console.WriteLine("Bags: {0} - Join Bags: {1} - Width: {2} - Vertices: {3} - Terminals: {4}", td.Nodes.Count, td.Nodes.Where((n) => n.Adj.Count > 2).Count(), td.Width, g.Vertices.Length, g.Vertices.Where((v) => v.IsTerminal).Count());
            }

            return(td);
        }
Exemple #2
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();
            }
        }
Exemple #3
0
 public TDNode(int n, TreeDecomposition ParentDecomposition, int w)
 {
     this.ParentDecomposition = ParentDecomposition;
     Bag           = new Vertex[n];
     VertexByColor = new Vertex[w];
 }