在规则中使用CountableValueRange

问题描述 投票:0回答:1

我目前正在为共享一些资源的任务构建调度应用程序。每个任务可能会使用一定百分比的资源。

我需要检查Drools规则是并行任务对每个共享资源的使用不超过100%。

所以代码看起来像:

@Data
public class Resource {
   @PlanningId
   private Integer id;

   private String label;
}
public class ResourceUsage {
   @PlanningId
   private Integer id;

   private Resource resource;

   private int usagePercent;

}

要安排的实体

@Data
@PlanningEntity
public class TaskAssignment {
   @PlanningId
   private Integer id;

   @PlanningVariable(valueRangeProviderRefs = { "slotRange" })
   private Integer timeSlot;

   private int duration;
   private ResourceUsage resourceUsage;

   public Integer getEndingSlot() {
        return timeSlot + duration;
   }
}

最后是解决方案

@Data
@PlanningSolution
public class PlanningSolution {
  @PlanningId
  private Integer id;

  @PlanningEntityCollectionProperty
  private List<TaskAssignment> tasks = new ArrayList<>();

  @ValueRangeProvider(id = "slotRange")
  public CountableValueRange<Integer> getSlotRange() {
        return ValueRangeFactory.createIntValueRange(0, 10_000);
  }

  @ProblemFactCollectionProperty
  private Set<Resource> resources = new TreeSet<>();
}

由于我使用Lombok以避免编写它们,所以没有设置者和获取者。

过去,我使用一个时隙类,并且编写规则来遍历时隙集合很容易,我能够按时隙检查每个资源的全局使用情况,并在使用量大于100%。

由于内存使用存在问题,我决定将TimeSlot类转换为CountableValueRange,但是现在,我不知道如何创建与范围的每个值匹配的规则。执行与以前相同的计算。

有没有办法或者我必须切换回TimeSlot类?

编辑:一种影子计划实体中包含的影子变量可以解决问题吗?

java optaplanner
1个回答
0
投票

我终于找到了一种编写规则的方法,该规则使我避免在时隙上进行迭代。这个想法是在分配开始时计算使用量]

rule "Maximum usage of a resource"
       when
             $r : Resource()
             $p : TaskAssignment($id1 : id, $ts : timeSlot != null,
                                 resourceUsage!.ressource==$r,
                                 $usage : resourceUsage!.usagePercent);
             accumulate(TaskAssignment(timeSlot != null, timeSlot <= $ts, 
                                      endingSlot > $ts, id != $id1, 
                                      resourceUsage!.ressource==$r, 
                                      $rate : resourceUsage!.usagePercent);
                                  $s:sum($rate);
                                  $s + $usage > 100) 
       then
             scoreHolder.addHardConstraintMatch(kcontext, 100-($s + $usage));         
end
© www.soinside.com 2019 - 2024. All rights reserved.