29.4. 分数配置
商业优化器将搜索具有最高 分数的解决方案。这个示例使用 Hard SoftScore,这意味着 Business Optimizer 将查找没有硬约束(需要填充的硬件要求)且尽可能少的软约束(尽量降低维护成本)的解决方案。
当然,业务优化器需要告知这些特定于域的分数限制。您可以使用 Java 或 dols 语言定义限制。
29.4.1. 使用 Java 配置分数计算 复制链接链接已复制到粘贴板!
定义分数功能的一种方法是以普通 Java 实施接口 EasyScoreCalculator。
流程
在 Cloud
BalancingSolverConfig.xml文件中,添加或取消注释设置:<scoreDirectorFactory> <easyScoreCalculatorClass>org.optaplanner.examples.cloudbalancing.optional.score.CloudBalancingEasyScoreCalculator</easyScoreCalculatorClass> </scoreDirectorFactory>实施 compute
Score (Solution)方法,以返回Hard SoftScore实例。例 29.6. CloudBalancingEasyScoreCalculator.java
public class CloudBalancingEasyScoreCalculator implements EasyScoreCalculator<CloudBalance> { /** * A very simple implementation. The double loop can easily be removed by using Maps as shown in * {@link CloudBalancingMapBasedEasyScoreCalculator#calculateScore(CloudBalance)}. */ public HardSoftScore calculateScore(CloudBalance cloudBalance) { int hardScore = 0; int softScore = 0; for (CloudComputer computer : cloudBalance.getComputerList()) { int cpuPowerUsage = 0; int memoryUsage = 0; int networkBandwidthUsage = 0; boolean used = false; // Calculate usage for (CloudProcess process : cloudBalance.getProcessList()) { if (computer.equals(process.getComputer())) { cpuPowerUsage += process.getRequiredCpuPower(); memoryUsage += process.getRequiredMemory(); networkBandwidthUsage += process.getRequiredNetworkBandwidth(); used = true; } } // Hard constraints int cpuPowerAvailable = computer.getCpuPower() - cpuPowerUsage; if (cpuPowerAvailable < 0) { hardScore += cpuPowerAvailable; } int memoryAvailable = computer.getMemory() - memoryUsage; if (memoryAvailable < 0) { hardScore += memoryAvailable; } int networkBandwidthAvailable = computer.getNetworkBandwidth() - networkBandwidthUsage; if (networkBandwidthAvailable < 0) { hardScore += networkBandwidthAvailable; } // Soft constraints if (used) { softScore -= computer.getCost(); } } return HardSoftScore.valueOf(hardScore, softScore); } }
即使我们优化了上述代码以使用 Maps 来迭代 processList 一次,它仍然会很慢,因为它不会进行增量分数计算。
要修复这个问题,可以使用增量 Java 分数计算或 drools 分数计算。本指南中不涵盖增量 Java 分数计算。
29.4.2. 使用 drools 配置分数计算 复制链接链接已复制到粘贴板!
您可以使用 dols 规则语言(DRL)来定义限制。dols 分数计算使用增量计算,每个分数约束都会写成一个或多个分数规则。
通过使用决策引擎进行分数计算,您可以与其他 dols 技术集成,如分区表(基于 XLS 或 Web)、Business Central 和其他支持的功能。
流程
在 classpath 中添加
scoreDrl资源,以使用决策引擎作为分数功能。在 CloudBalancingSolverConfig.xml文件中,添加或取消注释设置:<scoreDirectorFactory> <scoreDrl>org/optaplanner/examples/cloudbalancing/solver/cloudBalancingScoreRules.drl</scoreDrl> </scoreDirectorFactory>创建硬限制。这些限制可确保所有计算机有足够的 CPU、RAM 和网络带宽来支持其所有进程:
例 29.7. cloudBalancingScoreRules.drl - Hard Constraints
... import org.optaplanner.examples.cloudbalancing.domain.CloudBalance; import org.optaplanner.examples.cloudbalancing.domain.CloudComputer; import org.optaplanner.examples.cloudbalancing.domain.CloudProcess; global HardSoftScoreHolder scoreHolder; // ############################################################################ // Hard constraints // ############################################################################ rule "requiredCpuPowerTotal" when $computer : CloudComputer($cpuPower : cpuPower) accumulate( CloudProcess( computer == $computer, $requiredCpuPower : requiredCpuPower); $requiredCpuPowerTotal : sum($requiredCpuPower); $requiredCpuPowerTotal > $cpuPower ) then scoreHolder.addHardConstraintMatch(kcontext, $cpuPower - $requiredCpuPowerTotal); end rule "requiredMemoryTotal" ... end rule "requiredNetworkBandwidthTotal" ... end创建软约束。此约束可最小化维护成本。只有在满足硬限制时才会应用它:
例 29.8. cloudBalancingScoreRules.drl - Soft Constraints
// ############################################################################ // Soft constraints // ############################################################################ rule "computerCost" when $computer : CloudComputer($cost : cost) exists CloudProcess(computer == $computer) then scoreHolder.addSoftConstraintMatch(kcontext, - $cost); end