简体   繁体   中英

Updating object value after applying Filter in Scala

I am having List of List's and calling it BAT in my code. Each BAT has 2 attribute. First one is Position and second is fitness. For Every List in BAT , i am computing its fitness using Sphere function. Based on fitness i have applied Filter which filter only those list whom fitness is less than a object called GF. This return me BAT. My code is

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
}

This code set GF Fitness of last member of BAT but i want to set value of Object GF to Fitness of List with Lowest Fitness.

Here is some output to explain question. BAT with 5 Lists,

(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

This is seting value of GF to last List fitness, it should instead set it to Lowest value that is 10596.496873950442 that is fitness of third List.

This List could be very large and have to iterate over it millions of time. I want to find optimal solution.

According to what I understood from the question, you want a minimum fitness value from a List of BAT1 objects ( List[BAT1] ).

Problems noticed:

No need to set fitness later by mapping, .map is used for transformation of a list/collection/monad (eg, you want to convert a List[A] to List[B]).

So, your BAT1 class should look like:

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
}

To get the lowest fitness, you don't need to filter

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
*/

Another way:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM