- Extracted fitness function to separate class instead of Lambda

- Cleaned up javadoc
- Refactored fitness function code to add more significative variables names
This commit is contained in:
Donato Rimenti 2018-02-24 14:05:44 +01:00
parent b0d83a88be
commit 67599b1cbc
3 changed files with 62 additions and 35 deletions

View File

@ -3,7 +3,6 @@ package com.baeldung.algorithms.multiswarm;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
// TODO: Auto-generated Javadoc
/** /**
* Represents a collection of {@link Particle}. * Represents a collection of {@link Particle}.
* *

View File

@ -0,0 +1,52 @@
package com.baeldung.algorithms.multiswarm;
/**
* Specific fitness function implementation to solve the League of Legends
* problem. This is the problem statement: <br>
* <br>
* In League of Legends, a player's Effective Health when defending against
* physical damage is given by E=H(100+A)/100, where H is health and A is armor.
* Health costs 2.5 gold per unit, and Armor costs 18 gold per unit. You have
* 3600 gold, and you need to optimize the effectiveness E of your health and
* armor to survive as long as possible against the enemy team's attacks. How
* much of each should you buy? <br>
* <br>
*
* @author Donato Rimenti
*
*/
public class LolFitnessFunction implements FitnessFunction {
/*
* (non-Javadoc)
*
* @see
* com.baeldung.algorithms.multiswarm.FitnessFunction#getFitness(long[])
*/
@Override
public double getFitness(long[] particlePosition) {
long health = particlePosition[0];
long armor = particlePosition[1];
// No negatives values accepted.
if (health < 0 && armor < 0) {
return -(health * armor);
} else if (health < 0) {
return health;
} else if (armor < 0) {
return armor;
}
// Checks if the solution is actually feasible provided our gold.
double cost = (health * 2.5) + (armor * 18);
if (cost > 3600) {
return 3600 - cost;
} else {
// Check how good is the solution.
long fitness = (health * (100 + armor)) / 100;
return fitness;
}
}
}

View File

@ -22,46 +22,22 @@ public class MultiswarmUnitTest {
public MayFailRule mayFailRule = new MayFailRule(); public MayFailRule mayFailRule = new MayFailRule();
/** /**
* Tests the multiswarm algorithm with a generic problem. * Tests the multiswarm algorithm with a generic problem. The problem is the
* * following: <br>
* The problem is the following: * <br>
*
* In League of Legends, a player's Effective Health when defending against * In League of Legends, a player's Effective Health when defending against
* physical damage is given by E=H(100+A)/100, where H is health and A is * physical damage is given by E=H(100+A)/100, where H is health and A is
* armor. * armor. Health costs 2.5 gold per unit, and Armor costs 18 gold per unit.
* * You have 3600 gold, and you need to optimize the effectiveness E of your
* Health costs 2.5 gold per unit, and Armor costs 18 gold per unit. You
* have 3600 gold, and you need to optimize the effectiveness E of your
* health and armor to survive as long as possible against the enemy team's * health and armor to survive as long as possible against the enemy team's
* attacks. How much of each should you buy? * attacks. How much of each should you buy? <br>
* * <br>
* The solution is H = 1080, A = 50 for a total fitness of 1620. * The solution is H = 1080, A = 50 for a total fitness of 1620. Tested with
* * 50 swarms each with 1000 particles.
* Tested with 50 swarms each with 1000 particles.
*/ */
@Test @Test
public void givenMultiswarm_whenThousandIteration_thenSolutionFound() { public void givenMultiswarm_whenThousandIteration_thenSolutionFound() {
Multiswarm multiswarm = new Multiswarm(50, 1000, values -> { Multiswarm multiswarm = new Multiswarm(50, 1000, new LolFitnessFunction());
// No negatives values accepted.
if (values[0] < 0 && values[1] < 0) {
return -(values[0] * values[1]);
} else if (values[0] < 0) {
return values[0];
} else if (values[1] < 0) {
return values[1];
}
// Checks if the solution is actually feasible provided our gold.
double cost = (values[0] * 2.5) + (values[1] * 18);
if (cost > 3600) {
return 3600 - cost;
} else {
// Check how good is the solution.
long fitness = (values[0] * (100 + values[1])) / 100;
return fitness;
}
});
// Iterates 1000 times through the main loop and prints the result. // Iterates 1000 times through the main loop and prints the result.
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {