public void GA1_DoWork(object sender, DoWorkEventArgs e)
 {
     try
     {
         watch.Start();
         for (int gen = 0; gen < generations; gen++)//generations
         {
             if (GA1.CancellationPending == true)
             {
                 return;
             }
             etilism1();//etilism
             for (int i = 2; i < popsize; i += 2)
             {
                 genome   parent1  = selection1();                //select parent1
                 genome   parent2  = selection1();                //select parent2
                 genome[] children = crossover(parent1, parent2); //crossover
                 children[0] = mutate(children[0]);               //mutate 1st child
                 children[1] = mutate(children[1]);               //mutate 2nd child
                 storenewpop1(children[0]);                       //store 1st child
                 storenewpop1(children[1]);                       //store 2nd child
             }
             setcurrpop1();
             GA1.ReportProgress(gen, PresentPopData1);
             Thread.Sleep(pause);
         }
         bestsoln1();
     }
     catch (Exception f)
     {
         MessageBox.Show(f.Message, "Something went wrong", MessageBoxButton.OK);
     }
 }
        //crossover
        private genome[] crossover(genome parent1, genome parent2)
        {
            Random k = new Random();
            int    h = k.Next(1, this.cities.Count - 2);

            genome[] children = new genome[2];
            children[0] = new genome();
            children[1] = new genome();
            if (crossoverrandom.NextDouble() < crossoverrate)
            {
                for (int i = 0; i < h; i++)//copy first parts of parent 1 to child 1
                {
                    children[0].order.Add(parent1.order[i]);
                }
                for (int i = h; i < this.cities.Count; i++)//copy second part of parent 2 to child 2
                {
                    children[1].order.Add(parent2.order[i]);
                }
                for (int i = 0; i < parent2.order.Count; i++)    //fill up child 1
                {
                    bool found = false;
                    for (int j = 0; j < children[0].order.Count; j++)
                    {
                        if (parent2.order[i] == children[0].order[j])
                        {
                            found = true;
                            break;
                        }
                    }
                    if (found == false)
                    {
                        children[0].order.Add(parent2.order[i]);
                    }
                }
                for (int i = 0; i < parent1.order.Count; i++)//fill up child 2
                {
                    bool found = false;
                    for (int j = 0; j < children[1].order.Count; j++)
                    {
                        if (parent1.order[i] == children[1].order[j])
                        {
                            found = true;
                            break;
                        }
                    }
                    if (found == false)
                    {
                        children[1].order.Add(parent1.order[i]);
                    }
                }
                return(children);
            }
            else
            {
                children[0] = parent1;
                children[1] = parent2;
                return(children);
            }
        }
        //select random start population
        private void startpop1()
        {
            PresentPopData1.Clear();
            NewPopData1.Clear();
            genome g = new genome();

            for (int i = 0; i < this.cities.Count; i++)
            {
                g.order.Add(i);
            }
            g.distance = genomefitness(g);
            g.makestring();
            PresentPopData1.Add(g);
            g          = null;
            g          = new genome();
            g.distance = 0;
            if (this.cities.Count % 2 == 0)
            {
                for (int i = this.cities.Count / 2; i < this.cities.Count; i++)
                {
                    g.order.Add(i);
                }
                for (int i = (this.cities.Count / 2) - 1; i > -1; i--)
                {
                    g.order.Add(i);
                }
            }
            else
            {
                for (int i = this.cities.Count + 1 / 2; i < this.cities.Count; i++)
                {
                    g.order.Add(i);
                }
                for (int i = (this.cities.Count + 1 / 2) - 1; i > -1; i--)
                {
                    g.order.Add(i);
                }
            }
            g.makestring();
            g.distance = genomefitness(g);
            PresentPopData1.Add(g);
            Random m = new Random();

            for (int i = 2; i < popsize; i++)
            {
                g = new genome();
                int[] array = randomarray(m);
                for (int k = 0; k < this.cities.Count; k++)
                {
                    g.order.Add(array[k]);
                }
                g.distance = genomefitness(g);
                g.makestring();
                PresentPopData1.Add(g);
            }
        }
        //get total distance of a genome
        private int genomefitness(genome h)
        {
            int m = 0;

            for (int i = 0; i < this.cities.Count; i++)
            {
                if (i + 1 == this.cities.Count)
                {
                    m += distances[h.order[i], h.order[0]];
                    break;
                }
                m += distances[h.order[i], h.order[i + 1]];
            }
            return(m);
        }
 void GA_DoWork(object sender, DoWorkEventArgs e)
 {
     try
     {
         for (int gen = 0; gen < generations; gen++)//generations
         {
             if (GA.CancellationPending)
             {
                 break;
             }
             while (NewPopData.Count > 0)
             {
                 NewPopData.Clear();
             }
             etilism();//etilism
             for (int i = 2; i < popsize; i += 2)
             {
                 genome   parent1  = selection();                 //select parent1
                 genome   parent2  = selection();                 //select parent2
                 genome[] children = crossover(parent1, parent2); //crossover
                 children[0] = mutate(children[0]);               //mutate 1st child
                 children[1] = mutate(children[1]);               //mutate 2nd child
                 storenewpop(children[0]);                        //store 1st child
                 storenewpop(children[1]);                        //store 2nd child
                 Thread.Sleep(pause);
             }
             while (PresentPopData.Count > 0)
             {
                 PresentPopData.Clear();
             }
             setcurrpop();
             while (NewPopData.Count > 0)
             {
                 NewPopData.Clear();
             }
             bestsoln();
             this.GA.ReportProgress(gen);
             Thread.Sleep(pause);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Please run this input set without visualization" + " " + ex.Message, "Alert", MessageBoxButton.OK);
     }
 }
        //mutate
        private genome mutate(genome child)
        {
            Random d    = new Random();
            int    num1 = d.Next(0, child.order.Count - 1);
            int    num2 = 0;

            do
            {
                num2 = d.Next(0, child.order.Count - 1);
            } while (num1 == num2);
            if (mutaterandom.NextDouble() < mutationrate)
            {
                int temp = child.order[num1];
                child.order[num1] = child.order[num2];
                child.order[num2] = temp;
            }
            child.distance = genomefitness(child);
            child.makestring();
            return(child);
        }
 //store to new population
 private void storenewpop1(genome newgenome)
 {
     NewPopData1.Add(newgenome);
 }