title: Simulated Binary Crossover (SBX) crossover operator in Scala genetic algorithm (GA) library
body: <p>I work on a very little research team to create/adapt a Genetic Algorithm library in Scala for distributed computation with Scientific Worklow System, in our case  we use the open source OpenMole software (<a href="http://www.openmole.org/" rel="nofollow noreferrer">http://www.openmole.org/</a>).</p>
  
  <p>Recently, i try to understand and re-implement the SBX crossover operator written in JMetal Metaheuristics library (<a href="http://jmetal.sourceforge.net/" rel="nofollow noreferrer">http://jmetal.sourceforge.net/</a>) to adapt it in functionnal version in our Scala library. </p>
  
  <p>I write some code, but i need our advice or your validation about the SBX defined into java library, because the source code (<a href="http://jmetal.svn.sourceforge.net/viewvc/jmetal/trunk/jmetal/operators/crossover/SBXCrossover.java?revision=288&amp;view=markup" rel="nofollow noreferrer" title="pdf">src in svn</a>) doesn't appear equal to the original equation written here : <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.33.7291&amp;rep=rep1&amp;type=pdf" rel="nofollow noreferrer">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.33.7291&amp;rep=rep1&amp;type=pdf</a> at page 30, in annexe A</p>
  
  <p><img src="https://i.stack.imgur.com/DNYjB.gif" alt="BetaEquation"></p>
  
  <p>First question, i don't understand the java version of JMetal, why  they use two different beta values ?!</p>
  
  <ul>
  <li><strong>beta1</strong> which use in the equation the first arg of min[(y1 - yL), ...] and </li>
  <li><strong>beta2</strong> which use the second arg of min [... , (yu - y2)])</li>
  </ul>
  
  <p><strong>Beta</strong> 1 and 2 are used for computation of <strong>alpha</strong> value and two (so here and in jmetal we have also two alpha different value alpha1 and 2) ...</p>
  
  <p>Same problem/question, we have  in jmetal two computation for <strong>betaq</strong> (java code) or in Deb equation, result of : <img src="https://i.stack.imgur.com/b0T4X.gif" alt="betaoverlined"></p>
  
  <p>Second question, what is the meaning of the symbol <img src="https://i.stack.imgur.com/b0T4X.gif" alt="betaoverlined"> used in (2) and (3) procedure in pseudo-algorithm of SBX, and the difference with simple <strong>beta</strong> ? Especially when we want to compute children/offsprings of crossover parents, like here :</p>
  
  <p><img src="https://i.stack.imgur.com/iq6t4.gif" alt="enter image description here"></p>
  
  <h2>Edit</h2>
  
  <ul>
  <li><p>Correct a no-op if/else block  </p></li>
  <li><p>Author of code in jmetal give me the link of original source code of Nsga-II algorithm, and he explain me that description of SBX by Deb differs from his implementation :/</p>
  
  <p><a href="http://www.iitk.ac.in/kangal/codes.shtml" rel="nofollow noreferrer">http://www.iitk.ac.in/kangal/codes.shtml</a></p>
  
  <p>I don't understand the difference between the description and the implementation in jmetal and original source code, do you have an explanation ?</p></li>
  <li><p>Correct if/else return for map</p></li>
  </ul>
  
  <h2>Start of translation into scala</h2>
  
  <pre class="lang-scala prettyprint-override"><code>  class SBXBoundedCrossover[G &lt;: GAGenome, F &lt;: GAGenomeFactory[G]](rate: Random =&gt; Double = _.nextDouble) extends CrossOver [G, F] {
  
    def this(rate: Double) = this( _ =&gt; rate)
  
    def crossOver (genomes : IndexedSeq [G], factory: F) (implicit aprng : Random) = {
      val g1 = genomes.random
      val g2 = genomes.random
      val crossoverRate = rate(aprng)
      val EPS =  1.0e-14
      val numberOfVariables = g1.wrappedValues.size
      val distributionIndex = 2
  
      val variableToMutate = (0 until g1.wrappedValues.size).map{x =&gt; !(aprng.nextDouble &lt; 0.5)}
  
      //crossover probability
      val offspring = {
  
        if (aprng.nextDouble &lt; crossoverRate) {      
          (variableToMutate zip (g1.wrappedValues zip g2.wrappedValues)) map {
            case (b, (g1e, g2e)) =&gt;
              if(b) {
                if (abs(g1e - g2e) &gt; EPS){
  
                  val y1 = min(g1e, g2e)
                  val y2 = max(g2e, g1e)
  
                  var yL = 0.0 //g1e.getLowerBound
                  var yu = 1.0 //g1e.getUpperBound  
                  var rand = aprng.nextDouble   // ui
  
                  var beta1 = 1.0 + (2.0 * (y1 - yL)/(y2 - y1))
                  var alpha1 = 2.0 - pow(beta1,-(distributionIndex+1.0))
                  var betaq1 = computebetaQ(alpha1,distributionIndex,rand)
  
                  //calcul offspring 1 en utilisant betaq1, correspond au β barre
                  var c1 = 0.5 * ((y1 + y2) - betaq1 * (y2 - y1)) 
  
                  // -----------------------------------------------
  
                  var beta2 = 1.0 + (2.0 * (yu - y2) / (y2 - y1))
                  var alpha2 = 2.0 - pow(beta2, -(distributionIndex + 1.0))
  
                  var betaq2 = computebetaQ(alpha2,distributionIndex,rand)
  
                  //calcul offspring2 en utilisant betaq2
                  var c2 = 0.5 * ((y1 + y2) + betaq2 * (y2 - y1))
  
                  if (c1 &lt; yL) c1 = yL
                  if (c1 &gt; yu) c1 = yu
  
                  if (c2 &lt; yL) c2 = yL
                  if (c2 &gt; yu) c2 = yu   
  
                  if (aprng.nextDouble &lt;= 0.5) {
                    (c2,c1)
                  } else {
                    (c1, c2) 
                  }
  
                }else{
                  (g1e, g2e)
                }
  
              }else{
                (g2e, g1e)
              }
          }
  
        }else{
          // not so good here ...
          (g1.wrappedValues zip g2.wrappedValues)
        }
      }
      (factory.buildGenome(offspring.map{_._1}),  factory.buildGenome(offspring.map{_._2}))
    }
  
    def computebetaQ(alpha:Double,  distributionIndex:Double,  rand:Double):Double = { 
      if (rand &lt;= (1.0/alpha)){
        pow ((rand * alpha),(1.0 / (distributionIndex + 1.0)))
      } else {
        pow ((1.0 / (2.0 - rand * alpha)),(1.0 / (distributionIndex + 1.0)))
      } 
    }
  </code></pre>
  
  <p>Thanks a lot for your advice, or help in this problem.</p>
  
  <p>SR</p>