public Individual Recombine(Individual b)
        {
            Individual res = null;

            do
                try
                {
                    bool[] a_genes = new bool[fe.n];
                    foreach (int i in genes)
                        a_genes[i] = true;
                    bool[] b_genes = new bool[b.fe.n];
                    foreach (int i in b.genes)
                        b_genes[i] = true;

                    int s = prms.rand.Next(fe.n), t = prms.rand.Next(fe.n);
                    int gen;
                    for (int i = 0; i < t; ++i)
                    {
                        gen = (s + i) % fe.n;
                        a_genes[gen] ^= b_genes[gen];
                        b_genes[gen] ^= a_genes[gen];
                        a_genes[gen] ^= b_genes[gen];
                    }

                    List<int> new_genes = new List<int>();
                    for (int i = 0; i < fe.n; ++i)
                        if (a_genes[i])
                            new_genes.Add(i);

                    res = new Individual(new_genes, fe, prms);
                }
                catch (CalculationException e) { }
            while (res == null);
            return res;
        }
 public static Individual RandomIndividual(FitnessEstimator fe, double density, EvolutionParams prms)
 {
     Individual res = null;
     do
         try
         {
             List<int> r = new List<int>();
             for (int i = 0; i < fe.n; ++i)
                 if (prms.rand.NextDouble() < density)
                     r.Add(i);
             res = new Individual(r, fe, prms);
         }
         catch (CalculationException e) { }
     while (res == null);
     return res;
 }
        public Individual Mutate()
        {
            Individual res = null;
            do
                try
                {
                    bool[] gene_array = new bool[fe.n];
                    foreach (int i in genes)
                        gene_array[i] = true;

                    List<int> new_genes = new List<int>();
                    for (int i = 0; i < fe.n; ++i)
                    {
                        if (gene_array[i])
                        {
                            if (prms.rand.NextDouble() >= prms.mut_rate_deact)
                                new_genes.Add(i);
                        }
                        else
                        {
                            if (!too_many_genes && prms.rand.NextDouble() < prms.mut_rate_act)
                                new_genes.Add(i);
                        }
                    }
                    res = new Individual(new_genes, fe, prms);
                }
                catch (CalculationException e) { }
            while (res == null);
            return res;
        }
        public static void Optimize(double[,] S, bool[] rev, bool increase, LinkedList<FluxPattern> witnesses, FluxPattern max, FluxPattern frev, IIntCoupling coupling, List<int> R0, List<int> Rb, bool lp, double max_value, double tolerance, bool output, int population_size, int generations, double recomb_rate, double mut_rate_act, double mut_rate_deact, double start_density, out LinkedList<String> dot_tree)
        {
            IIntFCACalculator<FluxPattern> fcacalculator = lp ? (IIntFCACalculator<FluxPattern>)new LPIntFCACalculator(S, rev, max_value, tolerance) : (IIntFCACalculator<FluxPattern>)new MILPIntFCACalculator(S, rev, max_value, tolerance);
            FitnessEstimator fe = new FitnessEstimator(R0, Rb, increase, rev.Length, fcacalculator, witnesses, max, frev, coupling);

            List<int> approximation = null;
            FluxPattern max_approx = null;

            if (population_size > 0)
            {
                Population population = new Population(fe, population_size, recomb_rate, mut_rate_act, mut_rate_deact, start_density);

                for (int i = 1; i < generations; ++i)
                    population.evolve();

                Individual best = population.FittestIndividual;
                if (best.Fitness < 0)
                {
                    approximation = best.Genes;
                    max_approx = best.Max;
                }
            }

            OptimizationTree tree = new OptimizationTree(fe, R0, Rb, approximation, max_approx, output);

            dot_tree = tree.DotTree;
            LinkedList<List<int>> opt_solutions = tree.OptGenes;

            Console.WriteLine("\n\n\nThere are {0} optimal solutions.\n\t{1} reactions are unblocked.\n\tYou have to use {2} drugs.", opt_solutions.Count, tree.OptMaxSize, tree.OptRSize);

            if (opt_solutions.Count > 0)
            {
                Individual opt = new Individual(opt_solutions.First.Value, fe, new EvolutionParams());
                Console.WriteLine("\n\tOne optimal solution is: {0}", opt);
            }

            Console.WriteLine("\n\tI had to calculate {0} out of {1} maxima to find the optima.", tree.NumberNodes, ((long)1) << Rb.Count());
        }