AbstractPersistable 类 实体类的基类
package com.apsbyoptaplanner.domain; import java.io.Serializable; import org.apache.commons.lang3.builder.CompareToBuilder; import org.optaplanner.core.api.domain.lookup.PlanningId; public class AbstractPersistable implements Serializable, Comparable<AbstractPersistable> { protected Long id; protected AbstractPersistable() { } protected AbstractPersistable(long id) { this.id = id; } @PlanningId public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Override public int compareTo(AbstractPersistable other) { return new CompareToBuilder().append(getClass().getName(), other.getClass().getName()).append(id, other.id) .toComparison(); } @Override public String toString() { return getClass().getName().replaceAll(".*\\.", "") + "-" + id; } }
机器类
package com.apsbyoptaplanner.domain; import org.optaplanner.core.api.domain.entity.PlanningEntity; public class Machine extends AbstractPersistable{ private String yarnType; private int capacity; private int cost; public String getYarnType() { return yarnType; } public void setYarnType(String yarnType) { this.yarnType = yarnType; } public int getCapacity() { return capacity; } public void setCapacity(int capacity) { this.capacity = capacity; } public int getCost() { return cost; } public void setCost(int cost) { this.cost = cost; } public Machine(int id, String yarnType, int capacity, int cost) { super(id); this.yarnType = yarnType; this.capacity = capacity; this.cost = cost; } }
任务类
package com.apsbyoptaplanner.domain; import org.optaplanner.core.api.domain.entity.PlanningEntity; import org.optaplanner.core.api.domain.variable.PlanningVariable; @PlanningEntity public class Task extends AbstractPersistable{ private String requiredYarnType; private int amount; private Machine machine; public String getRequiredYarnType() { return requiredYarnType; } public void setRequiredYarnType(String requiredYarnType) { this.requiredYarnType = requiredYarnType; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount = amount; } @PlanningVariable(valueRangeProviderRefs={"machineRange"}) public Machine getMachine() { return machine; } public void setMachine(Machine machine) { this.machine = machine; } public Task(){} public Task(int id, String requiredYarnType, int amount) { super(id); this.requiredYarnType = requiredYarnType; this.amount = amount; } }
任务分配类 用来存储结果
package com.apsbyoptaplanner.domain; import java.util.List; import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty; import org.optaplanner.core.api.domain.solution.PlanningScore; import org.optaplanner.core.api.domain.solution.PlanningSolution; import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty; import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider; import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; @PlanningSolution public class TaskAssignment extends AbstractPersistable{ private HardSoftScore score; private List<Machine> machineList; private List<Task> taskList; @PlanningScore public HardSoftScore getScore() { return score; } public void setScore(HardSoftScore score) { this.score = score; } @ProblemFactCollectionProperty @ValueRangeProvider(id = "machineRange") public List<Machine> getMachineList() { return machineList; } public void setMachineList(List<Machine> machineList) { this.machineList = machineList; } @PlanningEntityCollectionProperty @ValueRangeProvider(id = "taskRange") public List<Task> getTaskList() { return taskList; } public void setTaskList(List<Task> taskList) { this.taskList = taskList; } public TaskAssignment(List<Machine> machineList, List<Task> taskList) { //super(0); this.machineList = machineList; this.taskList = taskList; } public TaskAssignment(){} }
约束类
package com.apsbyoptaplanner.solver; import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore; import org.optaplanner.core.api.score.stream.Constraint; import org.optaplanner.core.api.score.stream.ConstraintFactory; import org.optaplanner.core.api.score.stream.ConstraintProvider; import org.optaplanner.core.api.score.stream.Joiners; import static org.optaplanner.core.api.score.stream.ConstraintCollectors.sum; import com.apsbyoptaplanner.domain.Machine; import com.apsbyoptaplanner.domain.Task; public class TaskAssignmentConstraintProvider implements ConstraintProvider{ @Override public Constraint[] defineConstraints(ConstraintFactory constraintFactory) { // TODO Auto-generated method stub return new Constraint[] { // Hard constraints yarnTypeMatchConflict(constraintFactory), machineCapacityConflict(constraintFactory), machineCost_usedConflict(constraintFactory) }; } Constraint yarnTypeMatchConflict(ConstraintFactory constraintFactory) { // A room can accommodate at most one lesson at the same time. return constraintFactory // Select each pair of 2 different lessons ... .forEach(Task.class) .filter((task) -> task.getRequiredYarnType() != task.getMachine().getYarnType()) .penalize(HardSoftScore.ONE_HARD) .asConstraint("yarnTypeMatch"); } Constraint machineCapacityConflict(ConstraintFactory constraintFactory) { // A room can accommodate at most one lesson at the same time. return constraintFactory // Select each pair of 2 different lessons ... .forEach(Task.class) .filter(task -> task.getMachine() != null) .groupBy(Task::getMachine,sum(Task::getAmount)) .filter((machine, amount) -> amount > machine.getCapacity()) .penalize(HardSoftScore.ONE_HARD) .asConstraint("machineCapacity"); } Constraint machineCost_usedConflict(ConstraintFactory constraintFactory) { // A room can accommodate at most one lesson at the same time. return constraintFactory // Select each pair of 2 different lessons ... .forEach(Task.class) .groupBy(Task::getMachine) .penalize(HardSoftScore.ONE_SOFT,(machine) -> machine.getCost()) .asConstraint("machineCost_used"); } }
程序启动
package com.apsbyoptaplanner; import java.io.InputStream; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.acme.schooltimetabling.domain.Lesson; import org.acme.schooltimetabling.domain.TimeTable; import org.acme.schooltimetabling.solver.TimeTableConstraintProvider; import org.optaplanner.core.api.solver.Solver; import org.optaplanner.core.api.solver.SolverFactory; import org.optaplanner.core.config.solver.SolverConfig; import com.apsbyoptaplanner.domain.Machine; import com.apsbyoptaplanner.domain.Task; import com.apsbyoptaplanner.domain.TaskAssignment; import com.apsbyoptaplanner.solver.TaskAssignmentConstraintProvider; public class App { public static void main(String[] args) { startPlan(); } private static void startPlan(){ List<Machine> machines = getMachines(); List<Task> tasks = getTasks(); SolverFactory<TaskAssignment> solverFactory = SolverFactory.create(new SolverConfig() .withSolutionClass(TaskAssignment.class) .withEntityClasses(Task.class) .withConstraintProviderClass(TaskAssignmentConstraintProvider.class) // The solver runs only for 5 seconds on this small dataset. // It's recommended to run for at least 5 minutes ("5m") otherwise. .withTerminationSpentLimit(Duration.ofSeconds(5))); Solver<TaskAssignment> solver = solverFactory.buildSolver(); TaskAssignment unassignment = new TaskAssignment(machines, tasks); TaskAssignment assigned = solver.solve(unassignment);//启动引擎 List<Machine> machinesAssigned = assigned.getTaskList().stream().map(Task::getMachine).distinct().collect(Collectors.toList()); for(Machine machine : machinesAssigned) { System.out.print("\n" + machine + ":"); List<Task> tasksInMachine = assigned.getTaskList().stream().filter(x -> x.getMachine().equals(machine)).collect(Collectors.toList()); for(Task task : tasksInMachine) { System.out.print("->" + task); } } } private static List<Machine> getMachines() { // 六个机台 Machine m1 = new Machine(1, "Type_A", 300, 100); Machine m2 = new Machine(2, "Type_A", 1000, 100); Machine m3 = new Machine(3, "TYPE_B", 1000, 300); Machine m4 = new Machine(4, "TYPE_B", 1000, 100); Machine m5 = new Machine(5, "Type_C", 1100, 100); Machine m6 = new Machine(6, "Type_D", 900, 100); List<Machine> machines = new ArrayList<Machine>(); machines.add(m1); machines.add(m2); machines.add(m3); machines.add(m4); machines.add(m5); machines.add(m6); return machines; } private static List<Task> getTasks(){ // 10个任务 Task t1 = new Task(1, "Type_A", 10000); Task t2 = new Task(2, "Type_A", 100); Task t3 = new Task(3, "Type_A", 100); Task t4 = new Task(4, "Type_A", 100); Task t5 = new Task(5, "TYPE_B", 800); Task t6 = new Task(6, "TYPE_B", 500); Task t7 = new Task(7, "Type_C", 800); Task t8 = new Task(8, "Type_C", 300); Task t9 = new Task(9, "Type_D", 400); Task t10 = new Task(10, "Type_D", 500); List<Task> tasks = new ArrayList<Task>(); tasks.add(t1); tasks.add(t2); tasks.add(t3); tasks.add(t4); tasks.add(t5); tasks.add(t6); tasks.add(t7); tasks.add(t8); tasks.add(t9); tasks.add(t10); return tasks; } }

浙公网安备 33010602011771号