乐趣区

关于javascript:PlanningSolution类讲解

内容概要
通过这篇文章,咱们来学习将 ProblemFact、PlanningEntity 连贯在一起以及负责与 OptaPlanner 交互的 Solution 类。

ProblemFact 实例
一个布局问题的数据集须要被蕴含在一个类中,供求解器求解。该解决方案类同时代表了布局问题和(求解完结后)解决方案。它被注解为 @PlanningSolution 注解。例如,云资源优化的例子中,解决方案类是 CloudBalance 类,它蕴含一个 computerList 列表,一个 processList 列表。

@PlanningSolution
@XStreamAlias("CloudBalance")
public class CloudBalance extends AbstractPersistable {
    private List<CloudComputer> computerList;
    private List<CloudProcess> processList;
    ......
}
复制代码

一个布局问题实际上是一个未解决的布局解决方案,或者换个说法,一个未初始化的解决方案。

例如,在云资源优化例子中,那个 CloudBalance 类有 @PlanningSolution 注解,然而未解决的 processList 类中的每个 CloudProcess 都还没有被调配到一个计算机(他们的 computer 属性为空)。这不是一个可行的解决方案,它甚至不是一个可能的解决方案,这是一个未初始化的解决方案。

Solution 类
一个 Solution 类持有所有的 ProblemFact、PlanningEntity 和一个 Score。增加 @PlanningSolution 注解。例如,一个 loudBalance 实例持有所有计算机、过程的列表。

@PlanningSolution
@XStreamAlias("CloudBalance")
public class CloudBalance extends AbstractPersistable {
    private List<CloudComputer> computerList;
    private List<CloudProcess> processList;
    ......
}
复制代码

求解器配置须要申明布局解决方案类:

<solver xmlns=”https://www.optaplanner.org/xsd/solver” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation="https://www.optaplanner.org/xsd/solver https://www.optaplanner.org/xsd/solver/solver.xsd">


<solutionClass>org.optaplanner.examples.nqueens.domain.NQueens</solutionClass>

</solver>
复制代码
Solution 中的 PlanningEntity
OptaPlanner 须要从 Solution 实例中提取 PlanningEntity 实例。它通过调用每一个被 @PlanningEntityCollectionProperty 正文的 getter(或字段)来取得这些汇合。

@PlanningSolution
public class NQueens {
    ...

    private List<Queen> queenList;

    @PlanningEntityCollectionProperty
    public List<Queen> getQueenList() {return queenList;}

}
复制代码

能够有多个 @PlanningEntityCollectionProperty 注解的属性。那些甚至能够返回一个具备雷同实体类类型的汇合,也能够返回一个数组。

@PlanningEntityCollectionProperty 注解须要在具备 @PlanningSolution 注解的类中的一个属性上。它在没有该注解的父类或子类中被疏忽。

在极少数状况下,一个布局实体可能是一个属性:在其 getter 办法(或字段)上应用 @PlanningEntityProperty 来代替。如果启用,这两个注解也能够被主动发现。

Solution 中的 Score
一个 @PlanningSolution 类须要一个分数属性(或字段),须要增加 @PlanningScore 注解。如果分数还没有被计算,那么分数属性就是空的。分数属性的类型与你的用例的具体分数实现无关。例如,NQueens 应用一个 SimpleScore,CloudBalance 应用的是 HardSoftScore。

@PlanningSolution
public class NQueens {
    ...

    private SimpleScore score;

    @PlanningScore
    public SimpleScore getScore() {return score;}
    public void setScore(SimpleScore score) {this.score = score;}

}
复制代码

大多数用例都应用 HardSoftScore:

@PlanningSolution
public class CloudBalance {
    ...

    private HardSoftScore score;

    @PlanningScore
    public HardSoftScore getScore() {return score;}

    public void setScore(HardSoftScore score) {this.score = score;}

}
复制代码

有些用例会应用其余分数类型。

Solution 中的 ProblemFact
对于束缚流和 Drools 分数计算,OptaPlanner 须要从 Solution 实例中提取 ProblemFact 实例。它通过调用每一个带有 @ProblemFactCollectionProperty 注解的办法(或字段)来取得这些汇合。所有由这些办法返回的对象都能够被束缚流或 Drools 规定所应用。例如,在 CloudBalance 中,所有的 computerList 是问题事实。

@PlanningSolution
@XStreamAlias("CloudBalance")
public class CloudBalance extends AbstractPersistable {

    private List<CloudComputer> computerList;

    private List<CloudProcess> processList;

    @XStreamConverter(HardSoftScoreXStreamConverter.class)
    private HardSoftScore score;

    public CloudBalance() {}

    public CloudBalance(long id, List<CloudComputer> computerList, List<CloudProcess> processList) {super(id);
        this.computerList = computerList;
        this.processList = processList;
    }

    @ValueRangeProvider(id = "computerRange")
    @ProblemFactCollectionProperty
    public List<CloudComputer> getComputerList() {return computerList;}

    public void setComputerList(List<CloudComputer> computerList) {this.computerList = computerList;}

    @PlanningEntityCollectionProperty
    public List<CloudProcess> getProcessList() {return processList;}
}
复制代码

所有的 ProblemFact 都会主动插入到 Drools 工作存内存,请留神在它们的属性上增加注解。

而且能够有多个 @ProblemFactCollectionProperty 注解的成属性。这些属性甚至能够返回具备雷同类别类型的汇合,但它们不应该两次返回雷同的实例,它也能够返回一个数组。

@ProblemFactCollectionProperty 注解须要在一个有 @PlanningSolution 注解的类中的成员上。它在父类或没有该注解的子类上会被疏忽。

在极少数状况下,ProblemFact 可能是一个对象:在其办法(或字段)上应用 @ProblemFactProperty 代替。

扩大 ProblemFact
有些 ProblemFact 一开始并未在业务模型中的体现,然而这些 ProblemFact 数据能够简化束缚规定的编写,在提交求解之前,将这些数据计算出来作为一个 ProblemFact 放在 Solution 类内,能够是求解器更快、更简略的进行求解。

例如,在考试中,每两个至多共享一个学生的考试科目,就会创立一个的 ProblemFact 问题事实

TopicConflict。@ProblemFactCollectionProperty
    private List<TopicConflict> calculateTopicConflictList() {List<TopicConflict> topicConflictList = new ArrayList<TopicConflict>();
        for (Topic leftTopic : topicList) {for (Topic rightTopic : topicList) {if (leftTopic.getId() < rightTopic.getId()) {
                    int studentSize = 0;
                    for (Student student : leftTopic.getStudentList()) {if (rightTopic.getStudentList().contains(student)) {studentSize++;}
                    }
                    if (studentSize > 0) {topicConflictList.add(new TopicConflict(leftTopic, rightTopic, studentSize));
                    }
                }
            }
        }
        return topicConflictList;
    }
复制代码

当分数束缚须要查看是否有两个具备独特学生的题目的考试被安顿在一起(取决于束缚:在同一时间,在一排,或在同一天),TopicConflict 实例能够被用作问题事实,而不是必须联合每两个学生实例,在求解过程中去计算,这样会大大降低 OptaPlanner 求解的效率。

主动扫描属性
与其明确配置每个属性(或字段)注解,有些也能够由 OptaPlanner 主动推导进去。例如,在 CloudBalance 的例子中:

@PlanningSolution(autoDiscoverMemberType = AutoDiscoverMemberType.FIELD)public class CloudBalance {

    // 主动发现为  @ProblemFactCollectionProperty
    @ValueRangeProvider(id = "computerRange") // Not (yet) auto discovered
    private List<CloudComputer> computerList;

    // 主动发现为  @PlanningEntityCollectionProperty
    private List<CloudProcess> processList;

    // 主动发现为 @PlanningScore
    private HardSoftScore score;

    ...
}
复制代码

AutoDiscoverMemberType 反对:

NONE:没有主动发现。
FIELD:主动发现 @PlanningSolution 类中的所有字段。
GETTER:主动发现 @PlanningSolution 类上的所有 getter。
主动注解是基于字段类型(或 getter 返回类型):

@ProblemFactProperty:当它不是一个汇合、一个数组、一个 @PlanningEntity 类或一个分数时。
@ProblemFactCollectionProperty:当它是一个不是 @PlanningEntity 类的汇合(或数组)的类型时。
@PlanningEntityProperty:当它是一个配置的 @PlanningEntity 类或子类时。
@PlanningEntityCollectionProperty:当它是一个类型为配置的 @PlanningEntity 类或子类的汇合(或数组)。
@PlanningScore:当它是一个分数或子类时。
最初
如果你感觉此文对你有一丁点帮忙,点个赞。或者能够退出我的开发交换群:1025263163 互相学习,咱们会有业余的技术答疑解惑

如果你感觉这篇文章对你有点用的话,麻烦请给咱们的开源我的项目点点 star: http://github.crmeb.net/u/defu 不胜感激!

退出移动版