Picking from a list of individuals based on their fitness values

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I have this method that takes a list of my individuals (class has public field fitnessValue). I sum all fitnessValue and then draw a random value between 0 and sum of fitnessValue. In the end, I check for each individual where cumulative sum of fitnessValue passes the point I counted before and return the one which passed first.



public Individual pickRandomIndividual(List<Individual> pool) 
Double totalScore = 0d;
Double runningScore = 0d;
for (Individual ind : pool)
totalScore += ind.fitnessValue;


Double rnd = Math.random() * totalScore;

for (Individual ind : pool)
if (rnd >= runningScore &&
rnd <= runningScore + ind.fitnessValue)
return ind;

runningScore += ind.fitnessValue;

return null;



I want to refactor this function with Java 8 streams. Any idea how can I achieve that?



I changed it a bit, into:



Double fitnessSum = genePool.stream()
.mapToDouble(individual -> individual.fitnessValue)
.sum();
Double runningScore = 0d;

Double rnd = random() * fitnessSum;

for (Individual g : genePool)
if (rnd >= runningScore && rnd <= runningScore + g.fitnessValue)
return g;

runningScore += g.fitnessValue;

return null;


Still, I do not know how to change cumulative sum part into a stream. Maybe entire logic is poorly implemented? I just want to draw one Individual from the list depending on how large the Individual's fitnessValue is.







share|improve this question



























    up vote
    1
    down vote

    favorite












    I have this method that takes a list of my individuals (class has public field fitnessValue). I sum all fitnessValue and then draw a random value between 0 and sum of fitnessValue. In the end, I check for each individual where cumulative sum of fitnessValue passes the point I counted before and return the one which passed first.



    public Individual pickRandomIndividual(List<Individual> pool) 
    Double totalScore = 0d;
    Double runningScore = 0d;
    for (Individual ind : pool)
    totalScore += ind.fitnessValue;


    Double rnd = Math.random() * totalScore;

    for (Individual ind : pool)
    if (rnd >= runningScore &&
    rnd <= runningScore + ind.fitnessValue)
    return ind;

    runningScore += ind.fitnessValue;

    return null;



    I want to refactor this function with Java 8 streams. Any idea how can I achieve that?



    I changed it a bit, into:



    Double fitnessSum = genePool.stream()
    .mapToDouble(individual -> individual.fitnessValue)
    .sum();
    Double runningScore = 0d;

    Double rnd = random() * fitnessSum;

    for (Individual g : genePool)
    if (rnd >= runningScore && rnd <= runningScore + g.fitnessValue)
    return g;

    runningScore += g.fitnessValue;

    return null;


    Still, I do not know how to change cumulative sum part into a stream. Maybe entire logic is poorly implemented? I just want to draw one Individual from the list depending on how large the Individual's fitnessValue is.







    share|improve this question























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have this method that takes a list of my individuals (class has public field fitnessValue). I sum all fitnessValue and then draw a random value between 0 and sum of fitnessValue. In the end, I check for each individual where cumulative sum of fitnessValue passes the point I counted before and return the one which passed first.



      public Individual pickRandomIndividual(List<Individual> pool) 
      Double totalScore = 0d;
      Double runningScore = 0d;
      for (Individual ind : pool)
      totalScore += ind.fitnessValue;


      Double rnd = Math.random() * totalScore;

      for (Individual ind : pool)
      if (rnd >= runningScore &&
      rnd <= runningScore + ind.fitnessValue)
      return ind;

      runningScore += ind.fitnessValue;

      return null;



      I want to refactor this function with Java 8 streams. Any idea how can I achieve that?



      I changed it a bit, into:



      Double fitnessSum = genePool.stream()
      .mapToDouble(individual -> individual.fitnessValue)
      .sum();
      Double runningScore = 0d;

      Double rnd = random() * fitnessSum;

      for (Individual g : genePool)
      if (rnd >= runningScore && rnd <= runningScore + g.fitnessValue)
      return g;

      runningScore += g.fitnessValue;

      return null;


      Still, I do not know how to change cumulative sum part into a stream. Maybe entire logic is poorly implemented? I just want to draw one Individual from the list depending on how large the Individual's fitnessValue is.







      share|improve this question













      I have this method that takes a list of my individuals (class has public field fitnessValue). I sum all fitnessValue and then draw a random value between 0 and sum of fitnessValue. In the end, I check for each individual where cumulative sum of fitnessValue passes the point I counted before and return the one which passed first.



      public Individual pickRandomIndividual(List<Individual> pool) 
      Double totalScore = 0d;
      Double runningScore = 0d;
      for (Individual ind : pool)
      totalScore += ind.fitnessValue;


      Double rnd = Math.random() * totalScore;

      for (Individual ind : pool)
      if (rnd >= runningScore &&
      rnd <= runningScore + ind.fitnessValue)
      return ind;

      runningScore += ind.fitnessValue;

      return null;



      I want to refactor this function with Java 8 streams. Any idea how can I achieve that?



      I changed it a bit, into:



      Double fitnessSum = genePool.stream()
      .mapToDouble(individual -> individual.fitnessValue)
      .sum();
      Double runningScore = 0d;

      Double rnd = random() * fitnessSum;

      for (Individual g : genePool)
      if (rnd >= runningScore && rnd <= runningScore + g.fitnessValue)
      return g;

      runningScore += g.fitnessValue;

      return null;


      Still, I do not know how to change cumulative sum part into a stream. Maybe entire logic is poorly implemented? I just want to draw one Individual from the list depending on how large the Individual's fitnessValue is.









      share|improve this question












      share|improve this question




      share|improve this question








      edited May 26 at 11:39









      Reinderien

      900415




      900415









      asked May 26 at 0:01









      Rafalsky

      837




      837




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          You have to keep in mind that Streams are not the solution to everything. In this case for example, you need to keep track of multiple values, i.e. the current individual, and a cumulative sum (and you have to return a a value as soon as a certain condition is met). Yes, there are ways to do this with Streams, but I think in this case it is best to implement it with a simple loop like you have.



          A couple of side notes:



          • Use the primitive type double instead of the wrapper class.

          • Declare variables as late as possible.

          • Perhaps allow the user to pass a Random instance.


          • I think your implementation can be simplified by subtracting, which would then mean you only have to check for < 0, e.g.:



            double fitnessSum = genePool.stream()
            .mapToDouble(individual -> individual.fitnessValue)
            .sum();

            double remainder = Math.random() * fitnessSum;
            for (Individual gene : genePool)
            remainder -= gene.fitnessValue;
            if (remainder <= 0.0)
            return gene;


            return genePool.get(genePool.size() - 1);






          share|improve this answer





















          • Couldn't agree more. Streams is not the solution for this. Good answer!
            – Simon Forsberg♦
            May 26 at 17:25










          • Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
            – Rafalsky
            May 26 at 20:16






          • 1




            @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
            – Stingy
            May 26 at 21:32

















          up vote
          2
          down vote













          There's also this variation on the classic solution to picking a random element from an Iterator while iterating only once:



          Double fitnessSum = 0.0;
          Individual chosen = null;
          for (Individual g : genePool)
          fitnessSum += g.fitnessValue;
          if (Math.random() * fitnessSum < g.fitnessValue)
          chosen = g;


          return g;





          share|improve this answer

















          • 1




            Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
            – Daniel Martin
            May 26 at 13:40

















          up vote
          1
          down vote














          • In the second loop, the loop where you update runningScore, there is no need to check whether rnd >= runningScore, because at the first loop iteration, it will be true by default, and at every subsequent iteration, runningScore will be equal to the runningScore of the previous iteration plus the fitnessValue of the previous individual, and if this value were greater than (or even equal to) rnd, then the loop would have already been terminated at the previous iteration. In fact, you could rewrite this loop to:



            for (Individual ind : pool) 
            runningScore += ind.fitnessValue;
            if (rnd <= runningScore)
            return ind;




            That way, you only have to perform the addition once, saving performance. Of course, this assumes that fitnessValue will always be non-negative.




          • Based on how the code is supposed to work, the return null; statement after the last for loop should never be reached. Since the compiler does not know that, you could insert an assert false; before the return statement. It is also possible to use assert statements with a detail message, for example like this:



            assert false : "totalScore: " + totalScore;






          share|improve this answer





















          • Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
            – Rafalsky
            May 26 at 21:32






          • 1




            @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
            – Stingy
            May 26 at 22:06










          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          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: "196"
          ;
          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',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195191%2fpicking-from-a-list-of-individuals-based-on-their-fitness-values%23new-answer', 'question_page');

          );

          Post as a guest






























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          You have to keep in mind that Streams are not the solution to everything. In this case for example, you need to keep track of multiple values, i.e. the current individual, and a cumulative sum (and you have to return a a value as soon as a certain condition is met). Yes, there are ways to do this with Streams, but I think in this case it is best to implement it with a simple loop like you have.



          A couple of side notes:



          • Use the primitive type double instead of the wrapper class.

          • Declare variables as late as possible.

          • Perhaps allow the user to pass a Random instance.


          • I think your implementation can be simplified by subtracting, which would then mean you only have to check for < 0, e.g.:



            double fitnessSum = genePool.stream()
            .mapToDouble(individual -> individual.fitnessValue)
            .sum();

            double remainder = Math.random() * fitnessSum;
            for (Individual gene : genePool)
            remainder -= gene.fitnessValue;
            if (remainder <= 0.0)
            return gene;


            return genePool.get(genePool.size() - 1);






          share|improve this answer





















          • Couldn't agree more. Streams is not the solution for this. Good answer!
            – Simon Forsberg♦
            May 26 at 17:25










          • Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
            – Rafalsky
            May 26 at 20:16






          • 1




            @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
            – Stingy
            May 26 at 21:32














          up vote
          3
          down vote



          accepted










          You have to keep in mind that Streams are not the solution to everything. In this case for example, you need to keep track of multiple values, i.e. the current individual, and a cumulative sum (and you have to return a a value as soon as a certain condition is met). Yes, there are ways to do this with Streams, but I think in this case it is best to implement it with a simple loop like you have.



          A couple of side notes:



          • Use the primitive type double instead of the wrapper class.

          • Declare variables as late as possible.

          • Perhaps allow the user to pass a Random instance.


          • I think your implementation can be simplified by subtracting, which would then mean you only have to check for < 0, e.g.:



            double fitnessSum = genePool.stream()
            .mapToDouble(individual -> individual.fitnessValue)
            .sum();

            double remainder = Math.random() * fitnessSum;
            for (Individual gene : genePool)
            remainder -= gene.fitnessValue;
            if (remainder <= 0.0)
            return gene;


            return genePool.get(genePool.size() - 1);






          share|improve this answer





















          • Couldn't agree more. Streams is not the solution for this. Good answer!
            – Simon Forsberg♦
            May 26 at 17:25










          • Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
            – Rafalsky
            May 26 at 20:16






          • 1




            @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
            – Stingy
            May 26 at 21:32












          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          You have to keep in mind that Streams are not the solution to everything. In this case for example, you need to keep track of multiple values, i.e. the current individual, and a cumulative sum (and you have to return a a value as soon as a certain condition is met). Yes, there are ways to do this with Streams, but I think in this case it is best to implement it with a simple loop like you have.



          A couple of side notes:



          • Use the primitive type double instead of the wrapper class.

          • Declare variables as late as possible.

          • Perhaps allow the user to pass a Random instance.


          • I think your implementation can be simplified by subtracting, which would then mean you only have to check for < 0, e.g.:



            double fitnessSum = genePool.stream()
            .mapToDouble(individual -> individual.fitnessValue)
            .sum();

            double remainder = Math.random() * fitnessSum;
            for (Individual gene : genePool)
            remainder -= gene.fitnessValue;
            if (remainder <= 0.0)
            return gene;


            return genePool.get(genePool.size() - 1);






          share|improve this answer













          You have to keep in mind that Streams are not the solution to everything. In this case for example, you need to keep track of multiple values, i.e. the current individual, and a cumulative sum (and you have to return a a value as soon as a certain condition is met). Yes, there are ways to do this with Streams, but I think in this case it is best to implement it with a simple loop like you have.



          A couple of side notes:



          • Use the primitive type double instead of the wrapper class.

          • Declare variables as late as possible.

          • Perhaps allow the user to pass a Random instance.


          • I think your implementation can be simplified by subtracting, which would then mean you only have to check for < 0, e.g.:



            double fitnessSum = genePool.stream()
            .mapToDouble(individual -> individual.fitnessValue)
            .sum();

            double remainder = Math.random() * fitnessSum;
            for (Individual gene : genePool)
            remainder -= gene.fitnessValue;
            if (remainder <= 0.0)
            return gene;


            return genePool.get(genePool.size() - 1);







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 26 at 10:52









          Koekje

          1,017211




          1,017211











          • Couldn't agree more. Streams is not the solution for this. Good answer!
            – Simon Forsberg♦
            May 26 at 17:25










          • Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
            – Rafalsky
            May 26 at 20:16






          • 1




            @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
            – Stingy
            May 26 at 21:32
















          • Couldn't agree more. Streams is not the solution for this. Good answer!
            – Simon Forsberg♦
            May 26 at 17:25










          • Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
            – Rafalsky
            May 26 at 20:16






          • 1




            @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
            – Stingy
            May 26 at 21:32















          Couldn't agree more. Streams is not the solution for this. Good answer!
          – Simon Forsberg♦
          May 26 at 17:25




          Couldn't agree more. Streams is not the solution for this. Good answer!
          – Simon Forsberg♦
          May 26 at 17:25












          Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
          – Rafalsky
          May 26 at 20:16




          Thanks for the answer. Nice idea with substracting :) I guess the only way to do it by streams it to keep it in a separate field but it looks like an unnecessary workaround.
          – Rafalsky
          May 26 at 20:16




          1




          1




          @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
          – Stingy
          May 26 at 21:32




          @Rafalsky It would not only be a workaround, it would be against the nature of streams, being an operation that depends on state that changes during the stream's execution. You might be interested in this. Of course, one can ensure that the stream is sequential, but then, why bother? Streams are not only not a solution to everything, they are also not a replacement, or a newer version, of for loops, so you shouldn't aim to use streams just for the sake of using streams.
          – Stingy
          May 26 at 21:32












          up vote
          2
          down vote













          There's also this variation on the classic solution to picking a random element from an Iterator while iterating only once:



          Double fitnessSum = 0.0;
          Individual chosen = null;
          for (Individual g : genePool)
          fitnessSum += g.fitnessValue;
          if (Math.random() * fitnessSum < g.fitnessValue)
          chosen = g;


          return g;





          share|improve this answer

















          • 1




            Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
            – Daniel Martin
            May 26 at 13:40














          up vote
          2
          down vote













          There's also this variation on the classic solution to picking a random element from an Iterator while iterating only once:



          Double fitnessSum = 0.0;
          Individual chosen = null;
          for (Individual g : genePool)
          fitnessSum += g.fitnessValue;
          if (Math.random() * fitnessSum < g.fitnessValue)
          chosen = g;


          return g;





          share|improve this answer

















          • 1




            Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
            – Daniel Martin
            May 26 at 13:40












          up vote
          2
          down vote










          up vote
          2
          down vote









          There's also this variation on the classic solution to picking a random element from an Iterator while iterating only once:



          Double fitnessSum = 0.0;
          Individual chosen = null;
          for (Individual g : genePool)
          fitnessSum += g.fitnessValue;
          if (Math.random() * fitnessSum < g.fitnessValue)
          chosen = g;


          return g;





          share|improve this answer













          There's also this variation on the classic solution to picking a random element from an Iterator while iterating only once:



          Double fitnessSum = 0.0;
          Individual chosen = null;
          for (Individual g : genePool)
          fitnessSum += g.fitnessValue;
          if (Math.random() * fitnessSum < g.fitnessValue)
          chosen = g;


          return g;






          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 26 at 13:38









          Daniel Martin

          1413




          1413







          • 1




            Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
            – Daniel Martin
            May 26 at 13:40












          • 1




            Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
            – Daniel Martin
            May 26 at 13:40







          1




          1




          Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
          – Daniel Martin
          May 26 at 13:40




          Though what the other answer said about Random - you really should let the user pass in a Random inject if their own
          – Daniel Martin
          May 26 at 13:40










          up vote
          1
          down vote














          • In the second loop, the loop where you update runningScore, there is no need to check whether rnd >= runningScore, because at the first loop iteration, it will be true by default, and at every subsequent iteration, runningScore will be equal to the runningScore of the previous iteration plus the fitnessValue of the previous individual, and if this value were greater than (or even equal to) rnd, then the loop would have already been terminated at the previous iteration. In fact, you could rewrite this loop to:



            for (Individual ind : pool) 
            runningScore += ind.fitnessValue;
            if (rnd <= runningScore)
            return ind;




            That way, you only have to perform the addition once, saving performance. Of course, this assumes that fitnessValue will always be non-negative.




          • Based on how the code is supposed to work, the return null; statement after the last for loop should never be reached. Since the compiler does not know that, you could insert an assert false; before the return statement. It is also possible to use assert statements with a detail message, for example like this:



            assert false : "totalScore: " + totalScore;






          share|improve this answer





















          • Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
            – Rafalsky
            May 26 at 21:32






          • 1




            @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
            – Stingy
            May 26 at 22:06














          up vote
          1
          down vote














          • In the second loop, the loop where you update runningScore, there is no need to check whether rnd >= runningScore, because at the first loop iteration, it will be true by default, and at every subsequent iteration, runningScore will be equal to the runningScore of the previous iteration plus the fitnessValue of the previous individual, and if this value were greater than (or even equal to) rnd, then the loop would have already been terminated at the previous iteration. In fact, you could rewrite this loop to:



            for (Individual ind : pool) 
            runningScore += ind.fitnessValue;
            if (rnd <= runningScore)
            return ind;




            That way, you only have to perform the addition once, saving performance. Of course, this assumes that fitnessValue will always be non-negative.




          • Based on how the code is supposed to work, the return null; statement after the last for loop should never be reached. Since the compiler does not know that, you could insert an assert false; before the return statement. It is also possible to use assert statements with a detail message, for example like this:



            assert false : "totalScore: " + totalScore;






          share|improve this answer





















          • Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
            – Rafalsky
            May 26 at 21:32






          • 1




            @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
            – Stingy
            May 26 at 22:06












          up vote
          1
          down vote










          up vote
          1
          down vote










          • In the second loop, the loop where you update runningScore, there is no need to check whether rnd >= runningScore, because at the first loop iteration, it will be true by default, and at every subsequent iteration, runningScore will be equal to the runningScore of the previous iteration plus the fitnessValue of the previous individual, and if this value were greater than (or even equal to) rnd, then the loop would have already been terminated at the previous iteration. In fact, you could rewrite this loop to:



            for (Individual ind : pool) 
            runningScore += ind.fitnessValue;
            if (rnd <= runningScore)
            return ind;




            That way, you only have to perform the addition once, saving performance. Of course, this assumes that fitnessValue will always be non-negative.




          • Based on how the code is supposed to work, the return null; statement after the last for loop should never be reached. Since the compiler does not know that, you could insert an assert false; before the return statement. It is also possible to use assert statements with a detail message, for example like this:



            assert false : "totalScore: " + totalScore;






          share|improve this answer














          • In the second loop, the loop where you update runningScore, there is no need to check whether rnd >= runningScore, because at the first loop iteration, it will be true by default, and at every subsequent iteration, runningScore will be equal to the runningScore of the previous iteration plus the fitnessValue of the previous individual, and if this value were greater than (or even equal to) rnd, then the loop would have already been terminated at the previous iteration. In fact, you could rewrite this loop to:



            for (Individual ind : pool) 
            runningScore += ind.fitnessValue;
            if (rnd <= runningScore)
            return ind;




            That way, you only have to perform the addition once, saving performance. Of course, this assumes that fitnessValue will always be non-negative.




          • Based on how the code is supposed to work, the return null; statement after the last for loop should never be reached. Since the compiler does not know that, you could insert an assert false; before the return statement. It is also possible to use assert statements with a detail message, for example like this:



            assert false : "totalScore: " + totalScore;







          share|improve this answer













          share|improve this answer



          share|improve this answer











          answered May 26 at 21:04









          Stingy

          1,888212




          1,888212











          • Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
            – Rafalsky
            May 26 at 21:32






          • 1




            @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
            – Stingy
            May 26 at 22:06
















          • Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
            – Rafalsky
            May 26 at 21:32






          • 1




            @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
            – Stingy
            May 26 at 22:06















          Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
          – Rafalsky
          May 26 at 21:32




          Thanks, for an answer. Is it a good idea to use an assert on production code? For me it was always a feature it could be used for testing and debugging.
          – Rafalsky
          May 26 at 21:32




          1




          1




          @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
          – Stingy
          May 26 at 22:06




          @Rafalsky Yes, testing and debugging is exactly what assertions are for, which is why they are disabled by default and have to be explicitly enabled with the JVM option -ea. I did not intend to suggest the usage of assertions for anything other than testing and debugging. After all, one of your individuals might be a superhero with infinite fitness, and if you're unlucky and the call to Math.random() yields 0, you'll have a NaN infestation in your method, and the statement presumed to be unreachable will, in fact, be executed.
          – Stingy
          May 26 at 22:06












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195191%2fpicking-from-a-list-of-individuals-based-on-their-fitness-values%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Python Lists

          Aion

          JavaScript Array Iteration Methods