コード例 #1
0
        // Parses a tree decomposition for a graph g, reading the input from a specific streamreader sr
        // Format: https://pacechallenge.wordpress.com/pace-2016/track-a-treewidth/
        public static TreeDecomposition Parse(TextReader sr, Graph g)
        {
            TreeDecomposition td = null;

            for (string line = sr.ReadLine(); line != "END" && line != null; 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;

            // Find a (tw+1)-coloring for g
            td.Nodes[0].ColorVertices(null);

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

            return(td);
        }
コード例 #2
0
 public TDNode(int n, TreeDecomposition ParentDecomposition, int w)
 {
     this.ParentDecomposition = ParentDecomposition;
     Bag           = new Vertex[n];
     VertexByColor = new Vertex[w];
 }
コード例 #3
0
        static void Main(string[] args)
        {
            ///*
            Graph             g  = Graph.ParsePACE2016(new StreamReader("../../../../instances/911network.gr"));
            TreeDecomposition td = TreeDecomposition.Parse(new StreamReader("../../../../instances/911network.td"), g);//*/

            /*
             * StreamReader sr = new StreamReader("../../../../instances/pace/instance070.gr");
             * Graph g = Graph.ParsePACE2018(sr);
             * TreeDecomposition td = TreeDecomposition.Parse(sr, g);//*/

            ShapleyAlgorithm algo = new ShapleyAlgorithm();
            Dictionary <Tuple <TDNode, TDNode>, Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > > lookup = new Dictionary <Tuple <TDNode, TDNode>, Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > >();

            Stopwatch sw = new Stopwatch();

            sw.Start();

            // We need to run the computation with different bags as root
            // Such that each vertex occurs in at least one such root bag
            // Greedily find a set cover
            Dictionary <Vertex, Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > > results = new Dictionary <Vertex, Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > >();
            PriorityQueue <TDNode> pq = new PriorityQueue <TDNode>();

            pq.Enqueue(td.Nodes.First((z) => z.Bag.Contains(g.Vertices[0])), 1);

            foreach (TDNode t in td.Nodes)
            {
                pq.Enqueue(t, -t.Bag.Length);
            }

            while (!pq.IsEmpty())
            {
                int    count        = (int)(-pq.PeekDist());
                TDNode cur          = pq.Dequeue();
                int    currentCount = cur.Bag.Where((v) => !results.ContainsKey(v)).Count();
                if (currentCount == 0)
                {
                    continue;
                }
                if (currentCount != count)
                {
                    pq.Enqueue(cur, -currentCount);
                    continue;
                }

                Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > result = cur.Compute(algo, null, lookup);

                foreach (Vertex v in cur.Bag)
                {
                    results[v] = result;
                }

                Console.WriteLine(results.Count + " / " + g.Vertices.Length);
            }

            sw.Stop();

            BigInteger[][] IncludingVertexCount = new BigInteger[g.Vertices.Length][], ExcludingVertexCount = new BigInteger[g.Vertices.Length][];
            BigInteger[][] IncludingVertexValue = new BigInteger[g.Vertices.Length][], ExcludingVertexValue = new BigInteger[g.Vertices.Length][];

            int n = g.Vertices.Length;

            for (int i = 0; i < n; i++)
            {
                Dictionary <int, Dictionary <int, Dictionary <PartialSolution, SolutionValue> > > table = results[g.Vertices[i]];

                BigInteger[] includingCount = new BigInteger[n + 1], excludingCount = new BigInteger[n + 1];
                BigInteger[] includingValue = new BigInteger[n + 1], excludingValue = new BigInteger[n + 1];

                for (int j = 0; j <= n; j++)
                {
                    includingCount[j] = new BigInteger(0);
                    excludingCount[j] = new BigInteger(0);

                    includingValue[j] = new BigInteger(0);
                    excludingValue[j] = new BigInteger(0);
                }

                foreach (var(subset, subsetTable) in table)
                {
                    foreach (var(size, sizeTable) in subsetTable)
                    {
                        foreach (var(partition, partitionValue) in sizeTable)
                        {
                            if (subset == 0 || partition.CountComponents(subset) == 1)
                            {
                                if ((subset & (1 << g.Vertices[i].Color)) != 0)
                                {
                                    //Console.WriteLine("Size {0} including {1} total number {2}", size, i, partitionValue.TotalNumber);
                                    includingCount[size] += partitionValue.TotalNumber;
                                    includingValue[size] += partitionValue.TotalValue;
                                }
                                else
                                {
                                    //Console.WriteLine("Size {0} excluding {1} total number {2}", size, i, partitionValue.TotalNumber);
                                    excludingCount[size] += partitionValue.TotalNumber;
                                    excludingValue[size] += partitionValue.TotalValue;
                                }
                            }
                        }
                    }
                }

                BigInteger unweighted = 0;
                BigInteger weighted   = 0;

                for (int s = 1; s < n; s++)
                {
                    // How much can be gained by adding i to a coalition of size s?
                    BigInteger fac1 = Factorial(s), fac2 = Factorial(n - s - 1);
                    unweighted += (includingCount[s + 1] - (s == 1 ? 0 : excludingCount[s])) * fac1 * fac2;
                    weighted   += (includingValue[s + 1] - excludingValue[s]) * fac1 * fac2;
                }

                unweighted *= 10000000000000000000;
                weighted   *= 10000000000000000000;
                BigInteger nFac = Factorial(n);

                unweighted /= nFac;
                weighted   /= nFac;

                Console.WriteLine("Vertex {0} unweighted: {1}, weighted: {2}", i + 1, Math.Round(((double)unweighted) / 10000000000000000000.0, 9), Math.Round(((double)weighted) / 10000000000000000000.0, 9));
            }

            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }