Skip to content

Commit

Permalink
GreatDekugeAcceptor modified to does not use doubles, and rest adaped…
Browse files Browse the repository at this point in the history
… to that. Also mulitple small changes for pull request
  • Loading branch information
Boris Kocian authored and ge0ffrey committed Jul 11, 2019
1 parent 92ef299 commit 81924ab
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import org.optaplanner.core.api.score.Score;
import org.optaplanner.core.config.AbstractConfig;
import org.optaplanner.core.config.heuristic.policy.HeuristicConfigPolicy;
import org.optaplanner.core.config.localsearch.decider.acceptor.stepcountinghillclimbing.StepCountingHillClimbingType;
Expand Down Expand Up @@ -76,8 +77,8 @@ public class AcceptorConfig extends AbstractConfig<AcceptorConfig> {
protected StepCountingHillClimbingType stepCountingHillClimbingType = null;

protected String greatDelugeStartingWaterLevel = null;
protected Double greatDelugeRainSpeed = null;
protected Double greatDelugeRainSpeedRatio = null;
protected String greatDelugeRainSpeedScore = null;

@Deprecated
public List<Class<? extends Acceptor>> getAcceptorClassList() {
Expand Down Expand Up @@ -249,12 +250,12 @@ public void setGreatDelugeStartingWaterLevel(String greatDelugeStartingWaterLeve
this.greatDelugeStartingWaterLevel = greatDelugeStartingWaterLevel;
}

public Double getGreatDelugeRainSpeed() {
return greatDelugeRainSpeed;
public String getGreatDelugeRainSpeedScore() {
return greatDelugeRainSpeedScore;
}

public void setGreatDelugeRainSpeed(Double greatDelugeRainSpeed) {
this.greatDelugeRainSpeed = greatDelugeRainSpeed;
public void setGreatDelugeRainSpeedScore(String greatDelugeRainSpeedScore) {
this.greatDelugeRainSpeedScore = greatDelugeRainSpeedScore;
}

public Double getGreatDelugeRainSpeedRatio() {
Expand Down Expand Up @@ -525,26 +526,30 @@ public Acceptor buildAcceptor(HeuristicConfigPolicy configPolicy) {
acceptorList.add(acceptor);
}
if ((acceptorTypeList!= null && acceptorTypeList.contains(AcceptorType.GREAT_DELUGE))
|| greatDelugeRainSpeed != null || greatDelugeRainSpeedRatio != null) {
|| greatDelugeRainSpeedRatio != null || greatDelugeRainSpeedScore != null) {
GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();

if (greatDelugeRainSpeed != null && greatDelugeRainSpeedRatio != null) {
throw new IllegalArgumentException("You can use only rainSpeed or rainSpeedRatio at a time.");
if (greatDelugeRainSpeedScore != null && greatDelugeRainSpeedRatio != null) {
throw new IllegalArgumentException("The greatDelugeRainSpeedScore (" + greatDelugeRainSpeedScore
+ ") and greatDelugeRainSpeedRatio (" + greatDelugeRainSpeedRatio
+ ") cannot be both non null.");
}

if (greatDelugeRainSpeed != null) {
acceptor.setRainSpeed(greatDelugeRainSpeed);
}
if (greatDelugeRainSpeedRatio != null) {
acceptor.setRainSpeedRatio(greatDelugeRainSpeedRatio);
}

if (greatDelugeRainSpeedScore != null) {
acceptor.setRainSpeedScore(configPolicy.getScoreDefinition().parseScore(greatDelugeRainSpeedScore));
}

if (greatDelugeStartingWaterLevel != null) {
acceptor.setInitialLevels(configPolicy.getScoreDefinition()
acceptor.setInitialWaterLevels(configPolicy.getScoreDefinition()
.parseScore(greatDelugeStartingWaterLevel));
}
acceptorList.add(acceptor);
}

if (acceptorList.size() == 1) {
return acceptorList.get(0);
} else if (acceptorList.size() > 1) {
Expand Down Expand Up @@ -606,10 +611,10 @@ public void inherit(AcceptorConfig inheritedConfig) {
inheritedConfig.getStepCountingHillClimbingType());
greatDelugeStartingWaterLevel = ConfigUtils.inheritOverwritableProperty(greatDelugeStartingWaterLevel,
inheritedConfig.getGreatDelugeStartingWaterLevel());
greatDelugeRainSpeed = ConfigUtils.inheritOverwritableProperty(greatDelugeRainSpeed,
inheritedConfig.getGreatDelugeRainSpeed());
greatDelugeRainSpeedRatio = ConfigUtils.inheritOverwritableProperty(greatDelugeRainSpeedRatio,
inheritedConfig.getGreatDelugeRainSpeedRatio());
greatDelugeRainSpeedScore = ConfigUtils.inheritOverwritableProperty(greatDelugeRainSpeedScore,
inheritedConfig.getGreatDelugeRainSpeedScore());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,110 +9,79 @@

public class GreatDelugeAcceptor extends AbstractAcceptor {

private Score initialLevel = null;
private Score initialWaterLevels = null;
private Score currentWaterLevel = null;

private Double rainSpeed = null;
private Double rainSpeedRatio = DEFAULT_RAIN_SPEED_RATIO;

private int levelsLength = -1;
private double[] initialLevelScoreLevels;
private double[] levelScoreLevels;

private double levelMinimum = 0;
private static final double THRESHOLD = .0000001;
private Score rainSpeedScore = null;

// Good value to come out from. Source: https://github.com/UniTime/cpsolver from Tomas Muller
private static final double DEFAULT_RAIN_SPEED_RATIO = 0.99_999_995;

public void setInitialLevels(Score initialLevel) { this.initialLevel = initialLevel; }

public Score getInitialLevels() { return this.initialLevel; }
public Score getRainSpeedScore() {
return this.rainSpeedScore;
}

public void setRainSpeed(Double rainSpeed) {
this.rainSpeed = rainSpeed;
public void setRainSpeedScore(Score rainSpeedScore) {
this.rainSpeedScore = rainSpeedScore;
this.rainSpeedRatio = null;
}

public Double getRainSpeed() { return this.rainSpeed; }
public Score getInitialWaterLevels() {
return this.initialWaterLevels;
}

public void setRainSpeedRatio(Double rainSpeedRatio) {this.rainSpeedRatio = rainSpeedRatio; }
public void setInitialWaterLevels(Score initialLevel) {
this.initialWaterLevels = initialLevel;
}

public Double getRainSpeedRatio() { return this.rainSpeedRatio; }
public Double getRainSpeedRatio() {
return this.rainSpeedRatio;
}

public double[] getLevelScoreLevels() { return this.levelScoreLevels; }
public void setRainSpeedRatio(Double rainSpeedRatio) {
this.rainSpeedRatio = rainSpeedRatio;
}

public void phaseStarted(LocalSearchPhaseScope phaseScope) {
super.phaseStarted(phaseScope);

if (initialLevel != null) {
for (double initialLevelLevel : ScoreUtils.extractLevelDoubles(initialLevel)) {
if (initialWaterLevels != null) {
for (double initialLevelLevel : ScoreUtils.extractLevelDoubles(initialWaterLevels)) {
if (initialLevelLevel < 0.0) {
throw new IllegalArgumentException("The initial level (" + initialLevel
+ ") cannot have negative level (" + initialLevelLevel + ").");
throw new IllegalArgumentException("The initial level (" + initialWaterLevels
+ ") cannot have negative level (" + initialLevelLevel + ").");
}
}
initialLevelScoreLevels = ScoreUtils.extractLevelDoubles(initialLevel);
levelScoreLevels = initialLevelScoreLevels;
} else {
double[] initialLevelScoreLevelsNegative;
initialLevelScoreLevelsNegative = ScoreUtils.extractLevelDoubles(phaseScope.getBestScore());
levelScoreLevels = initialLevelScoreLevelsNegative;
currentWaterLevel = initialWaterLevels;

for (int i = 0; i < levelScoreLevels.length; i++) {
if (Math.abs(levelScoreLevels[i]) < THRESHOLD) {
continue;
}
levelScoreLevels[i] = -levelScoreLevels[i];
}
} else {
currentWaterLevel = phaseScope.getBestScore().negate();
}
levelsLength = levelScoreLevels.length;
}

public void phaseEnded(LocalSearchPhaseScope phaseScope) {
super.phaseEnded(phaseScope);
initialLevelScoreLevels = null;
levelScoreLevels = null;
levelsLength = -1;
initialWaterLevels = null;
rainSpeedRatio = DEFAULT_RAIN_SPEED_RATIO;
rainSpeedScore = null;
}

@Override
public boolean isAccepted(LocalSearchMoveScope moveScope) {

Score moveScore = moveScope.getScore();
double[] moveScoreLevels = ScoreUtils.extractLevelDoubles(moveScore);

for (int i = 0; i < levelsLength; i++) {
double moveScoreLevel = moveScoreLevels[i];
double levelScoreLevel = levelScoreLevels[i];

double isZeroIfEqual = Math.abs(moveScoreLevel + levelScoreLevel);

if (moveScoreLevel > -levelScoreLevel) {
// Checks if given score is better than water level, if so, move is accepted.
return true;
} else if (!(isZeroIfEqual < THRESHOLD)) {
// Returns false when above condition is not met and, new score and water level are not equal.
return false;
} else if (i == levelsLength - 1){
// Returns true when new score and water level are equal and it is last iteration of cycle.
return true;
}
}
return true;

return moveScore.compareTo(currentWaterLevel.negate()) >= 0;
}

// change water level at the beginning of the step
public void stepStarted(LocalSearchStepScope stepScope) {
super.stepEnded(stepScope);
for (int i = 0; i < levelsLength; i++) {
if (rainSpeed != null) {
levelScoreLevels[i] = levelScoreLevels[i] - rainSpeed;
} else if (rainSpeedRatio != null) {
levelScoreLevels[i] = levelScoreLevels[i] * rainSpeedRatio;
}
if (levelScoreLevels[i] < levelMinimum) {
levelScoreLevels[i] = levelMinimum;
}
if (rainSpeedScore != null) {
currentWaterLevel = currentWaterLevel.subtract(rainSpeedScore);
} else {
currentWaterLevel = currentWaterLevel.multiply(rainSpeedRatio);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import org.optaplanner.core.impl.solver.scope.DefaultSolverScope;
import org.optaplanner.core.impl.testdata.domain.TestdataSolution;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;


Expand All @@ -24,8 +21,8 @@ public class GreatDelugeAcceptorTest extends AbstractAcceptorTest {
public void isAcceptedPositiveLevelSingleScoreRainSpeed() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(SimpleScore.of(1100));
acceptor.setRainSpeed(100.0);
acceptor.setInitialWaterLevels(SimpleScore.of(1100));
acceptor.setRainSpeedScore(SimpleScore.of(100));

DefaultSolverScope<TestdataSolution> solverScope = new DefaultSolverScope<>();
solverScope.setBestScore(SimpleScore.of(-1000));
Expand Down Expand Up @@ -99,8 +96,8 @@ public void isAcceptedPositiveLevelSingleScoreRainSpeed() {
public void isAcceptedPositiveLevelMultipleScoreRainSpeed() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(HardMediumSoftScore.of(0, 200, 500));
acceptor.setRainSpeed(100.0);
acceptor.setInitialWaterLevels(HardMediumSoftScore.of(0, 200, 500));
acceptor.setRainSpeedScore(HardMediumSoftScore.of(0,100,100));

DefaultSolverScope<TestdataSolution> solverScope = new DefaultSolverScope<>();
solverScope.setBestScore(HardMediumSoftScore.of(0, -200, -1000));
Expand Down Expand Up @@ -145,7 +142,7 @@ public void isAcceptedPositiveLevelMultipleScoreRainSpeed() {
public void isAcceptedPositiveLevelMultipleScoreRainSpeedRatio() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(HardMediumSoftScore.of(0, 200, 500));
acceptor.setInitialWaterLevels(HardMediumSoftScore.of(0, 200, 500));
acceptor.setRainSpeedRatio(0.9);

DefaultSolverScope<TestdataSolution> solverScope = new DefaultSolverScope<>();
Expand Down Expand Up @@ -191,82 +188,24 @@ public void isAcceptedPositiveLevelMultipleScoreRainSpeedRatio() {
public void negativeWaterLevelSingleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(SimpleScore.of(-100));
acceptor.setInitialWaterLevels(SimpleScore.of(-100));
try {
acceptor.phaseStarted(null);
} catch (IllegalArgumentException e) {
assertEquals("The initial level (" + acceptor.getInitialLevels()
assertEquals("The initial level (" + acceptor.getInitialWaterLevels()
+ ") cannot have negative level (" + "-100.0" + ").", e.getMessage());
}
}
@Test
public void negativeWaterLevelMultipleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(HardMediumSoftScore.parseScore("1hard/-1medium/2soft"));
acceptor.setInitialWaterLevels(HardMediumSoftScore.parseScore("1hard/-1medium/2soft"));
try {
acceptor.phaseStarted(null);
} catch (IllegalArgumentException e) {
assertEquals("The initial level (" + acceptor.getInitialLevels()
assertEquals("The initial level (" + acceptor.getInitialWaterLevels()
+ ") cannot have negative level (" + "-1.0" + ").", e.getMessage());
}
}

@Test
public void parsingLevelScoreLevelsFromInitialLevelSingleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(SimpleScore.of(150));
double[] actualScore = {150};
acceptor.phaseStarted(null);

assertTrue(Arrays.equals(actualScore, acceptor.getLevelScoreLevels()));
}

@Test
public void parsingLevelScoreLevelsFromInitialLevelMultipleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setInitialLevels(HardMediumSoftScore.parseScore("1hard/15medium/24soft"));
double[] actualScore = {1, 15, 24};
acceptor.phaseStarted(null);

assertTrue(Arrays.equals(actualScore, acceptor.getLevelScoreLevels()));
}

@Test
public void parsingLevelScoreLevelsFromPhaseBestScoreSingleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setRainSpeedRatio(0.9995);

DefaultSolverScope<TestdataSolution> solverScope = new DefaultSolverScope<>();
solverScope.setBestScore(SimpleScore.of(-66));
LocalSearchPhaseScope<TestdataSolution> phaseScope = new LocalSearchPhaseScope<>(solverScope);
LocalSearchStepScope<TestdataSolution> lastCompletedStepScope = new LocalSearchStepScope<>(phaseScope, -1);
lastCompletedStepScope.setScore(SimpleScore.of(-66));
phaseScope.setLastCompletedStepScope(lastCompletedStepScope);
acceptor.phaseStarted(phaseScope);
double[] actualScore = {66};

assertTrue(Arrays.equals(actualScore, acceptor.getLevelScoreLevels()));
}

@Test
public void parsingLevelScoreLevelsFromPhaseBestScoreMultipleScore() {

GreatDelugeAcceptor acceptor = new GreatDelugeAcceptor();
acceptor.setRainSpeedRatio(0.959595);

DefaultSolverScope<TestdataSolution> solverScope = new DefaultSolverScope<>();
solverScope.setBestScore(HardMediumSoftScore.of(-5, 0, -24));
LocalSearchPhaseScope<TestdataSolution> phaseScope = new LocalSearchPhaseScope<>(solverScope);
LocalSearchStepScope<TestdataSolution> lastCompletedStepScope = new LocalSearchStepScope<>(phaseScope, -1);
lastCompletedStepScope.setScore(HardMediumSoftScore.of(-5, 0, -24));
phaseScope.setLastCompletedStepScope(lastCompletedStepScope);
acceptor.phaseStarted(phaseScope);
double[] actualScore = {5, 0, 24};

assertTrue(Arrays.equals(actualScore, acceptor.getLevelScoreLevels()));
}
}
}

0 comments on commit 81924ab

Please sign in to comment.