//search all partitions
        private Coalition[] searchSpace(ArrayList a)
        {
            var vcs = ValueOfCoalitionStructure(cs);

            while (setG.Count != 0 && !stop)
            {
                Console.WriteLine(setG.Count);
                var gIndex = select(maxOfSetG);
                var g      = (int[])setG[gIndex];
                var newCS  = searchList(g, maxOfSetG[gIndex]);

                setG.RemoveAt(gIndex);
                maxOfSetG.RemoveAt(gIndex);
                avgOfSetG.RemoveAt(gIndex);

                if (newCS != cs)
                {
                    cs  = newCS;
                    vcs = ValueOfCoalitionStructure(cs);
                    PruneResult pruneResult = prune(setG, maxOfSetG, avgOfSetG, vcs);
                    setG      = pruneResult.setG;
                    maxOfSetG = pruneResult.maxOfSetG;
                    avgOfSetG = pruneResult.avgOfSetG;
                }
                if (setG.Count > 0)
                {
                    ub = Math.Max(vcs, maxOfSetG.Max()); // new upper bound
                    if (vcs != 0)
                    {
                        beta = Math.Min(ub / vcs, beta);           //new bound on quality
                    }
                }
                else
                {
                    ub = vcs;
                    if (vcs != 0)
                    {
                        beta = (ub / vcs);
                    }
                }
            }
            return(cs);
        }
        private PruneResult prune(List <int[]> setG, List <Double> maxg, List <Double> avgg, Double v)
        {
            var i = 0;

            while (i < setG.Count)
            {
                if (maxg[i] <= v)
                {
                    setG.RemoveAt(i);
                    maxg.RemoveAt(i);
                    avgg.RemoveAt(i);
                }
                else
                {
                    i++;
                }
            }
            var result = new PruneResult();

            result.setG      = setG;
            result.avgOfSetG = avgg;
            result.maxOfSetG = maxg;
            return(result);
        }
        private void scanAndSearch()
        {
            //Pi = coalitions structures which contains i coalition
            var valueOfP1 = ValueOfCoalitionStructure(l[0]);
            var valueOfPn = ValueOfCoalitionStructure(l[n - 1]);

            cs = l[0];           //best coalition structure found so far
            var vcs = valueOfP1; //value of best coalition structure found so far

            if (valueOfP1 < valueOfPn)
            {
                cs  = l[n - 1];
                vcs = valueOfPn;
            }
            addtoFoundStructures();
            var maxs = new Double[n];        //maximum value of l[s]
            var avgs = new Double[n];        //average value of l[s]
            var sums = new Double[n];        //sum value of l[s]
            var vmax = Double.MinValue;      //maximum of current coalitions structure formed by 2 complementary coalitions
            var xmax = 0;                    // index of vmax

            for (var s = 1; s <= n / 2; s++) //scan all complementary coalitions
            {
                Console.WriteLine(s);
                var s1  = s - 1;
                var s2  = (n - s) - 1;
                var end = l[s1].Length; // length of coalitions containing s player
                if (s1 == s2)           //same list
                {
                    end = end / 2;
                }
                maxs[s1] = Double.MinValue;
                maxs[s2] = Double.MinValue;
                sums[s1] = 0;
                for (var x = 1; x <= end; x++)
                {
                    var x1 = x - 1;
                    var x2 = (l[s1].Length - x + 1) - 1;
                    var v1 = l[s1][x1].getMaximumValue(); //value of coalition ls1x1
                    var v2 = l[s2][x2].getMaximumValue(); //value of coalition ls2x2
                    if (vmax < v1 + v2)
                    {
                        vmax = v1 + v2;
                        xmax = x;
                    }
                    if (maxs[s1] < v1)
                    {
                        maxs[s1] = v1;
                    }
                    if (maxs[s2] < v2)
                    {
                        maxs[s2] = v2;
                    }
                    sums[s1] += v1;
                    sums[s2] += v2;
                    if (stop)
                    {
                        return;
                    }
                }
                var xmax1      = xmax - 1;
                var xmax2      = (l[s1].Length - xmax + 1) - 1;
                var currentCS  = new Coalition[] { l[s1][xmax1], l[s2][xmax2] }; // create coalition Structure of the 2 complementary coalitions
                var vcurrentCS = ValueOfCoalitionStructure(currentCS);           //value of currentCS
                if (vcs < vcurrentCS)                                            // found a new best coalition structure
                {
                    cs = currentCS;
                    addtoFoundStructures();
                    vcs = vcurrentCS;
                }
                avgs[s1] = sums[s1] / l[s1].Length;
                avgs[s2] = sums[s2] / l[s2].Length;
                if (stop)
                {
                    return;
                }
            }
            setG = generateNumbersAllPartitionExcept(n, 2);
            var xxxxx = setG.Count;

            //set of possible integer partitions of n except that contains 2 parts(because we just scanned them)
            maxOfSetG = new List <Double>();
            avgOfSetG = new List <Double>();
            for (var i = 0; i < setG.Count; i++)
            {
                int[]  g    = (int[])setG[i];
                Double maxg = 0;
                Double avgg = 0;
                for (var j = 0; j < g.Length; j++)
                {
                    maxg += maxs[g[j] - 1];
                    avgg += avgs[g[j] - 1];
                    if (stop)
                    {
                        return;
                    }
                }
                maxOfSetG.Add(maxg);
                avgOfSetG.Add(avgg);
                if (stop)
                {
                    return;
                }
            }
            var         ub          = Math.Max(vcs, maxOfSetG.Max()); //calculate upper bound
            var         lb          = Math.Max(vcs, avgOfSetG.Max()); //calculate lower bound
            PruneResult pruneResult = prune(setG, maxOfSetG, avgOfSetG, lb);

            setG = pruneResult.setG;
            var lx = setG.Count;

            maxOfSetG = pruneResult.maxOfSetG;
            avgOfSetG = pruneResult.avgOfSetG;
            if (vcs != 0)
            {
                beta = Math.Min(n / 2, ub / vcs);
            }
        }
 private PruneResult prune(List<int[]> setG, List<Double> maxg, List<Double> avgg, Double v)
 {
     var i = 0;
     while (i < setG.Count)
     {
         if (maxg[i] <= v)
         {
             setG.RemoveAt(i);
             maxg.RemoveAt(i);
             avgg.RemoveAt(i);
         }
         else
         {
             i++;
         }
     }
     var result = new PruneResult();
     result.setG = setG;
     result.avgOfSetG = avgg;
     result.maxOfSetG = maxg;
     return result;
 }