# Optaplanner

## Example

We will be using OptaPlanner to find the roots for a polynomial. We start by defining our planning entity, PolynomialEntity, which will calculate the polynomial value for a specific value. The polynomial we will use is

$f(x) = 2x^3 + 3x^2 + x + 6$

This polynomial has a root for $$x=-2$$. The entity is then

Define the Lesson:

import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.valuerange.ValueRange;
import org.optaplanner.core.api.domain.valuerange.ValueRangeFactory;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.domain.variable.PlanningVariable;

@PlanningEntity
public class PolynomialEntity {
private double value;

private PolynomialEntity() {
}

public PolynomialEntity(double i) {
this.value = i;
}

@Override public String toString() {
return "PolynomialEntity{" +
"value=" + value +
'}';
}

@PlanningVariable(valueRangeProviderRefs = { "polynomialRange" })
public Double getValue() {
return value;
}

public void setValue(Double value) {
this.value = value;
}

@ValueRangeProvider(id = "polynomialRange")
public ValueRange<Double> getCountValue() {
return ValueRangeFactory.createDoubleValueRange(-100, 100);
}

public double calculate() {
return 2.0 * Math.pow(this.value, 3) + 3 * Math.pow(this.value, 2) + this.value + 6;
}

}


We now define the solution PolynomialSolution:

import org.optaplanner.core.api.domain.solution.PlanningEntityProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.score.buildin.simplebigdecimal.SimpleBigDecimalScore;

@PlanningSolution
public class PolynomialSolution {

@PlanningEntityProperty
PolynomialEntity polynomialEntity;

@PlanningScore
private SimpleBigDecimalScore score;

public PolynomialSolution() {
this.polynomialEntity = new PolynomialEntity(0.0);
}

public PolynomialSolution(PolynomialEntity polynomialEntity) {
this.polynomialEntity = polynomialEntity;
}

public PolynomialEntity getPolynomialEntity() {
return polynomialEntity;
}

public void setPolynomialEntity(PolynomialEntity polynomialEntity) {
this.polynomialEntity = polynomialEntity;
}

public SimpleBigDecimalScore getScore() {
return score;
}

}


And the score calculator:

import java.math.BigDecimal;

import org.optaplanner.core.api.score.buildin.simplebigdecimal.SimpleBigDecimalScore;
import org.optaplanner.core.api.score.calculator.EasyScoreCalculator;

public class PolynomialEasyScoreCalculator implements EasyScoreCalculator<PolynomialSolution, SimpleBigDecimalScore> {

@Override
public SimpleBigDecimalScore calculateScore(PolynomialSolution polynomialSolution) {
PolynomialEntity entity = polynomialSolution.getPolynomialEntity();
double y = -Math.abs(entity.calculate());
return SimpleBigDecimalScore.of(BigDecimal.valueOf(y));
}

}


Finally we run it

import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.config.solver.SolverConfig;
import org.optaplanner.core.config.solver.termination.TerminationConfig;

SolverFactory<PolynomialSolution> solverFactory = SolverFactory.create(new SolverConfig()
.withSolutionClass(PolynomialSolution.class)
.withEntityClasses(PolynomialEntity.class)
.withEasyScoreCalculatorClass(PolynomialEasyScoreCalculator.class)
.withTerminationConfig(new TerminationConfig().withSecondsSpentLimit(5L)));


PolynomialEntity{value=-2.0000069627535737}