示例#1
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();
        }