Roulette Selection in Genetic Algorithms












35















Can anyone provide some pseudo code for a roulette selection function? How would I implement this:



alt text



I don't really understand how to read this math notation. I never took any probability or statistics.










share|improve this question




















  • 3





    The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

    – rampion
    May 16 '09 at 16:56






  • 1





    @rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

    – jkp
    Dec 23 '10 at 10:37











  • does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

    – mkuse
    Jan 4 '13 at 7:05











  • obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

    – fangmobile.com
    May 3 '15 at 5:49
















35















Can anyone provide some pseudo code for a roulette selection function? How would I implement this:



alt text



I don't really understand how to read this math notation. I never took any probability or statistics.










share|improve this question




















  • 3





    The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

    – rampion
    May 16 '09 at 16:56






  • 1





    @rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

    – jkp
    Dec 23 '10 at 10:37











  • does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

    – mkuse
    Jan 4 '13 at 7:05











  • obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

    – fangmobile.com
    May 3 '15 at 5:49














35












35








35


23






Can anyone provide some pseudo code for a roulette selection function? How would I implement this:



alt text



I don't really understand how to read this math notation. I never took any probability or statistics.










share|improve this question
















Can anyone provide some pseudo code for a roulette selection function? How would I implement this:



alt text



I don't really understand how to read this math notation. I never took any probability or statistics.







genetic-algorithm evolutionary-algorithm roulette-wheel-selection






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 8 '17 at 14:08









Community

11




11










asked Oct 7 '08 at 4:56









Sam McAfeeSam McAfee

5,717134963




5,717134963








  • 3





    The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

    – rampion
    May 16 '09 at 16:56






  • 1





    @rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

    – jkp
    Dec 23 '10 at 10:37











  • does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

    – mkuse
    Jan 4 '13 at 7:05











  • obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

    – fangmobile.com
    May 3 '15 at 5:49














  • 3





    The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

    – rampion
    May 16 '09 at 16:56






  • 1





    @rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

    – jkp
    Dec 23 '10 at 10:37











  • does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

    – mkuse
    Jan 4 '13 at 7:05











  • obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

    – fangmobile.com
    May 3 '15 at 5:49








3




3





The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

– rampion
May 16 '09 at 16:56





The denominator is just a sum : SUM(f_j for j=1 upto N). This just says that the probability p_i of choosing item i is just its fitness f_i over the sum of all fitnesses.

– rampion
May 16 '09 at 16:56




1




1





@rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

– jkp
Dec 23 '10 at 10:37





@rampion: thanks. this kind of notation makes my head spin but I had guessed correctly and your explanation confirmed it :)

– jkp
Dec 23 '10 at 10:37













does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

– mkuse
Jan 4 '13 at 7:05





does anyone know if the above formula is valid even when the f_i values (ie. fitness values) are negative?

– mkuse
Jan 4 '13 at 7:05













obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

– fangmobile.com
May 3 '15 at 5:49





obviously not valid if you have negative fitness value. Your sum could be zero when you have both positive and negative.

– fangmobile.com
May 3 '15 at 5:49












13 Answers
13






active

oldest

votes


















37














It's been a few years since i've done this myself, however the following pseudo code was found easily enough on google.




for all members of population
sum += fitness of this individual
end for

for all members of population
probability = sum of probabilities + (fitness / sum)
sum of probabilities += probability
end for

loop until new population is full
do this twice
number = Random between 0 and 1
for all members of population
if number > probability but less than next probability
then you have been selected
end for
end
create offspring
end loop


The site where this came from can be found here if you need further details.






share|improve this answer





















  • 2





    You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

    – rampion
    May 16 '09 at 16:54






  • 9





    Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

    – gpampara
    Feb 13 '10 at 6:45






  • 1





    Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

    – user1032613
    Feb 4 '13 at 22:26






  • 1





    @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

    – user1520427
    May 20 '13 at 0:10






  • 4





    @Jarod Elliott do the population fitnesses need to be sorted in this example?

    – CatsLoveJazz
    Jun 22 '16 at 14:47





















15














Lots of correct solutions already, but I think this code is clearer.



def select(fs):
p = random.uniform(0, sum(fs))
for i, f in enumerate(fs):
if p <= 0:
break
p -= f
return i


In addition, if you accumulate the fs, you can produce a more efficient solution.



cfs = [sum(fs[:i+1]) for i in xrange(len(fs))]

def select(cfs):
return bisect.bisect_left(cfs, random.uniform(0, cfs[-1]))


This is both faster and it's extremely concise code. STL in C++ has a similar bisection algorithm available if that's the language you're using.






share|improve this answer



















  • 1





    That solution is not just shorter than my code but also clearer and more efficient. (Y)

    – noio
    Jan 29 '12 at 11:08






  • 6





    It would really help if these variables had english names

    – Tyrsius
    Oct 8 '15 at 17:37



















12














The pseudocode posted contained some unclear elements, and it adds the complexity of generating offspring in stead of performing pure selection. Here is a simple python implementation of that pseudocode:



def roulette_select(population, fitnesses, num):
""" Roulette selection, implemented according to:
<http://stackoverflow.com/questions/177271/roulette
-selection-in-genetic-algorithms/177278#177278>
"""
total_fitness = float(sum(fitnesses))
rel_fitness = [f/total_fitness for f in fitnesses]
# Generate probability intervals for each individual
probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
# Draw new population
new_population =
for n in xrange(num):
r = rand()
for (i, individual) in enumerate(population):
if r <= probs[i]:
new_population.append(individual)
break
return new_population





share|improve this answer































    8














    This is called roulette-wheel selection via stochastic acceptance:



    /// param[in] f_max maximum fitness of the population
    ///
    /// return index of the selected individual
    ///
    /// note Assuming positive fitness. Greater is better.

    unsigned rw_selection(double f_max)
    {
    for (;;)
    {
    // Select randomly one of the individuals
    unsigned i(random_individual());

    // The selection is accepted with probability fitness(i) / f_max
    if (uniform_random_01() < fitness(i) / f_max)
    return i;
    }
    }


    The average number of attempts needed for a single selection is:



    τ = fmax / avg(f)




    • fmax is the maximum fitness of the population

    • avg(f) is the average fitness


    τ doesn't depend explicitly on the number of individual in the population (N), but the ratio can change with N.



    However in many application (where the fitness remains bounded and the average fitness doesn't diminish to 0 for increasing N) τ doesn't increase unboundedly with N and thus a typical complexity of this algorithm is O(1) (roulette wheel selection using search algorithms has O(N) or O(log N) complexity).



    The probability distribution of this procedure is indeed the same as in the classical roulette-wheel selection.



    For further details see:





    • Roulette-wheel selection via stochastic acceptance (Adam Liposki, Dorota Lipowska - 2011)






    share|improve this answer

































      5














      Here is some code in C :



      // Find the sum of fitnesses. The function fitness(i) should 
      //return the fitness value for member i**

      float sumFitness = 0.0f;
      for (int i=0; i < nmembers; i++)
      sumFitness += fitness(i);

      // Get a floating point number in the interval 0.0 ... sumFitness**
      float randomNumber = (float(rand() % 10000) / 9999.0f) * sumFitness;

      // Translate this number to the corresponding member**
      int memberID=0;
      float partialSum=0.0f;

      while (randomNumber > partialSum)
      {
      partialSum += fitness(memberID);
      memberID++;
      }

      **// We have just found the member of the population using the roulette algorithm**
      **// It is stored in the "memberID" variable**
      **// Repeat this procedure as many times to find random members of the population**





      share|improve this answer


























      • Should the members be sorted?

        – Zimano
        Oct 24 '16 at 16:38



















      1














      From the above answer, I got the following, which was clearer to me than the answer itself.



      To give an example:



      Random(sum) :: Random(12)
      Iterating through the population, we check the following: random < sum



      Let us chose 7 as the random number.



      Index   |   Fitness |   Sum |   7 < Sum
      0 | 2 | 2 | false
      1 | 3 | 5 | false
      2 | 1 | 6 | false
      3 | 4 | 10 | true
      4 | 2 | 12 | ...


      Through this example, the most fit (Index 3) has the highest percentage of being chosen (33%); as the random number only has to land within 6->10, and it will be chosen.



          for (unsigned int i=0;i<sets.size();i++) {
      sum += sets[i].eval();
      }
      double rand = (((double)rand() / (double)RAND_MAX) * sum);
      sum = 0;
      for (unsigned int i=0;i<sets.size();i++) {
      sum += sets[i].eval();
      if (rand < sum) {
      //breed i
      break;
      }
      }





      share|improve this answer

































        1














        Prof. Thrun of Stanford AI lab also presented a fast(er?) re-sampling code in python during his CS373 of Udacity. Google search result led to the following link:



        http://www.udacity-forums.com/cs373/questions/20194/fast-resampling-algorithm



        Hope this helps






        share|improve this answer































          1














          Here's a compact java implementation I wrote recently for roulette selection, hopefully of use.



          public static gene rouletteSelection()
          {
          float totalScore = 0;
          float runningScore = 0;
          for (gene g : genes)
          {
          totalScore += g.score;
          }

          float rnd = (float) (Math.random() * totalScore);

          for (gene g : genes)
          {
          if ( rnd>=runningScore &&
          rnd<=runningScore+g.score)
          {
          return g;
          }
          runningScore+=g.score;
          }

          return null;
          }





          share|improve this answer































            1














            Roulette Wheel Selection in MatLab:



            TotalFitness=sum(Fitness);
            ProbSelection=zeros(PopLength,1);
            CumProb=zeros(PopLength,1);

            for i=1:PopLength
            ProbSelection(i)=Fitness(i)/TotalFitness;
            if i==1
            CumProb(i)=ProbSelection(i);
            else
            CumProb(i)=CumProb(i-1)+ProbSelection(i);
            end
            end

            SelectInd=rand(PopLength,1);

            for i=1:PopLength
            flag=0;
            for j=1:PopLength
            if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
            SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
            flag=1;
            break;
            end
            end
            if(flag==0)
            SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
            end
            end





            share|improve this answer































              0














              Based on my research ,Here is another implementation in C# if there is a need for it:


              //those with higher fitness get selected wit a large probability
              //return-->individuals with highest fitness
              private int RouletteSelection()
              {
              double randomFitness = m_random.NextDouble() * m_totalFitness;
              int idx = -1;
              int mid;
              int first = 0;
              int last = m_populationSize -1;
              mid = (last - first)/2;

              // ArrayList's BinarySearch is for exact values only
              // so do this by hand.
              while (idx == -1 && first <= last)
              {
              if (randomFitness < (double)m_fitnessTable[mid])
              {
              last = mid;
              }
              else if (randomFitness > (double)m_fitnessTable[mid])
              {
              first = mid;
              }
              mid = (first + last)/2;
              // lies between i and i+1
              if ((last - first) == 1)
              idx = last;
              }
              return idx;
              }





              share|improve this answer































                0














                Okay, so there are 2 methods for roulette wheel selection implementation: Usual and Stochastic Acceptance one.



                Usual algorithm:



                # there will be some amount of repeating organisms here.
                mating_pool =

                all_organisms_in_population.each do |organism|
                organism.fitness.times { mating_pool.push(organism) }
                end

                # [very_fit_organism, very_fit_organism, very_fit_organism, not_so_fit_organism]
                return mating_pool.sample #=> random, likely fit, parent!


                Stochastic Acceptance algorithm:



                max_fitness_in_population = all_organisms_in_population.sort_by(:fitness)[0]
                loop do
                random_parent = all_organisms_in_population.sample
                probability = random_parent.fitness/max_fitness_in_population * 100
                # if random_parent's fitness is 90%,
                # it's very likely that rand(100) is smaller than it.
                if rand(100) < probability
                return random_parent #=> random, likely fit, parent!
                else
                next #=> or let's keep on searching for one.
                end
                end


                You can choose either, they will be returning identical results.





                Useful resources:



                http://natureofcode.com/book/chapter-9-the-evolution-of-code - a beginner-friendly and clear chapter on genetic algorithms. explains roulette wheel selection as a bucket of wooden letters (the more As you put in - the great is the chance of picking an A, Usual algorithm).



                https://en.wikipedia.org/wiki/Fitness_proportionate_selection - describes Stochastic Acceptance algorithm.






                share|improve this answer































                  0














                  This Swift 4 array extension implements weighted random selection, a.k.a Roulette selection from its elements:



                  public extension Array where Element == Double {

                  /// Consider the elements as weight values and return a weighted random selection by index.
                  /// a.k.a Roulette wheel selection.
                  func weightedRandomIndex() -> Int {
                  var selected: Int = 0
                  var total: Double = self[0]

                  for i in 1..<self.count { // start at 1
                  total += self[i]
                  if( Double.random(in: 0...1) <= (self[i] / total)) { selected = i }
                  }

                  return selected
                  }
                  }


                  For example given the two element array:



                  [0.9, 0.1]


                  weightedRandomIndex() will return zero 90% of the time and one 10% of the time.



                  Here is a more complete test:



                  let weights = [0.1, 0.7, 0.1, 0.1]
                  var results = [Int:Int]()
                  let n = 100000
                  for _ in 0..<n {
                  let index = weights.weightedRandomIndex()
                  results[index] = results[index, default:0] + 1
                  }
                  for (key,val) in results.sorted(by: { a,b in weights[a.key] < weights[b.key] }) {
                  print(weights[key], Double(val)/Double(n))
                  }


                  output:



                  0.1 0.09906
                  0.1 0.10126
                  0.1 0.09876
                  0.7 0.70092


                  This answer is basically the same as Andrew Mao's answer here:
                  https://stackoverflow.com/a/15582983/74975






                  share|improve this answer

































                    -1














                    I wrote a version in C# and am really looking for confirmation that it is indeed correct:



                    (roulette_selector is a random number which will be in the range 0.0 to 1.0)



                    private Individual Select_Roulette(double sum_fitness)
                    {
                    Individual ret = new Individual();
                    bool loop = true;

                    while (loop)
                    {
                    //this will give us a double within the range 0.0 to total fitness
                    double slice = roulette_selector.NextDouble() * sum_fitness;

                    double curFitness = 0.0;

                    foreach (Individual ind in _generation)
                    {
                    curFitness += ind.Fitness;
                    if (curFitness >= slice)
                    {
                    loop = false;
                    ret = ind;
                    break;
                    }
                    }
                    }
                    return ret;

                    }





                    share|improve this answer























                      Your Answer






                      StackExchange.ifUsing("editor", function () {
                      StackExchange.using("externalEditor", function () {
                      StackExchange.using("snippets", function () {
                      StackExchange.snippets.init();
                      });
                      });
                      }, "code-snippets");

                      StackExchange.ready(function() {
                      var channelOptions = {
                      tags: "".split(" "),
                      id: "1"
                      };
                      initTagRenderer("".split(" "), "".split(" "), channelOptions);

                      StackExchange.using("externalEditor", function() {
                      // Have to fire editor after snippets, if snippets enabled
                      if (StackExchange.settings.snippets.snippetsEnabled) {
                      StackExchange.using("snippets", function() {
                      createEditor();
                      });
                      }
                      else {
                      createEditor();
                      }
                      });

                      function createEditor() {
                      StackExchange.prepareEditor({
                      heartbeatType: 'answer',
                      autoActivateHeartbeat: false,
                      convertImagesToLinks: true,
                      noModals: true,
                      showLowRepImageUploadWarning: true,
                      reputationToPostImages: 10,
                      bindNavPrevention: true,
                      postfix: "",
                      imageUploader: {
                      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                      allowUrls: true
                      },
                      onDemand: true,
                      discardSelector: ".discard-answer"
                      ,immediatelyShowMarkdownHelp:true
                      });


                      }
                      });














                      draft saved

                      draft discarded


















                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f177271%2froulette-selection-in-genetic-algorithms%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown

























                      13 Answers
                      13






                      active

                      oldest

                      votes








                      13 Answers
                      13






                      active

                      oldest

                      votes









                      active

                      oldest

                      votes






                      active

                      oldest

                      votes









                      37














                      It's been a few years since i've done this myself, however the following pseudo code was found easily enough on google.




                      for all members of population
                      sum += fitness of this individual
                      end for

                      for all members of population
                      probability = sum of probabilities + (fitness / sum)
                      sum of probabilities += probability
                      end for

                      loop until new population is full
                      do this twice
                      number = Random between 0 and 1
                      for all members of population
                      if number > probability but less than next probability
                      then you have been selected
                      end for
                      end
                      create offspring
                      end loop


                      The site where this came from can be found here if you need further details.






                      share|improve this answer





















                      • 2





                        You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                        – rampion
                        May 16 '09 at 16:54






                      • 9





                        Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                        – gpampara
                        Feb 13 '10 at 6:45






                      • 1





                        Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                        – user1032613
                        Feb 4 '13 at 22:26






                      • 1





                        @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                        – user1520427
                        May 20 '13 at 0:10






                      • 4





                        @Jarod Elliott do the population fitnesses need to be sorted in this example?

                        – CatsLoveJazz
                        Jun 22 '16 at 14:47


















                      37














                      It's been a few years since i've done this myself, however the following pseudo code was found easily enough on google.




                      for all members of population
                      sum += fitness of this individual
                      end for

                      for all members of population
                      probability = sum of probabilities + (fitness / sum)
                      sum of probabilities += probability
                      end for

                      loop until new population is full
                      do this twice
                      number = Random between 0 and 1
                      for all members of population
                      if number > probability but less than next probability
                      then you have been selected
                      end for
                      end
                      create offspring
                      end loop


                      The site where this came from can be found here if you need further details.






                      share|improve this answer





















                      • 2





                        You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                        – rampion
                        May 16 '09 at 16:54






                      • 9





                        Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                        – gpampara
                        Feb 13 '10 at 6:45






                      • 1





                        Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                        – user1032613
                        Feb 4 '13 at 22:26






                      • 1





                        @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                        – user1520427
                        May 20 '13 at 0:10






                      • 4





                        @Jarod Elliott do the population fitnesses need to be sorted in this example?

                        – CatsLoveJazz
                        Jun 22 '16 at 14:47
















                      37












                      37








                      37







                      It's been a few years since i've done this myself, however the following pseudo code was found easily enough on google.




                      for all members of population
                      sum += fitness of this individual
                      end for

                      for all members of population
                      probability = sum of probabilities + (fitness / sum)
                      sum of probabilities += probability
                      end for

                      loop until new population is full
                      do this twice
                      number = Random between 0 and 1
                      for all members of population
                      if number > probability but less than next probability
                      then you have been selected
                      end for
                      end
                      create offspring
                      end loop


                      The site where this came from can be found here if you need further details.






                      share|improve this answer















                      It's been a few years since i've done this myself, however the following pseudo code was found easily enough on google.




                      for all members of population
                      sum += fitness of this individual
                      end for

                      for all members of population
                      probability = sum of probabilities + (fitness / sum)
                      sum of probabilities += probability
                      end for

                      loop until new population is full
                      do this twice
                      number = Random between 0 and 1
                      for all members of population
                      if number > probability but less than next probability
                      then you have been selected
                      end for
                      end
                      create offspring
                      end loop


                      The site where this came from can be found here if you need further details.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Mar 20 '14 at 22:20









                      Ian Kemp

                      17.1k1270101




                      17.1k1270101










                      answered Oct 7 '08 at 5:03









                      Jarod ElliottJarod Elliott

                      12.9k22932




                      12.9k22932








                      • 2





                        You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                        – rampion
                        May 16 '09 at 16:54






                      • 9





                        Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                        – gpampara
                        Feb 13 '10 at 6:45






                      • 1





                        Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                        – user1032613
                        Feb 4 '13 at 22:26






                      • 1





                        @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                        – user1520427
                        May 20 '13 at 0:10






                      • 4





                        @Jarod Elliott do the population fitnesses need to be sorted in this example?

                        – CatsLoveJazz
                        Jun 22 '16 at 14:47
















                      • 2





                        You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                        – rampion
                        May 16 '09 at 16:54






                      • 9





                        Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                        – gpampara
                        Feb 13 '10 at 6:45






                      • 1





                        Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                        – user1032613
                        Feb 4 '13 at 22:26






                      • 1





                        @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                        – user1520427
                        May 20 '13 at 0:10






                      • 4





                        @Jarod Elliott do the population fitnesses need to be sorted in this example?

                        – CatsLoveJazz
                        Jun 22 '16 at 14:47










                      2




                      2





                      You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                      – rampion
                      May 16 '09 at 16:54





                      You may be able to make this more efficient by doing a binary search on the probability array (rather than an iterative search).

                      – rampion
                      May 16 '09 at 16:54




                      9




                      9





                      Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                      – gpampara
                      Feb 13 '10 at 6:45





                      Please note that this algorithm will not function as expected for minimization problems. It is a common problem with the Roulette Selection (fitness proportionate selection).

                      – gpampara
                      Feb 13 '10 at 6:45




                      1




                      1





                      Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                      – user1032613
                      Feb 4 '13 at 22:26





                      Fitness score should be assigned in a way such that higher score is always more favourable. For minimization problems, the invert is usually taken. For example, to minimize the sum of x and y, a fitness function could be written as fitness = 1 / (x + y).

                      – user1032613
                      Feb 4 '13 at 22:26




                      1




                      1





                      @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                      – user1520427
                      May 20 '13 at 0:10





                      @JarodElliott I might be missing something, but that psuedocode doesn't look correct. The later values in probability could well be greater than 1 and will therefore never be selected.. number should be number = (Random between 0 and 1) * sum of probabilities shouldn't it?

                      – user1520427
                      May 20 '13 at 0:10




                      4




                      4





                      @Jarod Elliott do the population fitnesses need to be sorted in this example?

                      – CatsLoveJazz
                      Jun 22 '16 at 14:47







                      @Jarod Elliott do the population fitnesses need to be sorted in this example?

                      – CatsLoveJazz
                      Jun 22 '16 at 14:47















                      15














                      Lots of correct solutions already, but I think this code is clearer.



                      def select(fs):
                      p = random.uniform(0, sum(fs))
                      for i, f in enumerate(fs):
                      if p <= 0:
                      break
                      p -= f
                      return i


                      In addition, if you accumulate the fs, you can produce a more efficient solution.



                      cfs = [sum(fs[:i+1]) for i in xrange(len(fs))]

                      def select(cfs):
                      return bisect.bisect_left(cfs, random.uniform(0, cfs[-1]))


                      This is both faster and it's extremely concise code. STL in C++ has a similar bisection algorithm available if that's the language you're using.






                      share|improve this answer



















                      • 1





                        That solution is not just shorter than my code but also clearer and more efficient. (Y)

                        – noio
                        Jan 29 '12 at 11:08






                      • 6





                        It would really help if these variables had english names

                        – Tyrsius
                        Oct 8 '15 at 17:37
















                      15














                      Lots of correct solutions already, but I think this code is clearer.



                      def select(fs):
                      p = random.uniform(0, sum(fs))
                      for i, f in enumerate(fs):
                      if p <= 0:
                      break
                      p -= f
                      return i


                      In addition, if you accumulate the fs, you can produce a more efficient solution.



                      cfs = [sum(fs[:i+1]) for i in xrange(len(fs))]

                      def select(cfs):
                      return bisect.bisect_left(cfs, random.uniform(0, cfs[-1]))


                      This is both faster and it's extremely concise code. STL in C++ has a similar bisection algorithm available if that's the language you're using.






                      share|improve this answer



















                      • 1





                        That solution is not just shorter than my code but also clearer and more efficient. (Y)

                        – noio
                        Jan 29 '12 at 11:08






                      • 6





                        It would really help if these variables had english names

                        – Tyrsius
                        Oct 8 '15 at 17:37














                      15












                      15








                      15







                      Lots of correct solutions already, but I think this code is clearer.



                      def select(fs):
                      p = random.uniform(0, sum(fs))
                      for i, f in enumerate(fs):
                      if p <= 0:
                      break
                      p -= f
                      return i


                      In addition, if you accumulate the fs, you can produce a more efficient solution.



                      cfs = [sum(fs[:i+1]) for i in xrange(len(fs))]

                      def select(cfs):
                      return bisect.bisect_left(cfs, random.uniform(0, cfs[-1]))


                      This is both faster and it's extremely concise code. STL in C++ has a similar bisection algorithm available if that's the language you're using.






                      share|improve this answer













                      Lots of correct solutions already, but I think this code is clearer.



                      def select(fs):
                      p = random.uniform(0, sum(fs))
                      for i, f in enumerate(fs):
                      if p <= 0:
                      break
                      p -= f
                      return i


                      In addition, if you accumulate the fs, you can produce a more efficient solution.



                      cfs = [sum(fs[:i+1]) for i in xrange(len(fs))]

                      def select(cfs):
                      return bisect.bisect_left(cfs, random.uniform(0, cfs[-1]))


                      This is both faster and it's extremely concise code. STL in C++ has a similar bisection algorithm available if that's the language you're using.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Dec 11 '11 at 11:38







                      user97370















                      • 1





                        That solution is not just shorter than my code but also clearer and more efficient. (Y)

                        – noio
                        Jan 29 '12 at 11:08






                      • 6





                        It would really help if these variables had english names

                        – Tyrsius
                        Oct 8 '15 at 17:37














                      • 1





                        That solution is not just shorter than my code but also clearer and more efficient. (Y)

                        – noio
                        Jan 29 '12 at 11:08






                      • 6





                        It would really help if these variables had english names

                        – Tyrsius
                        Oct 8 '15 at 17:37








                      1




                      1





                      That solution is not just shorter than my code but also clearer and more efficient. (Y)

                      – noio
                      Jan 29 '12 at 11:08





                      That solution is not just shorter than my code but also clearer and more efficient. (Y)

                      – noio
                      Jan 29 '12 at 11:08




                      6




                      6





                      It would really help if these variables had english names

                      – Tyrsius
                      Oct 8 '15 at 17:37





                      It would really help if these variables had english names

                      – Tyrsius
                      Oct 8 '15 at 17:37











                      12














                      The pseudocode posted contained some unclear elements, and it adds the complexity of generating offspring in stead of performing pure selection. Here is a simple python implementation of that pseudocode:



                      def roulette_select(population, fitnesses, num):
                      """ Roulette selection, implemented according to:
                      <http://stackoverflow.com/questions/177271/roulette
                      -selection-in-genetic-algorithms/177278#177278>
                      """
                      total_fitness = float(sum(fitnesses))
                      rel_fitness = [f/total_fitness for f in fitnesses]
                      # Generate probability intervals for each individual
                      probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
                      # Draw new population
                      new_population =
                      for n in xrange(num):
                      r = rand()
                      for (i, individual) in enumerate(population):
                      if r <= probs[i]:
                      new_population.append(individual)
                      break
                      return new_population





                      share|improve this answer




























                        12














                        The pseudocode posted contained some unclear elements, and it adds the complexity of generating offspring in stead of performing pure selection. Here is a simple python implementation of that pseudocode:



                        def roulette_select(population, fitnesses, num):
                        """ Roulette selection, implemented according to:
                        <http://stackoverflow.com/questions/177271/roulette
                        -selection-in-genetic-algorithms/177278#177278>
                        """
                        total_fitness = float(sum(fitnesses))
                        rel_fitness = [f/total_fitness for f in fitnesses]
                        # Generate probability intervals for each individual
                        probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
                        # Draw new population
                        new_population =
                        for n in xrange(num):
                        r = rand()
                        for (i, individual) in enumerate(population):
                        if r <= probs[i]:
                        new_population.append(individual)
                        break
                        return new_population





                        share|improve this answer


























                          12












                          12








                          12







                          The pseudocode posted contained some unclear elements, and it adds the complexity of generating offspring in stead of performing pure selection. Here is a simple python implementation of that pseudocode:



                          def roulette_select(population, fitnesses, num):
                          """ Roulette selection, implemented according to:
                          <http://stackoverflow.com/questions/177271/roulette
                          -selection-in-genetic-algorithms/177278#177278>
                          """
                          total_fitness = float(sum(fitnesses))
                          rel_fitness = [f/total_fitness for f in fitnesses]
                          # Generate probability intervals for each individual
                          probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
                          # Draw new population
                          new_population =
                          for n in xrange(num):
                          r = rand()
                          for (i, individual) in enumerate(population):
                          if r <= probs[i]:
                          new_population.append(individual)
                          break
                          return new_population





                          share|improve this answer













                          The pseudocode posted contained some unclear elements, and it adds the complexity of generating offspring in stead of performing pure selection. Here is a simple python implementation of that pseudocode:



                          def roulette_select(population, fitnesses, num):
                          """ Roulette selection, implemented according to:
                          <http://stackoverflow.com/questions/177271/roulette
                          -selection-in-genetic-algorithms/177278#177278>
                          """
                          total_fitness = float(sum(fitnesses))
                          rel_fitness = [f/total_fitness for f in fitnesses]
                          # Generate probability intervals for each individual
                          probs = [sum(rel_fitness[:i+1]) for i in range(len(rel_fitness))]
                          # Draw new population
                          new_population =
                          for n in xrange(num):
                          r = rand()
                          for (i, individual) in enumerate(population):
                          if r <= probs[i]:
                          new_population.append(individual)
                          break
                          return new_population






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Mar 15 '11 at 17:37









                          noionoio

                          2,97353258




                          2,97353258























                              8














                              This is called roulette-wheel selection via stochastic acceptance:



                              /// param[in] f_max maximum fitness of the population
                              ///
                              /// return index of the selected individual
                              ///
                              /// note Assuming positive fitness. Greater is better.

                              unsigned rw_selection(double f_max)
                              {
                              for (;;)
                              {
                              // Select randomly one of the individuals
                              unsigned i(random_individual());

                              // The selection is accepted with probability fitness(i) / f_max
                              if (uniform_random_01() < fitness(i) / f_max)
                              return i;
                              }
                              }


                              The average number of attempts needed for a single selection is:



                              τ = fmax / avg(f)




                              • fmax is the maximum fitness of the population

                              • avg(f) is the average fitness


                              τ doesn't depend explicitly on the number of individual in the population (N), but the ratio can change with N.



                              However in many application (where the fitness remains bounded and the average fitness doesn't diminish to 0 for increasing N) τ doesn't increase unboundedly with N and thus a typical complexity of this algorithm is O(1) (roulette wheel selection using search algorithms has O(N) or O(log N) complexity).



                              The probability distribution of this procedure is indeed the same as in the classical roulette-wheel selection.



                              For further details see:





                              • Roulette-wheel selection via stochastic acceptance (Adam Liposki, Dorota Lipowska - 2011)






                              share|improve this answer






























                                8














                                This is called roulette-wheel selection via stochastic acceptance:



                                /// param[in] f_max maximum fitness of the population
                                ///
                                /// return index of the selected individual
                                ///
                                /// note Assuming positive fitness. Greater is better.

                                unsigned rw_selection(double f_max)
                                {
                                for (;;)
                                {
                                // Select randomly one of the individuals
                                unsigned i(random_individual());

                                // The selection is accepted with probability fitness(i) / f_max
                                if (uniform_random_01() < fitness(i) / f_max)
                                return i;
                                }
                                }


                                The average number of attempts needed for a single selection is:



                                τ = fmax / avg(f)




                                • fmax is the maximum fitness of the population

                                • avg(f) is the average fitness


                                τ doesn't depend explicitly on the number of individual in the population (N), but the ratio can change with N.



                                However in many application (where the fitness remains bounded and the average fitness doesn't diminish to 0 for increasing N) τ doesn't increase unboundedly with N and thus a typical complexity of this algorithm is O(1) (roulette wheel selection using search algorithms has O(N) or O(log N) complexity).



                                The probability distribution of this procedure is indeed the same as in the classical roulette-wheel selection.



                                For further details see:





                                • Roulette-wheel selection via stochastic acceptance (Adam Liposki, Dorota Lipowska - 2011)






                                share|improve this answer




























                                  8












                                  8








                                  8







                                  This is called roulette-wheel selection via stochastic acceptance:



                                  /// param[in] f_max maximum fitness of the population
                                  ///
                                  /// return index of the selected individual
                                  ///
                                  /// note Assuming positive fitness. Greater is better.

                                  unsigned rw_selection(double f_max)
                                  {
                                  for (;;)
                                  {
                                  // Select randomly one of the individuals
                                  unsigned i(random_individual());

                                  // The selection is accepted with probability fitness(i) / f_max
                                  if (uniform_random_01() < fitness(i) / f_max)
                                  return i;
                                  }
                                  }


                                  The average number of attempts needed for a single selection is:



                                  τ = fmax / avg(f)




                                  • fmax is the maximum fitness of the population

                                  • avg(f) is the average fitness


                                  τ doesn't depend explicitly on the number of individual in the population (N), but the ratio can change with N.



                                  However in many application (where the fitness remains bounded and the average fitness doesn't diminish to 0 for increasing N) τ doesn't increase unboundedly with N and thus a typical complexity of this algorithm is O(1) (roulette wheel selection using search algorithms has O(N) or O(log N) complexity).



                                  The probability distribution of this procedure is indeed the same as in the classical roulette-wheel selection.



                                  For further details see:





                                  • Roulette-wheel selection via stochastic acceptance (Adam Liposki, Dorota Lipowska - 2011)






                                  share|improve this answer















                                  This is called roulette-wheel selection via stochastic acceptance:



                                  /// param[in] f_max maximum fitness of the population
                                  ///
                                  /// return index of the selected individual
                                  ///
                                  /// note Assuming positive fitness. Greater is better.

                                  unsigned rw_selection(double f_max)
                                  {
                                  for (;;)
                                  {
                                  // Select randomly one of the individuals
                                  unsigned i(random_individual());

                                  // The selection is accepted with probability fitness(i) / f_max
                                  if (uniform_random_01() < fitness(i) / f_max)
                                  return i;
                                  }
                                  }


                                  The average number of attempts needed for a single selection is:



                                  τ = fmax / avg(f)




                                  • fmax is the maximum fitness of the population

                                  • avg(f) is the average fitness


                                  τ doesn't depend explicitly on the number of individual in the population (N), but the ratio can change with N.



                                  However in many application (where the fitness remains bounded and the average fitness doesn't diminish to 0 for increasing N) τ doesn't increase unboundedly with N and thus a typical complexity of this algorithm is O(1) (roulette wheel selection using search algorithms has O(N) or O(log N) complexity).



                                  The probability distribution of this procedure is indeed the same as in the classical roulette-wheel selection.



                                  For further details see:





                                  • Roulette-wheel selection via stochastic acceptance (Adam Liposki, Dorota Lipowska - 2011)







                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited Jul 3 '15 at 7:34

























                                  answered Apr 24 '14 at 8:56









                                  manliomanlio

                                  14.2k105082




                                  14.2k105082























                                      5














                                      Here is some code in C :



                                      // Find the sum of fitnesses. The function fitness(i) should 
                                      //return the fitness value for member i**

                                      float sumFitness = 0.0f;
                                      for (int i=0; i < nmembers; i++)
                                      sumFitness += fitness(i);

                                      // Get a floating point number in the interval 0.0 ... sumFitness**
                                      float randomNumber = (float(rand() % 10000) / 9999.0f) * sumFitness;

                                      // Translate this number to the corresponding member**
                                      int memberID=0;
                                      float partialSum=0.0f;

                                      while (randomNumber > partialSum)
                                      {
                                      partialSum += fitness(memberID);
                                      memberID++;
                                      }

                                      **// We have just found the member of the population using the roulette algorithm**
                                      **// It is stored in the "memberID" variable**
                                      **// Repeat this procedure as many times to find random members of the population**





                                      share|improve this answer


























                                      • Should the members be sorted?

                                        – Zimano
                                        Oct 24 '16 at 16:38
















                                      5














                                      Here is some code in C :



                                      // Find the sum of fitnesses. The function fitness(i) should 
                                      //return the fitness value for member i**

                                      float sumFitness = 0.0f;
                                      for (int i=0; i < nmembers; i++)
                                      sumFitness += fitness(i);

                                      // Get a floating point number in the interval 0.0 ... sumFitness**
                                      float randomNumber = (float(rand() % 10000) / 9999.0f) * sumFitness;

                                      // Translate this number to the corresponding member**
                                      int memberID=0;
                                      float partialSum=0.0f;

                                      while (randomNumber > partialSum)
                                      {
                                      partialSum += fitness(memberID);
                                      memberID++;
                                      }

                                      **// We have just found the member of the population using the roulette algorithm**
                                      **// It is stored in the "memberID" variable**
                                      **// Repeat this procedure as many times to find random members of the population**





                                      share|improve this answer


























                                      • Should the members be sorted?

                                        – Zimano
                                        Oct 24 '16 at 16:38














                                      5












                                      5








                                      5







                                      Here is some code in C :



                                      // Find the sum of fitnesses. The function fitness(i) should 
                                      //return the fitness value for member i**

                                      float sumFitness = 0.0f;
                                      for (int i=0; i < nmembers; i++)
                                      sumFitness += fitness(i);

                                      // Get a floating point number in the interval 0.0 ... sumFitness**
                                      float randomNumber = (float(rand() % 10000) / 9999.0f) * sumFitness;

                                      // Translate this number to the corresponding member**
                                      int memberID=0;
                                      float partialSum=0.0f;

                                      while (randomNumber > partialSum)
                                      {
                                      partialSum += fitness(memberID);
                                      memberID++;
                                      }

                                      **// We have just found the member of the population using the roulette algorithm**
                                      **// It is stored in the "memberID" variable**
                                      **// Repeat this procedure as many times to find random members of the population**





                                      share|improve this answer















                                      Here is some code in C :



                                      // Find the sum of fitnesses. The function fitness(i) should 
                                      //return the fitness value for member i**

                                      float sumFitness = 0.0f;
                                      for (int i=0; i < nmembers; i++)
                                      sumFitness += fitness(i);

                                      // Get a floating point number in the interval 0.0 ... sumFitness**
                                      float randomNumber = (float(rand() % 10000) / 9999.0f) * sumFitness;

                                      // Translate this number to the corresponding member**
                                      int memberID=0;
                                      float partialSum=0.0f;

                                      while (randomNumber > partialSum)
                                      {
                                      partialSum += fitness(memberID);
                                      memberID++;
                                      }

                                      **// We have just found the member of the population using the roulette algorithm**
                                      **// It is stored in the "memberID" variable**
                                      **// Repeat this procedure as many times to find random members of the population**






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Mar 15 '11 at 17:06









                                      noio

                                      2,97353258




                                      2,97353258










                                      answered Dec 24 '08 at 15:52









                                      WartinWartin

                                      90551837




                                      90551837













                                      • Should the members be sorted?

                                        – Zimano
                                        Oct 24 '16 at 16:38



















                                      • Should the members be sorted?

                                        – Zimano
                                        Oct 24 '16 at 16:38

















                                      Should the members be sorted?

                                      – Zimano
                                      Oct 24 '16 at 16:38





                                      Should the members be sorted?

                                      – Zimano
                                      Oct 24 '16 at 16:38











                                      1














                                      From the above answer, I got the following, which was clearer to me than the answer itself.



                                      To give an example:



                                      Random(sum) :: Random(12)
                                      Iterating through the population, we check the following: random < sum



                                      Let us chose 7 as the random number.



                                      Index   |   Fitness |   Sum |   7 < Sum
                                      0 | 2 | 2 | false
                                      1 | 3 | 5 | false
                                      2 | 1 | 6 | false
                                      3 | 4 | 10 | true
                                      4 | 2 | 12 | ...


                                      Through this example, the most fit (Index 3) has the highest percentage of being chosen (33%); as the random number only has to land within 6->10, and it will be chosen.



                                          for (unsigned int i=0;i<sets.size();i++) {
                                      sum += sets[i].eval();
                                      }
                                      double rand = (((double)rand() / (double)RAND_MAX) * sum);
                                      sum = 0;
                                      for (unsigned int i=0;i<sets.size();i++) {
                                      sum += sets[i].eval();
                                      if (rand < sum) {
                                      //breed i
                                      break;
                                      }
                                      }





                                      share|improve this answer






























                                        1














                                        From the above answer, I got the following, which was clearer to me than the answer itself.



                                        To give an example:



                                        Random(sum) :: Random(12)
                                        Iterating through the population, we check the following: random < sum



                                        Let us chose 7 as the random number.



                                        Index   |   Fitness |   Sum |   7 < Sum
                                        0 | 2 | 2 | false
                                        1 | 3 | 5 | false
                                        2 | 1 | 6 | false
                                        3 | 4 | 10 | true
                                        4 | 2 | 12 | ...


                                        Through this example, the most fit (Index 3) has the highest percentage of being chosen (33%); as the random number only has to land within 6->10, and it will be chosen.



                                            for (unsigned int i=0;i<sets.size();i++) {
                                        sum += sets[i].eval();
                                        }
                                        double rand = (((double)rand() / (double)RAND_MAX) * sum);
                                        sum = 0;
                                        for (unsigned int i=0;i<sets.size();i++) {
                                        sum += sets[i].eval();
                                        if (rand < sum) {
                                        //breed i
                                        break;
                                        }
                                        }





                                        share|improve this answer




























                                          1












                                          1








                                          1







                                          From the above answer, I got the following, which was clearer to me than the answer itself.



                                          To give an example:



                                          Random(sum) :: Random(12)
                                          Iterating through the population, we check the following: random < sum



                                          Let us chose 7 as the random number.



                                          Index   |   Fitness |   Sum |   7 < Sum
                                          0 | 2 | 2 | false
                                          1 | 3 | 5 | false
                                          2 | 1 | 6 | false
                                          3 | 4 | 10 | true
                                          4 | 2 | 12 | ...


                                          Through this example, the most fit (Index 3) has the highest percentage of being chosen (33%); as the random number only has to land within 6->10, and it will be chosen.



                                              for (unsigned int i=0;i<sets.size();i++) {
                                          sum += sets[i].eval();
                                          }
                                          double rand = (((double)rand() / (double)RAND_MAX) * sum);
                                          sum = 0;
                                          for (unsigned int i=0;i<sets.size();i++) {
                                          sum += sets[i].eval();
                                          if (rand < sum) {
                                          //breed i
                                          break;
                                          }
                                          }





                                          share|improve this answer















                                          From the above answer, I got the following, which was clearer to me than the answer itself.



                                          To give an example:



                                          Random(sum) :: Random(12)
                                          Iterating through the population, we check the following: random < sum



                                          Let us chose 7 as the random number.



                                          Index   |   Fitness |   Sum |   7 < Sum
                                          0 | 2 | 2 | false
                                          1 | 3 | 5 | false
                                          2 | 1 | 6 | false
                                          3 | 4 | 10 | true
                                          4 | 2 | 12 | ...


                                          Through this example, the most fit (Index 3) has the highest percentage of being chosen (33%); as the random number only has to land within 6->10, and it will be chosen.



                                              for (unsigned int i=0;i<sets.size();i++) {
                                          sum += sets[i].eval();
                                          }
                                          double rand = (((double)rand() / (double)RAND_MAX) * sum);
                                          sum = 0;
                                          for (unsigned int i=0;i<sets.size();i++) {
                                          sum += sets[i].eval();
                                          if (rand < sum) {
                                          //breed i
                                          break;
                                          }
                                          }






                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited Apr 27 '11 at 4:17

























                                          answered Oct 22 '10 at 8:22









                                          qreba47jhqb4e3lstrujvvdxqreba47jhqb4e3lstrujvvdx

                                          2,57812557




                                          2,57812557























                                              1














                                              Prof. Thrun of Stanford AI lab also presented a fast(er?) re-sampling code in python during his CS373 of Udacity. Google search result led to the following link:



                                              http://www.udacity-forums.com/cs373/questions/20194/fast-resampling-algorithm



                                              Hope this helps






                                              share|improve this answer




























                                                1














                                                Prof. Thrun of Stanford AI lab also presented a fast(er?) re-sampling code in python during his CS373 of Udacity. Google search result led to the following link:



                                                http://www.udacity-forums.com/cs373/questions/20194/fast-resampling-algorithm



                                                Hope this helps






                                                share|improve this answer


























                                                  1












                                                  1








                                                  1







                                                  Prof. Thrun of Stanford AI lab also presented a fast(er?) re-sampling code in python during his CS373 of Udacity. Google search result led to the following link:



                                                  http://www.udacity-forums.com/cs373/questions/20194/fast-resampling-algorithm



                                                  Hope this helps






                                                  share|improve this answer













                                                  Prof. Thrun of Stanford AI lab also presented a fast(er?) re-sampling code in python during his CS373 of Udacity. Google search result led to the following link:



                                                  http://www.udacity-forums.com/cs373/questions/20194/fast-resampling-algorithm



                                                  Hope this helps







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered May 28 '12 at 14:51









                                                  Kangwon LeeKangwon Lee

                                                  55116




                                                  55116























                                                      1














                                                      Here's a compact java implementation I wrote recently for roulette selection, hopefully of use.



                                                      public static gene rouletteSelection()
                                                      {
                                                      float totalScore = 0;
                                                      float runningScore = 0;
                                                      for (gene g : genes)
                                                      {
                                                      totalScore += g.score;
                                                      }

                                                      float rnd = (float) (Math.random() * totalScore);

                                                      for (gene g : genes)
                                                      {
                                                      if ( rnd>=runningScore &&
                                                      rnd<=runningScore+g.score)
                                                      {
                                                      return g;
                                                      }
                                                      runningScore+=g.score;
                                                      }

                                                      return null;
                                                      }





                                                      share|improve this answer




























                                                        1














                                                        Here's a compact java implementation I wrote recently for roulette selection, hopefully of use.



                                                        public static gene rouletteSelection()
                                                        {
                                                        float totalScore = 0;
                                                        float runningScore = 0;
                                                        for (gene g : genes)
                                                        {
                                                        totalScore += g.score;
                                                        }

                                                        float rnd = (float) (Math.random() * totalScore);

                                                        for (gene g : genes)
                                                        {
                                                        if ( rnd>=runningScore &&
                                                        rnd<=runningScore+g.score)
                                                        {
                                                        return g;
                                                        }
                                                        runningScore+=g.score;
                                                        }

                                                        return null;
                                                        }





                                                        share|improve this answer


























                                                          1












                                                          1








                                                          1







                                                          Here's a compact java implementation I wrote recently for roulette selection, hopefully of use.



                                                          public static gene rouletteSelection()
                                                          {
                                                          float totalScore = 0;
                                                          float runningScore = 0;
                                                          for (gene g : genes)
                                                          {
                                                          totalScore += g.score;
                                                          }

                                                          float rnd = (float) (Math.random() * totalScore);

                                                          for (gene g : genes)
                                                          {
                                                          if ( rnd>=runningScore &&
                                                          rnd<=runningScore+g.score)
                                                          {
                                                          return g;
                                                          }
                                                          runningScore+=g.score;
                                                          }

                                                          return null;
                                                          }





                                                          share|improve this answer













                                                          Here's a compact java implementation I wrote recently for roulette selection, hopefully of use.



                                                          public static gene rouletteSelection()
                                                          {
                                                          float totalScore = 0;
                                                          float runningScore = 0;
                                                          for (gene g : genes)
                                                          {
                                                          totalScore += g.score;
                                                          }

                                                          float rnd = (float) (Math.random() * totalScore);

                                                          for (gene g : genes)
                                                          {
                                                          if ( rnd>=runningScore &&
                                                          rnd<=runningScore+g.score)
                                                          {
                                                          return g;
                                                          }
                                                          runningScore+=g.score;
                                                          }

                                                          return null;
                                                          }






                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered Jun 8 '12 at 13:29









                                                          Nick DonnellyNick Donnelly

                                                          438411




                                                          438411























                                                              1














                                                              Roulette Wheel Selection in MatLab:



                                                              TotalFitness=sum(Fitness);
                                                              ProbSelection=zeros(PopLength,1);
                                                              CumProb=zeros(PopLength,1);

                                                              for i=1:PopLength
                                                              ProbSelection(i)=Fitness(i)/TotalFitness;
                                                              if i==1
                                                              CumProb(i)=ProbSelection(i);
                                                              else
                                                              CumProb(i)=CumProb(i-1)+ProbSelection(i);
                                                              end
                                                              end

                                                              SelectInd=rand(PopLength,1);

                                                              for i=1:PopLength
                                                              flag=0;
                                                              for j=1:PopLength
                                                              if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
                                                              SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
                                                              flag=1;
                                                              break;
                                                              end
                                                              end
                                                              if(flag==0)
                                                              SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
                                                              end
                                                              end





                                                              share|improve this answer




























                                                                1














                                                                Roulette Wheel Selection in MatLab:



                                                                TotalFitness=sum(Fitness);
                                                                ProbSelection=zeros(PopLength,1);
                                                                CumProb=zeros(PopLength,1);

                                                                for i=1:PopLength
                                                                ProbSelection(i)=Fitness(i)/TotalFitness;
                                                                if i==1
                                                                CumProb(i)=ProbSelection(i);
                                                                else
                                                                CumProb(i)=CumProb(i-1)+ProbSelection(i);
                                                                end
                                                                end

                                                                SelectInd=rand(PopLength,1);

                                                                for i=1:PopLength
                                                                flag=0;
                                                                for j=1:PopLength
                                                                if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
                                                                SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
                                                                flag=1;
                                                                break;
                                                                end
                                                                end
                                                                if(flag==0)
                                                                SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
                                                                end
                                                                end





                                                                share|improve this answer


























                                                                  1












                                                                  1








                                                                  1







                                                                  Roulette Wheel Selection in MatLab:



                                                                  TotalFitness=sum(Fitness);
                                                                  ProbSelection=zeros(PopLength,1);
                                                                  CumProb=zeros(PopLength,1);

                                                                  for i=1:PopLength
                                                                  ProbSelection(i)=Fitness(i)/TotalFitness;
                                                                  if i==1
                                                                  CumProb(i)=ProbSelection(i);
                                                                  else
                                                                  CumProb(i)=CumProb(i-1)+ProbSelection(i);
                                                                  end
                                                                  end

                                                                  SelectInd=rand(PopLength,1);

                                                                  for i=1:PopLength
                                                                  flag=0;
                                                                  for j=1:PopLength
                                                                  if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
                                                                  SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
                                                                  flag=1;
                                                                  break;
                                                                  end
                                                                  end
                                                                  if(flag==0)
                                                                  SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
                                                                  end
                                                                  end





                                                                  share|improve this answer













                                                                  Roulette Wheel Selection in MatLab:



                                                                  TotalFitness=sum(Fitness);
                                                                  ProbSelection=zeros(PopLength,1);
                                                                  CumProb=zeros(PopLength,1);

                                                                  for i=1:PopLength
                                                                  ProbSelection(i)=Fitness(i)/TotalFitness;
                                                                  if i==1
                                                                  CumProb(i)=ProbSelection(i);
                                                                  else
                                                                  CumProb(i)=CumProb(i-1)+ProbSelection(i);
                                                                  end
                                                                  end

                                                                  SelectInd=rand(PopLength,1);

                                                                  for i=1:PopLength
                                                                  flag=0;
                                                                  for j=1:PopLength
                                                                  if(CumProb(j)<SelectInd(i) && CumProb(j+1)>=SelectInd(i))
                                                                  SelectedPop(i,1:IndLength)=CurrentPop(j+1,1:IndLength);
                                                                  flag=1;
                                                                  break;
                                                                  end
                                                                  end
                                                                  if(flag==0)
                                                                  SelectedPop(i,1:IndLength)=CurrentPop(1,1:IndLength);
                                                                  end
                                                                  end






                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered Jan 26 '16 at 12:22









                                                                  Setu BasakSetu Basak

                                                                  4,45662648




                                                                  4,45662648























                                                                      0














                                                                      Based on my research ,Here is another implementation in C# if there is a need for it:


                                                                      //those with higher fitness get selected wit a large probability
                                                                      //return-->individuals with highest fitness
                                                                      private int RouletteSelection()
                                                                      {
                                                                      double randomFitness = m_random.NextDouble() * m_totalFitness;
                                                                      int idx = -1;
                                                                      int mid;
                                                                      int first = 0;
                                                                      int last = m_populationSize -1;
                                                                      mid = (last - first)/2;

                                                                      // ArrayList's BinarySearch is for exact values only
                                                                      // so do this by hand.
                                                                      while (idx == -1 && first <= last)
                                                                      {
                                                                      if (randomFitness < (double)m_fitnessTable[mid])
                                                                      {
                                                                      last = mid;
                                                                      }
                                                                      else if (randomFitness > (double)m_fitnessTable[mid])
                                                                      {
                                                                      first = mid;
                                                                      }
                                                                      mid = (first + last)/2;
                                                                      // lies between i and i+1
                                                                      if ((last - first) == 1)
                                                                      idx = last;
                                                                      }
                                                                      return idx;
                                                                      }





                                                                      share|improve this answer




























                                                                        0














                                                                        Based on my research ,Here is another implementation in C# if there is a need for it:


                                                                        //those with higher fitness get selected wit a large probability
                                                                        //return-->individuals with highest fitness
                                                                        private int RouletteSelection()
                                                                        {
                                                                        double randomFitness = m_random.NextDouble() * m_totalFitness;
                                                                        int idx = -1;
                                                                        int mid;
                                                                        int first = 0;
                                                                        int last = m_populationSize -1;
                                                                        mid = (last - first)/2;

                                                                        // ArrayList's BinarySearch is for exact values only
                                                                        // so do this by hand.
                                                                        while (idx == -1 && first <= last)
                                                                        {
                                                                        if (randomFitness < (double)m_fitnessTable[mid])
                                                                        {
                                                                        last = mid;
                                                                        }
                                                                        else if (randomFitness > (double)m_fitnessTable[mid])
                                                                        {
                                                                        first = mid;
                                                                        }
                                                                        mid = (first + last)/2;
                                                                        // lies between i and i+1
                                                                        if ((last - first) == 1)
                                                                        idx = last;
                                                                        }
                                                                        return idx;
                                                                        }





                                                                        share|improve this answer


























                                                                          0












                                                                          0








                                                                          0







                                                                          Based on my research ,Here is another implementation in C# if there is a need for it:


                                                                          //those with higher fitness get selected wit a large probability
                                                                          //return-->individuals with highest fitness
                                                                          private int RouletteSelection()
                                                                          {
                                                                          double randomFitness = m_random.NextDouble() * m_totalFitness;
                                                                          int idx = -1;
                                                                          int mid;
                                                                          int first = 0;
                                                                          int last = m_populationSize -1;
                                                                          mid = (last - first)/2;

                                                                          // ArrayList's BinarySearch is for exact values only
                                                                          // so do this by hand.
                                                                          while (idx == -1 && first <= last)
                                                                          {
                                                                          if (randomFitness < (double)m_fitnessTable[mid])
                                                                          {
                                                                          last = mid;
                                                                          }
                                                                          else if (randomFitness > (double)m_fitnessTable[mid])
                                                                          {
                                                                          first = mid;
                                                                          }
                                                                          mid = (first + last)/2;
                                                                          // lies between i and i+1
                                                                          if ((last - first) == 1)
                                                                          idx = last;
                                                                          }
                                                                          return idx;
                                                                          }





                                                                          share|improve this answer













                                                                          Based on my research ,Here is another implementation in C# if there is a need for it:


                                                                          //those with higher fitness get selected wit a large probability
                                                                          //return-->individuals with highest fitness
                                                                          private int RouletteSelection()
                                                                          {
                                                                          double randomFitness = m_random.NextDouble() * m_totalFitness;
                                                                          int idx = -1;
                                                                          int mid;
                                                                          int first = 0;
                                                                          int last = m_populationSize -1;
                                                                          mid = (last - first)/2;

                                                                          // ArrayList's BinarySearch is for exact values only
                                                                          // so do this by hand.
                                                                          while (idx == -1 && first <= last)
                                                                          {
                                                                          if (randomFitness < (double)m_fitnessTable[mid])
                                                                          {
                                                                          last = mid;
                                                                          }
                                                                          else if (randomFitness > (double)m_fitnessTable[mid])
                                                                          {
                                                                          first = mid;
                                                                          }
                                                                          mid = (first + last)/2;
                                                                          // lies between i and i+1
                                                                          if ((last - first) == 1)
                                                                          idx = last;
                                                                          }
                                                                          return idx;
                                                                          }






                                                                          share|improve this answer












                                                                          share|improve this answer



                                                                          share|improve this answer










                                                                          answered Mar 18 '14 at 12:15









                                                                          kiaGhkiaGh

                                                                          344




                                                                          344























                                                                              0














                                                                              Okay, so there are 2 methods for roulette wheel selection implementation: Usual and Stochastic Acceptance one.



                                                                              Usual algorithm:



                                                                              # there will be some amount of repeating organisms here.
                                                                              mating_pool =

                                                                              all_organisms_in_population.each do |organism|
                                                                              organism.fitness.times { mating_pool.push(organism) }
                                                                              end

                                                                              # [very_fit_organism, very_fit_organism, very_fit_organism, not_so_fit_organism]
                                                                              return mating_pool.sample #=> random, likely fit, parent!


                                                                              Stochastic Acceptance algorithm:



                                                                              max_fitness_in_population = all_organisms_in_population.sort_by(:fitness)[0]
                                                                              loop do
                                                                              random_parent = all_organisms_in_population.sample
                                                                              probability = random_parent.fitness/max_fitness_in_population * 100
                                                                              # if random_parent's fitness is 90%,
                                                                              # it's very likely that rand(100) is smaller than it.
                                                                              if rand(100) < probability
                                                                              return random_parent #=> random, likely fit, parent!
                                                                              else
                                                                              next #=> or let's keep on searching for one.
                                                                              end
                                                                              end


                                                                              You can choose either, they will be returning identical results.





                                                                              Useful resources:



                                                                              http://natureofcode.com/book/chapter-9-the-evolution-of-code - a beginner-friendly and clear chapter on genetic algorithms. explains roulette wheel selection as a bucket of wooden letters (the more As you put in - the great is the chance of picking an A, Usual algorithm).



                                                                              https://en.wikipedia.org/wiki/Fitness_proportionate_selection - describes Stochastic Acceptance algorithm.






                                                                              share|improve this answer




























                                                                                0














                                                                                Okay, so there are 2 methods for roulette wheel selection implementation: Usual and Stochastic Acceptance one.



                                                                                Usual algorithm:



                                                                                # there will be some amount of repeating organisms here.
                                                                                mating_pool =

                                                                                all_organisms_in_population.each do |organism|
                                                                                organism.fitness.times { mating_pool.push(organism) }
                                                                                end

                                                                                # [very_fit_organism, very_fit_organism, very_fit_organism, not_so_fit_organism]
                                                                                return mating_pool.sample #=> random, likely fit, parent!


                                                                                Stochastic Acceptance algorithm:



                                                                                max_fitness_in_population = all_organisms_in_population.sort_by(:fitness)[0]
                                                                                loop do
                                                                                random_parent = all_organisms_in_population.sample
                                                                                probability = random_parent.fitness/max_fitness_in_population * 100
                                                                                # if random_parent's fitness is 90%,
                                                                                # it's very likely that rand(100) is smaller than it.
                                                                                if rand(100) < probability
                                                                                return random_parent #=> random, likely fit, parent!
                                                                                else
                                                                                next #=> or let's keep on searching for one.
                                                                                end
                                                                                end


                                                                                You can choose either, they will be returning identical results.





                                                                                Useful resources:



                                                                                http://natureofcode.com/book/chapter-9-the-evolution-of-code - a beginner-friendly and clear chapter on genetic algorithms. explains roulette wheel selection as a bucket of wooden letters (the more As you put in - the great is the chance of picking an A, Usual algorithm).



                                                                                https://en.wikipedia.org/wiki/Fitness_proportionate_selection - describes Stochastic Acceptance algorithm.






                                                                                share|improve this answer


























                                                                                  0












                                                                                  0








                                                                                  0







                                                                                  Okay, so there are 2 methods for roulette wheel selection implementation: Usual and Stochastic Acceptance one.



                                                                                  Usual algorithm:



                                                                                  # there will be some amount of repeating organisms here.
                                                                                  mating_pool =

                                                                                  all_organisms_in_population.each do |organism|
                                                                                  organism.fitness.times { mating_pool.push(organism) }
                                                                                  end

                                                                                  # [very_fit_organism, very_fit_organism, very_fit_organism, not_so_fit_organism]
                                                                                  return mating_pool.sample #=> random, likely fit, parent!


                                                                                  Stochastic Acceptance algorithm:



                                                                                  max_fitness_in_population = all_organisms_in_population.sort_by(:fitness)[0]
                                                                                  loop do
                                                                                  random_parent = all_organisms_in_population.sample
                                                                                  probability = random_parent.fitness/max_fitness_in_population * 100
                                                                                  # if random_parent's fitness is 90%,
                                                                                  # it's very likely that rand(100) is smaller than it.
                                                                                  if rand(100) < probability
                                                                                  return random_parent #=> random, likely fit, parent!
                                                                                  else
                                                                                  next #=> or let's keep on searching for one.
                                                                                  end
                                                                                  end


                                                                                  You can choose either, they will be returning identical results.





                                                                                  Useful resources:



                                                                                  http://natureofcode.com/book/chapter-9-the-evolution-of-code - a beginner-friendly and clear chapter on genetic algorithms. explains roulette wheel selection as a bucket of wooden letters (the more As you put in - the great is the chance of picking an A, Usual algorithm).



                                                                                  https://en.wikipedia.org/wiki/Fitness_proportionate_selection - describes Stochastic Acceptance algorithm.






                                                                                  share|improve this answer













                                                                                  Okay, so there are 2 methods for roulette wheel selection implementation: Usual and Stochastic Acceptance one.



                                                                                  Usual algorithm:



                                                                                  # there will be some amount of repeating organisms here.
                                                                                  mating_pool =

                                                                                  all_organisms_in_population.each do |organism|
                                                                                  organism.fitness.times { mating_pool.push(organism) }
                                                                                  end

                                                                                  # [very_fit_organism, very_fit_organism, very_fit_organism, not_so_fit_organism]
                                                                                  return mating_pool.sample #=> random, likely fit, parent!


                                                                                  Stochastic Acceptance algorithm:



                                                                                  max_fitness_in_population = all_organisms_in_population.sort_by(:fitness)[0]
                                                                                  loop do
                                                                                  random_parent = all_organisms_in_population.sample
                                                                                  probability = random_parent.fitness/max_fitness_in_population * 100
                                                                                  # if random_parent's fitness is 90%,
                                                                                  # it's very likely that rand(100) is smaller than it.
                                                                                  if rand(100) < probability
                                                                                  return random_parent #=> random, likely fit, parent!
                                                                                  else
                                                                                  next #=> or let's keep on searching for one.
                                                                                  end
                                                                                  end


                                                                                  You can choose either, they will be returning identical results.





                                                                                  Useful resources:



                                                                                  http://natureofcode.com/book/chapter-9-the-evolution-of-code - a beginner-friendly and clear chapter on genetic algorithms. explains roulette wheel selection as a bucket of wooden letters (the more As you put in - the great is the chance of picking an A, Usual algorithm).



                                                                                  https://en.wikipedia.org/wiki/Fitness_proportionate_selection - describes Stochastic Acceptance algorithm.







                                                                                  share|improve this answer












                                                                                  share|improve this answer



                                                                                  share|improve this answer










                                                                                  answered Feb 27 '17 at 18:12









                                                                                  lakesarelakesare

                                                                                  6,59543347




                                                                                  6,59543347























                                                                                      0














                                                                                      This Swift 4 array extension implements weighted random selection, a.k.a Roulette selection from its elements:



                                                                                      public extension Array where Element == Double {

                                                                                      /// Consider the elements as weight values and return a weighted random selection by index.
                                                                                      /// a.k.a Roulette wheel selection.
                                                                                      func weightedRandomIndex() -> Int {
                                                                                      var selected: Int = 0
                                                                                      var total: Double = self[0]

                                                                                      for i in 1..<self.count { // start at 1
                                                                                      total += self[i]
                                                                                      if( Double.random(in: 0...1) <= (self[i] / total)) { selected = i }
                                                                                      }

                                                                                      return selected
                                                                                      }
                                                                                      }


                                                                                      For example given the two element array:



                                                                                      [0.9, 0.1]


                                                                                      weightedRandomIndex() will return zero 90% of the time and one 10% of the time.



                                                                                      Here is a more complete test:



                                                                                      let weights = [0.1, 0.7, 0.1, 0.1]
                                                                                      var results = [Int:Int]()
                                                                                      let n = 100000
                                                                                      for _ in 0..<n {
                                                                                      let index = weights.weightedRandomIndex()
                                                                                      results[index] = results[index, default:0] + 1
                                                                                      }
                                                                                      for (key,val) in results.sorted(by: { a,b in weights[a.key] < weights[b.key] }) {
                                                                                      print(weights[key], Double(val)/Double(n))
                                                                                      }


                                                                                      output:



                                                                                      0.1 0.09906
                                                                                      0.1 0.10126
                                                                                      0.1 0.09876
                                                                                      0.7 0.70092


                                                                                      This answer is basically the same as Andrew Mao's answer here:
                                                                                      https://stackoverflow.com/a/15582983/74975






                                                                                      share|improve this answer






























                                                                                        0














                                                                                        This Swift 4 array extension implements weighted random selection, a.k.a Roulette selection from its elements:



                                                                                        public extension Array where Element == Double {

                                                                                        /// Consider the elements as weight values and return a weighted random selection by index.
                                                                                        /// a.k.a Roulette wheel selection.
                                                                                        func weightedRandomIndex() -> Int {
                                                                                        var selected: Int = 0
                                                                                        var total: Double = self[0]

                                                                                        for i in 1..<self.count { // start at 1
                                                                                        total += self[i]
                                                                                        if( Double.random(in: 0...1) <= (self[i] / total)) { selected = i }
                                                                                        }

                                                                                        return selected
                                                                                        }
                                                                                        }


                                                                                        For example given the two element array:



                                                                                        [0.9, 0.1]


                                                                                        weightedRandomIndex() will return zero 90% of the time and one 10% of the time.



                                                                                        Here is a more complete test:



                                                                                        let weights = [0.1, 0.7, 0.1, 0.1]
                                                                                        var results = [Int:Int]()
                                                                                        let n = 100000
                                                                                        for _ in 0..<n {
                                                                                        let index = weights.weightedRandomIndex()
                                                                                        results[index] = results[index, default:0] + 1
                                                                                        }
                                                                                        for (key,val) in results.sorted(by: { a,b in weights[a.key] < weights[b.key] }) {
                                                                                        print(weights[key], Double(val)/Double(n))
                                                                                        }


                                                                                        output:



                                                                                        0.1 0.09906
                                                                                        0.1 0.10126
                                                                                        0.1 0.09876
                                                                                        0.7 0.70092


                                                                                        This answer is basically the same as Andrew Mao's answer here:
                                                                                        https://stackoverflow.com/a/15582983/74975






                                                                                        share|improve this answer




























                                                                                          0












                                                                                          0








                                                                                          0







                                                                                          This Swift 4 array extension implements weighted random selection, a.k.a Roulette selection from its elements:



                                                                                          public extension Array where Element == Double {

                                                                                          /// Consider the elements as weight values and return a weighted random selection by index.
                                                                                          /// a.k.a Roulette wheel selection.
                                                                                          func weightedRandomIndex() -> Int {
                                                                                          var selected: Int = 0
                                                                                          var total: Double = self[0]

                                                                                          for i in 1..<self.count { // start at 1
                                                                                          total += self[i]
                                                                                          if( Double.random(in: 0...1) <= (self[i] / total)) { selected = i }
                                                                                          }

                                                                                          return selected
                                                                                          }
                                                                                          }


                                                                                          For example given the two element array:



                                                                                          [0.9, 0.1]


                                                                                          weightedRandomIndex() will return zero 90% of the time and one 10% of the time.



                                                                                          Here is a more complete test:



                                                                                          let weights = [0.1, 0.7, 0.1, 0.1]
                                                                                          var results = [Int:Int]()
                                                                                          let n = 100000
                                                                                          for _ in 0..<n {
                                                                                          let index = weights.weightedRandomIndex()
                                                                                          results[index] = results[index, default:0] + 1
                                                                                          }
                                                                                          for (key,val) in results.sorted(by: { a,b in weights[a.key] < weights[b.key] }) {
                                                                                          print(weights[key], Double(val)/Double(n))
                                                                                          }


                                                                                          output:



                                                                                          0.1 0.09906
                                                                                          0.1 0.10126
                                                                                          0.1 0.09876
                                                                                          0.7 0.70092


                                                                                          This answer is basically the same as Andrew Mao's answer here:
                                                                                          https://stackoverflow.com/a/15582983/74975






                                                                                          share|improve this answer















                                                                                          This Swift 4 array extension implements weighted random selection, a.k.a Roulette selection from its elements:



                                                                                          public extension Array where Element == Double {

                                                                                          /// Consider the elements as weight values and return a weighted random selection by index.
                                                                                          /// a.k.a Roulette wheel selection.
                                                                                          func weightedRandomIndex() -> Int {
                                                                                          var selected: Int = 0
                                                                                          var total: Double = self[0]

                                                                                          for i in 1..<self.count { // start at 1
                                                                                          total += self[i]
                                                                                          if( Double.random(in: 0...1) <= (self[i] / total)) { selected = i }
                                                                                          }

                                                                                          return selected
                                                                                          }
                                                                                          }


                                                                                          For example given the two element array:



                                                                                          [0.9, 0.1]


                                                                                          weightedRandomIndex() will return zero 90% of the time and one 10% of the time.



                                                                                          Here is a more complete test:



                                                                                          let weights = [0.1, 0.7, 0.1, 0.1]
                                                                                          var results = [Int:Int]()
                                                                                          let n = 100000
                                                                                          for _ in 0..<n {
                                                                                          let index = weights.weightedRandomIndex()
                                                                                          results[index] = results[index, default:0] + 1
                                                                                          }
                                                                                          for (key,val) in results.sorted(by: { a,b in weights[a.key] < weights[b.key] }) {
                                                                                          print(weights[key], Double(val)/Double(n))
                                                                                          }


                                                                                          output:



                                                                                          0.1 0.09906
                                                                                          0.1 0.10126
                                                                                          0.1 0.09876
                                                                                          0.7 0.70092


                                                                                          This answer is basically the same as Andrew Mao's answer here:
                                                                                          https://stackoverflow.com/a/15582983/74975







                                                                                          share|improve this answer














                                                                                          share|improve this answer



                                                                                          share|improve this answer








                                                                                          edited Nov 20 '18 at 23:26

























                                                                                          answered Nov 20 '18 at 22:36









                                                                                          Pat NiemeyerPat Niemeyer

                                                                                          1,9111926




                                                                                          1,9111926























                                                                                              -1














                                                                                              I wrote a version in C# and am really looking for confirmation that it is indeed correct:



                                                                                              (roulette_selector is a random number which will be in the range 0.0 to 1.0)



                                                                                              private Individual Select_Roulette(double sum_fitness)
                                                                                              {
                                                                                              Individual ret = new Individual();
                                                                                              bool loop = true;

                                                                                              while (loop)
                                                                                              {
                                                                                              //this will give us a double within the range 0.0 to total fitness
                                                                                              double slice = roulette_selector.NextDouble() * sum_fitness;

                                                                                              double curFitness = 0.0;

                                                                                              foreach (Individual ind in _generation)
                                                                                              {
                                                                                              curFitness += ind.Fitness;
                                                                                              if (curFitness >= slice)
                                                                                              {
                                                                                              loop = false;
                                                                                              ret = ind;
                                                                                              break;
                                                                                              }
                                                                                              }
                                                                                              }
                                                                                              return ret;

                                                                                              }





                                                                                              share|improve this answer




























                                                                                                -1














                                                                                                I wrote a version in C# and am really looking for confirmation that it is indeed correct:



                                                                                                (roulette_selector is a random number which will be in the range 0.0 to 1.0)



                                                                                                private Individual Select_Roulette(double sum_fitness)
                                                                                                {
                                                                                                Individual ret = new Individual();
                                                                                                bool loop = true;

                                                                                                while (loop)
                                                                                                {
                                                                                                //this will give us a double within the range 0.0 to total fitness
                                                                                                double slice = roulette_selector.NextDouble() * sum_fitness;

                                                                                                double curFitness = 0.0;

                                                                                                foreach (Individual ind in _generation)
                                                                                                {
                                                                                                curFitness += ind.Fitness;
                                                                                                if (curFitness >= slice)
                                                                                                {
                                                                                                loop = false;
                                                                                                ret = ind;
                                                                                                break;
                                                                                                }
                                                                                                }
                                                                                                }
                                                                                                return ret;

                                                                                                }





                                                                                                share|improve this answer


























                                                                                                  -1












                                                                                                  -1








                                                                                                  -1







                                                                                                  I wrote a version in C# and am really looking for confirmation that it is indeed correct:



                                                                                                  (roulette_selector is a random number which will be in the range 0.0 to 1.0)



                                                                                                  private Individual Select_Roulette(double sum_fitness)
                                                                                                  {
                                                                                                  Individual ret = new Individual();
                                                                                                  bool loop = true;

                                                                                                  while (loop)
                                                                                                  {
                                                                                                  //this will give us a double within the range 0.0 to total fitness
                                                                                                  double slice = roulette_selector.NextDouble() * sum_fitness;

                                                                                                  double curFitness = 0.0;

                                                                                                  foreach (Individual ind in _generation)
                                                                                                  {
                                                                                                  curFitness += ind.Fitness;
                                                                                                  if (curFitness >= slice)
                                                                                                  {
                                                                                                  loop = false;
                                                                                                  ret = ind;
                                                                                                  break;
                                                                                                  }
                                                                                                  }
                                                                                                  }
                                                                                                  return ret;

                                                                                                  }





                                                                                                  share|improve this answer













                                                                                                  I wrote a version in C# and am really looking for confirmation that it is indeed correct:



                                                                                                  (roulette_selector is a random number which will be in the range 0.0 to 1.0)



                                                                                                  private Individual Select_Roulette(double sum_fitness)
                                                                                                  {
                                                                                                  Individual ret = new Individual();
                                                                                                  bool loop = true;

                                                                                                  while (loop)
                                                                                                  {
                                                                                                  //this will give us a double within the range 0.0 to total fitness
                                                                                                  double slice = roulette_selector.NextDouble() * sum_fitness;

                                                                                                  double curFitness = 0.0;

                                                                                                  foreach (Individual ind in _generation)
                                                                                                  {
                                                                                                  curFitness += ind.Fitness;
                                                                                                  if (curFitness >= slice)
                                                                                                  {
                                                                                                  loop = false;
                                                                                                  ret = ind;
                                                                                                  break;
                                                                                                  }
                                                                                                  }
                                                                                                  }
                                                                                                  return ret;

                                                                                                  }






                                                                                                  share|improve this answer












                                                                                                  share|improve this answer



                                                                                                  share|improve this answer










                                                                                                  answered May 4 '11 at 19:28









                                                                                                  flavour404flavour404

                                                                                                  2,6962387127




                                                                                                  2,6962387127






























                                                                                                      draft saved

                                                                                                      draft discarded




















































                                                                                                      Thanks for contributing an answer to Stack Overflow!


                                                                                                      • Please be sure to answer the question. Provide details and share your research!

                                                                                                      But avoid



                                                                                                      • Asking for help, clarification, or responding to other answers.

                                                                                                      • Making statements based on opinion; back them up with references or personal experience.


                                                                                                      To learn more, see our tips on writing great answers.




                                                                                                      draft saved


                                                                                                      draft discarded














                                                                                                      StackExchange.ready(
                                                                                                      function () {
                                                                                                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f177271%2froulette-selection-in-genetic-algorithms%23new-answer', 'question_page');
                                                                                                      }
                                                                                                      );

                                                                                                      Post as a guest















                                                                                                      Required, but never shown





















































                                                                                                      Required, but never shown














                                                                                                      Required, but never shown












                                                                                                      Required, but never shown







                                                                                                      Required, but never shown

































                                                                                                      Required, but never shown














                                                                                                      Required, but never shown












                                                                                                      Required, but never shown







                                                                                                      Required, but never shown







                                                                                                      Popular posts from this blog

                                                                                                      How to pass form data using jquery Ajax to insert data in database?

                                                                                                      National Museum of Racing and Hall of Fame

                                                                                                      Guess what letter conforming each word