首页 > 解决方案 > 在 Scala 中应用过滤器后更新对象值

问题描述

我有列表列表并在我的代码中将其称为 BAT。每个 BAT 有 2 个属性。第一个是位置,第二个是健身。对于 BAT 中的每个列表,我正在使用 Sphere 函数计算其适应度。基于适应度,我应用了过滤器,它只过滤那些适应度小于称为 GF 的对象的列表。这还给我 BAT。我的代码是

var GlobalBest_Fitness = Double.PositiveInfinit

var BAT = List.fill(N)(new BAT1(d, MinVal, MaxVal))

BAT.map { x =>
  x.fitness = sphere(x.position)
 }
 BAT.filter(_.Fitness < GF).map { x =>
  GF = x.Fitness
}   

def sphere(list: List[Double]): Double = {
 list.foldLeft(0.0)((x, xs) => x + xs * xs)
}
class BAT1 ( dim:Int  ,  min:Double  ,  max:Double) {

 val random = new Random()
 var position      : List[Double]      =   List.fill(dim)(random.nextDouble() * (max-min)+min )
 var fitness       :Double             =   math.random
}

此代码设置了 BAT 的最后一个成员的 GF 适应度,但我想将对象 GF 的值设置为具有最低适应度的列表的适应度。

这是一些解释问题的输出。BAT 有 5 个列表,

(List(-67.33460898977961, -71.09215709663737, 55.89607430834903, -43.23771807116002),14581.91575554507)
(List(90.12684307743376, 43.946793301728036, -93.06789837138616, -76.86083905559525),24623.390772205956)
(List(12.619843833260006, -86.17961848282789, 48.99208107528267, 24.69991428409682),10596.496873950442)
(List(96.24721330545535, 54.598176031247306, -92.20930457845513, -42.450241098519385),22549.06571516962)
(List(71.10095207554104, 74.02738064902607, 93.76767384566747, 40.917896190085656),21002.04935885428)


Output ==>> GF = 21002.04935885428

这是将 GF 的值设置为最后一个列表的适应度,它应该将其设置为最低值,即 10596.496873950442,即第三个列表的适应度。

该列表可能非常大,并且必须对其进行数百万次迭代。我想找到最佳解决方案。

标签: scalafunctional-programming

解决方案


根据我从问题中了解到的情况,您需要 BAT1 对象列表中的最小适应度值 ( List[BAT1])。

发现的问题:

无需稍后通过映射设置适应度,.map 用于列表/集合/monad 的转换(例如,您要将 List[A] 转换为 List[B])。

因此,您的 BAT1 课程应如下所示:

class BAT1(dim:Int, min:Double, max:Double) {
 val random = new Random()
 var position: List[Double] = List.fill(dim)(random.nextDouble() * (max-min)+min )
 val fitness: Double = sphere(position) //no need of var and can be directly computer here only
}

要获得最低的适应度,您不需要过滤

val minFitness = BAT.map(_.fitness).min
/* 
   we will first convert the list BAT which has type List[BAT1] to a
   List[Double] containing fitness of each BAT1 object in the list
   we will then get the minimum value in the List[Double] by .min method

   List[BAT1] -> List[Double] -> Double
*/

另一种方式:

val minFitness = BAT.minBy(_.fitness).fitness //please read about minBy, maxBy in Scala documentations.

推荐阅读