4

I'm working on a GA. My problem is as follows. I have a fitness function which takes a couple of values:

A - value which is huge, but less important for example 999999. (weight of importance 30% of the final result)

B - value couple times smaller but more important for example 50. (weight of importance 70% of final result)

I assume that both of these values strive to infinity. How to build a fitness function where I have something like:

long calculateFitness(A, weightOfA, B, weightOfB);

and the result will be any long number which will put B variable as much more important.

Matthew
  • 1,412
  • 2
  • 20
  • 35
  • I think this depends on how A and B grows. E.g. If A grows exponentially, you maybe want to use log(A) in your fitness function. – maraca Sep 08 '19 at 20:02
  • This could work. You mean get log(A) and log(B) multiplayed by their weights? How to pick correct log base? Both values grows in different speed. More important value B, grows couple times slower than A. – Paweł Cieśluk Sep 08 '19 at 20:19
  • It's not really clear what you want. Under what conditions would (a1,b1) be better than (a2,b2)? You are saying things like "weight of importance", but what do you actually mean by that? – Matt Timmermans Sep 09 '19 at 02:55
  • I can give you an example of how my AI behaves and how it gains fitness. For every step in correct direction it gets +1 point. A variable means number of steps in right direction. If you reach certain place you get 50 points which is variable B. The main problem to solve is to get highest score at variable B. Variable A significantly shorts time to find right path. – Paweł Cieśluk Sep 09 '19 at 08:10

2 Answers2

1

You need an upper bound and lower bound for each objective value. If it is not possible to estimate the upper bound (lower bound) you could consider the highest (lowest) values at your current iteration.

Let the upper bound for objective A and B be respectively ubA and ubB, and lower bounds for objective A and B be lbA and lbB. Here I assume that lbA and lbB are equal to 0, and ubA and ubB are respectively 999999 and 50.

Now assume that you have a valueA = 642465 and a valueB = 47. You could do:

let lbA = 0;
let ubA = 999999;
let valueA = 642465

let lbB = 0;
let ubB = 50
let valueB = 47

let remappedA = remap(valueA, lbA, ubA, 0, 1);
let remappedB = remap(valueB, lbB, ubB, 0, 1);
let weightedValue = getWeightedValue(0.3, remappedA, 0.7, remappedB);

console.log(valueA + ' remapped to ' + remappedA);
console.log(valueB + ' remapped to ' + remappedB);
console.log("Weighted objective value: " + weightedValue);

function remap(n, start1, stop1, start2, stop2) {
  return ((n - start1)/(stop1 - start1)) * (stop2 - start2) + start2;
}

function getWeightedValue(weightA, valueA, weightB, valueB){
   return  weightA * valueA + weightB * valueB;
}

Your output value should be 0.8507396927396926

WillEnsaba
  • 756
  • 1
  • 8
  • 23
  • Thx for answer, I will check it later. But I cannot predict max value for both variables. As it is fitness function, it strive to infinity. Every new organism finds better path in infinity game. Will it does it job when I will update ubA and ubB to it's highest recent value? That's why using log has some benefits. – Paweł Cieśluk Sep 10 '19 at 07:45
  • 1
    You should try updating the upper bound as you find new highest values, as you commented. If you cant calculate the upper bound unfortunately that's the only way I can think to solve the problem. – WillEnsaba Sep 10 '19 at 11:15
  • This was exaclty what I was looking for, thank you. With your equation it is possible to add any factor, scale and set proper weight to it. Despite this using double as a fitness causes some problems in library that I'm using, like NaN or Infnity. By now if I found higher valueA, I make ubA = valueA*1.2. This avoids getting 1 for every new high. If you have any more suggestions I would be thankful. – Paweł Cieśluk Sep 10 '19 at 21:02
  • And one more thing. Can you explain to me what are variables start2, stop2 in remap? This is scale boundry? – Paweł Cieśluk Sep 10 '19 at 22:29
  • 1
    The remap function means map value `n` which goes from `start1` to `stop1` to the range `start2` to `stop2`. – WillEnsaba Sep 11 '19 at 12:56
0

lets say you have {V1,W1} and {v2,W2} where V represents the value, and W represents weight of importance of it.

calcualteFintess(V1,W1, V2,W2){

valuePart1 = V1*W1;

valuePart2 = V2*W2;

and do your magic with valuePart1 and valuePart2 }

For example:

V1 = 120, W1 = 30% V2 = 30, W2 = 70%

Result will be calculated from 120*0.3 = 36 with 30*0.7 = 21 and it will contain 30% of value V1 and 70% of value V2. This is how i have understood your question, please correct me if I am wrong.

madnan
  • 161
  • 1
  • 7
  • It's not that simple, becouse A and B in my example are from a different range and I don't know upper limit of their range . For value A = 999999 is average number, for value B = 50 is average number. If I would took your aproche I will end up with A overwhelming B, which is incorrect. – Paweł Cieśluk Sep 08 '19 at 19:23
  • You could also get x = A / B, and depending on x together with weights of values of A and B you could calculate the percentage / participation of each value in the result. – madnan Sep 08 '19 at 19:28
  • This one is closer, but I'm not entirely sure how to scale those values dynamically when A and B gets a now upper limit. – Paweł Cieśluk Sep 08 '19 at 19:33