内容概要通过本文,让我们学习连接ProblemFact、PlanningEntity并负责与OptaPlanner交互的Solution类。ProblemFact实例一个编程问题的数据集需要包含在一个类中以供求解器求解。解决方案类代表规划问题和(解决后)解决方案。它使用@PlanningSolution注释进行注释。例如,在云资源优化的例子中,解决方案类是CloudBalance类,它包含一个computerList列表和一个processList列表。@PlanningSolution@XStreamAlias("CloudBalance")publicclassCloudBalanceextendsAbstractPersistable{privateListcomputerList;私有列表processList;…}规划问题实际上是一个未解决的规划解,或者说是一个未初始化的解。例如,在云资源优化示例中,CloudBalance类使用@PlanningSolution注解,但未解析的processList类中的每个CloudProcess尚未分配给计算机(它们的计算机属性为空)。这不是一个可行的解决方案,它甚至不是一个可能的解决方案,它是一个未初始化的解决方案。解决方案类解决方案类包含所有ProblemFact、PlanningEntity和分数。添加@PlanningSolution注解。例如,一个loudBalance实例包含所有计算机、进程的列表。@PlanningSolution@XStreamAlias("CloudBalance")publicclassCloudBalanceextendsAbstractPersistable{privateListcomputerList;私有列表processList;…}复制代码Solver配置需要声明规划解决方案类:...org.optaplanner.examples.nqueens.domain.NQueens...复制代码Solution中的PlanningEntityOptaPlanner需要从Solution实例中提取PlanningEntity实例。它通过调用每个用@PlanningEntityCollectionProperty注释的getter(或字段)来获取这些集合。@PlanningSolutionpublicclassNQueens{...privateListqueenList;@PlanningEntityCollectionPropertypublicListgetQueenList(){returnqueenList;}}可以有多个@PlanningEntityCollectionProperty注解属性。这些甚至可以返回具有相同实体类类型的集合或数组。@PlanningEntityCollectionProperty批注在使用@PlanningSolution批注的类中的属性上是必需的。没有此注释的超类或子类将忽略它。在极少数情况下,规划实体可能是一个属性:改为在其getter方法(或字段)上使用@PlanningEntityProperty。如果启用,这两个注释也可以自动发现。ScoreinSolution一个@PlanningSolution类需要一个score属性(或字段),需要用@PlanningScore注解。如果尚未计算分数,则分数属性为空。分数属性的类型与您的用例的具体分数实现相关。例如,NQueens使用SimpleScore而CloudBalance使用HardSoftScore。@PlanningSolutionpublicclassNQueens{...私人SimpleScore分数;@PlanningScorepublicSimpleScoregetScore(){返回分数;}publicvoidsetScore(SimpleScorescore){this.score=score;}}PlanningSolutionpublicclassCloudBalance{...privateHardSoftScore分数;@PlanningScorepublicHardSoftScoregetScore(){返回分数;}publicvoidsetScore(HardSoftScorescore){this.score=score;}}一些用例使用其他分数类型。ProblemFactinSolution对于约束流和Drools分数计算,OptaPlanner需要从Solution实例中提取ProblemFact实例。它通过调用每个用@ProblemFactCollectionProperty注释的方法(或字段)来获取这些集合。这些方法返回的所有对象都可以由约束流或Drools规则使用。例如,在CloudBalance中,所有计算机列表都是问题事实。@PlanningSolution@XStreamAlias("CloudBalance")publicclassCloudBalanceextendsAbstractPersistable{privateListcomputerList;私有列表processList;@XStreamConverter(HardSoftScoreXStreamConverter.class)私有的HardSoftScore分数;publicCloudBalance(){}publicCloudBalance(longid,ListcomputerList,ListprocessList){super(id);this.computerList=computerList;this.processList=processList;}@ValueRangeProvider(id="computerRange")@ProblemFactCollectionPropertypublicListgetComputerList(){returncomputerList;}publicvoidsetComputerList(ListcomputerList){this.computerList=computerList;}@PlanningEntityCollectionPropertypublicListgetProcessList(){returnprocessList;}}复制代码所有的概率lemFact会自动插入到Drools工作内存中,请注意为其属性添加注解,可以有多个属性注解@ProblemFactCollectionProperty。这些属性甚至可以返回具有相同类别类型的集合,但它们不应返回同一个实例两次,它还可以返回一个数组。@ProblemFactCollectionProperty注释对于使用@PlanningSolution注释的类的成员是必需的。它在没有此注释的超类或子类上被忽略。在极少数情况下,ProblemFact可能是一个对象:改为在其方法(或字段)上使用@ProblemFactProperty。ExtendingProblemFact有些ProblemFact一开始并没有体现在业务模型中,但是这些ProblemFact数据可以简化约束规则的编写。在提交解决方案之前,这些数据被计算为ProblemFact并放置在Solution类中,可以由求解器更新。更快更容易解决。例如,在考试中,对于每两个共享至少一个学生的考试科目,将为TopicConflict创建一个ProblemFact。@ProblemFactCollectionPropertyprivateListcalculateTopicConflictList(){ListtopicConflictList=newArrayList();for(TopicleftTopic:topicList){for(TopicrightTopic:topicList){if(leftTopic.right)<.getId()){intstudentSize=0;for(Studentstudent:leftTopic.getStudentList()){if(rightTopic.getStudentList().contains(student)){studentSize++;}}if(studentSize>0){topicConflictList.添加(新主题冲突(左主题,右主题,学生人数));}}}}返回topicConflictList;当分数约束需要检查两个具有共同学生主题的考试是否安排在一起时复制代码(取决于约束:在同一时间、连续或同一天),TopicConflict实例可以用作问题事实而不是有结合每个对于两个学生例子,计算都是在求解过程中进行的,这会大大降低OptaPlanner的求解效率。自动扫描属性并为每个属性(或字段)显式配置注释,其中一些也可以由OptaPlanner自动导出。例如,在CloudBalance的情况下:@PlanningSolution(autoDiscoverMemberType=AutoDiscoverMemberType.FIELD)publicclassCloudBalance{//自动发现为@ProblemFactCollectionProperty@ValueRangeProvider(id="computerRange")//还没有自动发现privateList计算机列表;//自动发现是@PlanningEntityCollectionPropertyprivateListprocessList;//自动发现是@PlanningScoreprivateHardSoftScore分数;...}复制代码AutoDiscoverMemberType支持:NONE:没有自动发现。FIELD:自动发现@PlanningSolution类中的所有字段。GETTER:自动发现@PlanningSolution类上的所有吸气剂。自动注解是基于字段类型(或getter返回类型):@ProblemFactProperty:当它不是集合、数组、@PlanningEntity类或分数时。@ProblemFactCollectionProperty:当它是不是@PlanningEntity类的集合(或数组)的类型时。@PlanningEntityProperty:当它是一个配置好的@PlanningEntity类或子类时。@PlanningEntityCollectionProperty:当它是@PlanningEntity类或Configuration类型的子类的集合(或数组)时。@PlanningScore:当它是分数或子类时。最后,如果您觉得这篇文章对您有点帮助,请点个赞。或者可以加入我的开发交流群:1025263163互相学习,我们会有专业的技术解答。如果您觉得这篇文章对您有用,请给我们的开源项目一个小星星:http://github。crmeb.net/u/defu非常感谢!