模拟二进制交叉(SBX)在Scala遗传算法(GA)库中的交叉算子

我在一个非常小的研究团队中工作,我们正在创建/调整一个用于分布式计算的Scala遗传算法库,我们使用的是开源的OpenMole软件(http://www.openmole.org/)。

最近,我试图理解并重新实现JMetal元启发式库中编写的SBX交叉算子(http://jmetal.sourceforge.net/),以便在我们的Scala库中适应其功能版本。

我写了一些代码,但我想请教你们关于Java库中定义的SBX的建议或验证,因为源代码(svn中的源码)似乎与此处撰写的原始方程不符:http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.33.7291&rep=rep1&type=pdf 第30页,附录A

BetaEquation

第一个问题,我不理解JMetal的Java版本,为什么他们使用两个不同的beta值?!

  • beta1 在方程中使用第一个参数min[(y1 – yL), …] 和
  • beta2 使用第二个参数min[…, (yu – y2)])

Beta 1和2用于计算alpha值和两个(因此在这里和jmetal中我们也有两个不同的alpha值alpha1和2)…

同样的问题/疑问,在jmetal中我们有两种计算betaq的方法(Java代码)或者在Deb方程中,结果是:betaoverlined

第二个问题,符号betaoverlined在SBX伪算法的(2)和(3)过程中使用,其含义是什么,与简单的beta有什么区别?特别是当我们想要计算交叉父母的后代时,就像这里一样:

enter image description here

编辑

  • 修正了一个无操作的if/else块

  • jmetal代码的作者给了我Nsga-II算法原始源代码的链接,他向我解释说Deb对SBX的描述与他的实现不同:/

    http://www.iitk.ac.in/kangal/codes.shtml

    我不理解描述与jmetal和原始源代码中的实现之间的区别,你有解释吗?

  • 修正if/else返回的map

开始翻译成Scala

  class SBXBoundedCrossover[G <: GAGenome, F <: GAGenomeFactory[G]](rate: Random => Double = _.nextDouble) extends CrossOver [G, F] {  def this(rate: Double) = this( _ => 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 => !(aprng.nextDouble < 0.5)}    //交叉概率    val offspring = {      if (aprng.nextDouble < crossoverRate) {              (variableToMutate zip (g1.wrappedValues zip g2.wrappedValues)) map {          case (b, (g1e, g2e)) =>            if(b) {              if (abs(g1e - g2e) > 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)                //使用betaq1计算后代1,对应于β条                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)                //使用betaq2计算后代2                var c2 = 0.5 * ((y1 + y2) + betaq2 * (y2 - y1))                if (c1 < yL) c1 = yL                if (c1 > yu) c1 = yu                if (c2 < yL) c2 = yL                if (c2 > yu) c2 = yu                   if (aprng.nextDouble <= 0.5) {                  (c2,c1)                } else {                  (c1, c2)                 }              }else{                (g1e, g2e)              }            }else{              (g2e, g1e)            }        }      }else{        // 这里不太好...        (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 <= (1.0/alpha)){      pow ((rand * alpha),(1.0 / (distributionIndex + 1.0)))    } else {      pow ((1.0 / (2.0 - rand * alpha)),(1.0 / (distributionIndex + 1.0)))    }   }

非常感谢您的建议或帮助解决这个问题。

SR


回答:

Reyman64,你的问题正是我一直在寻找的答案。谢谢你。

我拿了你链接的论文和Deb的实现代码,并试图理解两者。为此,我几乎对每一行代码都进行了注释。它们仅在beta的计算上有所不同。

由于Deb在他的NSGA-II实现中使用了这段代码,我将坚持使用这个版本的算法。

如果有人和我一样(不理解如何实现SBX),我将我的评论留在了下面的gist中,请查看。

https://gist.github.com/Tiagoperes/1779d5f1c89bae0cfdb87b1960bba36d

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注