麦田

不积跬步无以至千里.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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;
    }
}

 

posted on 2025-02-17 14:34  一些记录  阅读(50)  评论(0)    收藏  举报