64 lines
2.8 KiB
Java
64 lines
2.8 KiB
Java
package jobshop.solvers;
|
|
|
|
import jobshop.Instance;
|
|
import jobshop.encodings.ResourceOrder;
|
|
import jobshop.encodings.Schedule;
|
|
import jobshop.encodings.Task;
|
|
import jobshop.solvers.neighborhood.Neighborhood;
|
|
import jobshop.solvers.neighborhood.Nowicki;
|
|
|
|
import java.time.format.ResolverStyle;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
|
|
/** An empty shell to implement a descent solver. */
|
|
public class DescentSolver implements Solver {
|
|
|
|
final Neighborhood neighborhood;
|
|
final Solver baseSolver;
|
|
|
|
/** Creates a new descent solver with a given neighborhood and a solver for the initial solution.
|
|
*
|
|
* @param neighborhood Neighborhood object that should be used to generates neighbor solutions to the current candidate.
|
|
* @param baseSolver A solver to provide the initial solution.
|
|
*/
|
|
public DescentSolver(Neighborhood neighborhood, Solver baseSolver) {
|
|
this.neighborhood = neighborhood;
|
|
this.baseSolver = baseSolver;
|
|
}
|
|
|
|
@Override
|
|
public Optional<Schedule> solve(Instance instance, long deadline, int randomness, int randomRunNumber) {
|
|
Schedule schedule = baseSolver.solve(instance, deadline,randomness,randomRunNumber).get();
|
|
ResourceOrder order = new ResourceOrder(schedule);
|
|
ResourceOrder result = order;
|
|
Boolean bestFound = false;
|
|
Integer best = Integer.MAX_VALUE;
|
|
while(!bestFound) {
|
|
List<ResourceOrder> neighbours = neighborhood.generateNeighbors(order);
|
|
try {
|
|
Integer finalBest = best;
|
|
order = neighbours.stream()
|
|
.filter(e -> e.toSchedule().get().isValid()) // removes invalid solutions
|
|
.filter(e -> e.toSchedule().get().makespan() < finalBest) // removes solutions that do not improve
|
|
.sorted(Comparator.comparing(e -> e.toSchedule().get().makespan())) // takes the best
|
|
.toArray(ResourceOrder[]::new)[0];
|
|
result = order;
|
|
best = order.toSchedule().get().makespan();
|
|
System.out.println("\u001b[32m" + "Current best makespam : " + best + "\u001b[0m, "
|
|
+ "\u001b[33m" + "Number of neighbours : " + getNumberOfNeighbours(neighbours) + "\u001b[0m");
|
|
} catch (ArrayIndexOutOfBoundsException e) { // no solution found ==> stop
|
|
bestFound = true;
|
|
}
|
|
}
|
|
return result.toSchedule();
|
|
}
|
|
// used to compute the number of neighbours seen
|
|
private int getNumberOfNeighbours(List<ResourceOrder> neighbours) {
|
|
return neighbours.stream()
|
|
.filter(e -> e.toSchedule().get().isValid()) // removes invalid solutions
|
|
.toArray(ResourceOrder[]::new).length;
|
|
}
|
|
|
|
}
|