请先看上一篇:二、coudBalance 资源分配案例-CSDN博客
接下来我将给大家介绍第二种建模(可能有第三种,就交给大家自己去研究了)
一、开始建模。
①、资源对象
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-27 16:47
*/
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ComputerTwo extends AbstractPersistable {
/**
* cpu功率
*/
private Integer cpuPower;
/**
* 内存容量
*/
private Integer memoryCapacity;
/**
* 网络容量
*/
private Integer networkCapacity;
/**
* 维护费用
*/
private Integer cost;
}
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-27 16:48
*/
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ProcessesTwo extends AbstractPersistable {
/**
* 该进程需要的cpu
*/
private Integer cpu;
/**
* 该进程需要的内存
*/
private Integer ram;
}
②、问题解决对象
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-27 10:56
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@PlanningEntity
@SuperBuilder
public class CouldBalanceTwoSolve extends AbstractPersistable {
@PlanningVariable(valueRangeProviderRefs = {"processesRange"})
private ProcessesTwo processes;
@PlanningVariable(valueRangeProviderRefs = {"computerRange"})
private ComputerTwo computer;
}
③、规划类
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-27 16:49
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@PlanningSolution
@SuperBuilder
public class CouldBalanceTwoPlan extends AbstractPersistable {
/**
* 分值
*/
@PlanningScore
public HardSoftScore score;
/**
* 资源类(进程类)集合
*/
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "processesRange")
private List<ProcessesTwo> processesList;
/**
* 资源类(电脑类)集合
*/
@ProblemFactCollectionProperty
@ValueRangeProvider(id = "computerRange")
private List<ComputerTwo> computerList;
/**
* 问题解决方案类
*/
@PlanningEntityCollectionProperty
private List<CouldBalanceTwoSolve> couldBalanceTwoSolves;
}
这种建模方式是将资源对象与问题解决对象完全分离
二、约束建立
本例中我们可以得到两个硬约束,一个软约束;硬约束不可被打破,软约束尽量不要打破。
①、硬约束:
1、进程所需CPU功率之和不能超过电脑的CPU功率;
2、进程所需的内存之和不能超过电脑的内存容量。
②、软约束:
每台电脑不管维护多少个进程,他的维护费用都是一致的,尽量节省维护成本。
三、求解器
①、ConstraintStream求解器:
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-27 16:54
*/
public class CouldBalanceTwoConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[]{
cpuConflict(constraintFactory),
ramConflict(constraintFactory),
costConflict(constraintFactory)
};
}
/*****************************************************硬约束*********************************************************************/
private Constraint cpuConflict(ConstraintFactory constraintFactory) {
//接下来的代码有点类似于Stream流
return constraintFactory
//创建流
.from(CouldBalanceTwoSolve.class)
//进行分组
.groupBy((t) -> t.getComputer().getCpuPower(), ConstraintCollectors.sum((t) -> t.getProcesses().getCpu()))
//过滤出不满足电脑CPU>进程CPU之和的情况
.filter((cpu, sumCpu) -> cpu < sumCpu)
//进行扣分;关闭流
.penalize("Cpu conflict", HardSoftScore.ONE_HARD);
}
private Constraint ramConflict(ConstraintFactory constraintFactory) {
return constraintFactory.from(CouldBalanceTwoSolve.class)
//进行分组
.groupBy((t) -> t.getComputer().getMemoryCapacity(), ConstraintCollectors.sum((t) -> t.getProcesses().getRam()))
//过滤出不满足电脑内存>进程内存之和的情况
.filter((ram, sumRam) -> ram < sumRam)
//进行扣分
.penalize("Ram conflict", HardSoftScore.ONE_HARD);
}
/*****************************************************软约束****************************************************************************/
private Constraint costConflict(ConstraintFactory constraintFactory) {
return constraintFactory.from(CouldBalanceTwoSolve.class)
//分组
.groupBy(CouldBalanceTwoSolve::getComputer)
//去重
.distinct()
//扣分
.penalize("Cost Conflict", HardSoftScore.ONE_SOFT);
}
}
四、求解
/**
* @author Xiao Mi feng
* Created with IntelliJ IDEA
* @date 2024-01-29 14:35
*/
public class CouldBalanceTwoApp {
public static void main(String[] args) throws JsonProcessingException {
SolverFactory<CouldBalanceTwoPlan> objectSolverFactory = SolverFactory.create(new SolverConfig()
.withSolutionClass(CouldBalanceTwoPlan.class)
.withEntityClasses(CouldBalanceTwoSolve.class)
.withConstraintProviderClass(
CouldBalanceTwoConstraintProvider.class)
.withTerminationSpentLimit(Duration.ofSeconds(10))
);
CouldBalanceTwoPlan couldBalancePlan = generateDemoData();
CouldBalanceTwoPlan solve = objectSolverFactory.buildSolver().solve(couldBalancePlan);
String string = new ObjectMapper().writeValueAsString(solve);
System.out.println("string = " + string);
}
private static CouldBalanceTwoPlan generateDemoData() {
List<ComputerTwo> computerList = new ArrayList<>();
List<ProcessesTwo> processesList = new ArrayList<>();
List<CouldBalanceTwoSolve> couldBalanceTwoSolves = new ArrayList<>();
computerList.add(ComputerTwo.builder().cpuPower(6).memoryCapacity(6).id(1).cost(1).build());
computerList.add(ComputerTwo.builder().cpuPower(7).memoryCapacity(6).id(2).cost(1).build());
computerList.add(ComputerTwo.builder().cpuPower(5).memoryCapacity(6).id(3).cost(1).build());
computerList.add(ComputerTwo.builder().cpuPower(4).memoryCapacity(6).id(4).cost(1).build());
//computerList.add(ComputerTwo.builder().cpuPower(30).memoryCapacity(30).id(5).cost(1).build());
processesList.add(ProcessesTwo.builder().id(1).cpu(5).ram(5).build());
processesList.add(ProcessesTwo.builder().id(2).cpu(4).ram(3).build());
processesList.add(ProcessesTwo.builder().id(3).cpu(2).ram(3).build());
processesList.add(ProcessesTwo.builder().id(4).cpu(2).ram(1).build());
couldBalanceTwoSolves.add(CouldBalanceTwoSolve.builder().id(1).build());
couldBalanceTwoSolves.add(CouldBalanceTwoSolve.builder().id(2).build());
couldBalanceTwoSolves.add(CouldBalanceTwoSolve.builder().id(3).build());
couldBalanceTwoSolves.add(CouldBalanceTwoSolve.builder().id(4).build());
return CouldBalanceTwoPlan.builder().computerList(computerList).processesList(processesList).couldBalanceTwoSolves(couldBalanceTwoSolves).build();
}
}