【教程8】optaplanner阴影变量

本文档详细介绍了OptaPlanner中的阴影变量,包括双向变量、锚点阴影变量、列表变量阴影变量及其应用场景。通过使用阴影变量,可以更自然地表达约束条件,例如在车辆路径问题中自动调整客户到达时间。OptaPlanner通过VariableListener来更新和维护阴影变量,确保解决方案的正确性。同时,文章提到了阴影变量的克隆和VariableListener的触发顺序等关键概念。
摘要由CSDN通过智能技术生成

optaplanner阴影变量

简介

阴影变量是一种规划变量,其正确值可以从真实规划变量的状态推断出来。尽管根据定义,这种变量违反了归一化原则,但在某些情况下使用阴影变量非常实用,特别是为了更自然地表达约束条件。例如,在带有时间窗口的车辆路径问题中,车辆到达客户的时间可以基于该车辆先前访问的客户(以及两个位置之间已知的行驶时间)进行计算。planningVariableListener

当车辆的客户发生变化时,每个客户的到达时间会自动调整。有关更多信息,请参见车辆路径领域模型

从评分计算的角度来看,阴影变量与其他任何规划变量一样。从优化的角度来看,OptaPlanner实际上只优化真实变量(并且大部分忽略阴影变量):它仅确保当真实变量发生变化时,任何相关的阴影变量也会相应地发生变化。

任何至少有一个阴影变量的类都是一个规划实体类(即使它没有真实的规划变量)。该类必须在求解器配置中定义,并带有@PlanningEntity注解。

一个真实规划实体类至少有一个真实规划变量,但也可以有阴影变量。一个阴影规划实体类没有真实的规划变量,至少有一个阴影规划变量。

有几种内置的阴影变量:

双向变量(反向关系阴影变量)

如果两个变量总是相互指向对方的实例(除非一侧指向null并且另一侧不存在),则这两个变量是双向变量。例如,如果A引用B,则B引用A。bidirectionalVariable

对于非链式规划变量,双向关系必须是多对一的关系。要映射两个规划变量之间的双向关系,请在源端(真实端)上使用@PlanningVariable注解普通规划变量:

@PlanningEntity
public class CloudProcess {
   

    @PlanningVariable(...)
    public CloudComputer getComputer() {
   
        return computer;
    }
    public void setComputer(CloudComputer computer) {
   ...}

}

然后,在另一侧(阴影侧)使用@InverseRelationShadowVariable注解,并将其放在集合(通常是Set或List)属性上:

@PlanningEntity
public class CloudComputer {
   

    @InverseRelationShadowVariable(sourceVariableName = "computer")
    public List<CloudProcess> getProcessList() {
   
        return processList;
    }

}

请将此类注册为规划实体,否则OptaPlanner将无法检测到它,并且阴影变量不会更新。sourceVariableName属性是getter方法返回类型上真实规划变量的名称(即另一侧的真实规划变量的名称)。

阴影属性(通常是集合,如List、Set或SortedSet)永远不能为null。如果没有真实变量引用该阴影实体,则它是一个空集合。此外,它必须是可变的集合,因为一旦OptaPlanner开始初始化或更改真实规划变量,它将相应地添加和删除这些阴影变量的集合中的元素。

对于链式规划变量,双向关系始终是一对一的关系。在这种情况下,真实端看起来像这样:

@PlanningEntity
public class Customer ... {
   

    @PlanningVariable(graphType = PlanningVariableGraphType.CHAINED, ...)
    public Standstill getPreviousStandstill() {
   
        return previousStandstill;
    }
    public void setPreviousStandstill(Standstill previousStandstill) {
   ...}

}

阴影端看起来像这样:

@PlanningEntity
public class Standstill {
   

    @InverseRelationShadowVariable(sourceVariableName = "previousStandstill")
    public Customer getNextCustomer() {
   
         return nextCustomer;
    }
    public void setNextCustomer(Customer nextCustomer) {
   
  • 34
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值