29.4. 分数配置


商业优化器将搜索具有最高 分数的解决方案这个示例使用 Hard SoftScore,这意味着 Business Optimizer 将查找没有硬约束(需要填充的硬件要求)且尽可能少的软约束(尽量降低维护成本)的解决方案。

当然,业务优化器需要告知这些特定于域的分数限制。您可以使用 Java 或 dols 语言定义限制。

29.4.1. 使用 Java 配置分数计算

定义分数功能的一种方法是以普通 Java 实施接口 EasyScoreCalculator

流程

  1. 在 Cloud BalancingSolverConfig.xml 文件中,添加或取消注释设置:

      <scoreDirectorFactory>
        <easyScoreCalculatorClass>org.optaplanner.examples.cloudbalancing.optional.score.CloudBalancingEasyScoreCalculator</easyScoreCalculatorClass>
      </scoreDirectorFactory>
    Copy to Clipboard Toggle word wrap
  2. 实施 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);
        }
    
    }
    Copy to Clipboard Toggle word wrap

即使我们优化了上述代码以使用 Maps 来迭代 processList 一次,它仍然会很慢,因为它不会进行增量分数计算。

要修复这个问题,可以使用增量 Java 分数计算或 drools 分数计算。本指南中不涵盖增量 Java 分数计算。

29.4.2. 使用 drools 配置分数计算

您可以使用 dols 规则语言(DRL)来定义限制。dols 分数计算使用增量计算,每个分数约束都会写成一个或多个分数规则。

通过使用决策引擎进行分数计算,您可以与其他 dols 技术集成,如分区表(基于 XLS 或 Web)、Business Central 和其他支持的功能。

流程

  1. 在 classpath 中添加 scoreDrl 资源,以使用决策引擎作为分数功能。在 Cloud BalancingSolverConfig.xml 文件中,添加或取消注释设置:

      <scoreDirectorFactory>
        <scoreDrl>org/optaplanner/examples/cloudbalancing/solver/cloudBalancingScoreRules.drl</scoreDrl>
      </scoreDirectorFactory>
    Copy to Clipboard Toggle word wrap
  2. 创建硬限制。这些限制可确保所有计算机有足够的 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
    Copy to Clipboard Toggle word wrap
  3. 创建软约束。此约束可最小化维护成本。只有在满足硬限制时才会应用它:

    例 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
    Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat