我有一个要求,我需要在数据子集内进行规划。例如,我有一定等级的钢梁库存。在计划时,我需要将可用的横梁放入库存,前提是它们与配置文件匹配。
我如何使用约束流来做到这一点。任何例子将不胜感激。
我似乎不了解约束流。
只有在配置文件匹配时,我才需要将 ProjectMembers 放入 StockMembers。
规划实体
@PlanningEntity
public class ProjectMember
extends AbstractPersistable
implements Labeled {
private int requiredLength; // in mm
private String profile;
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
private StockMember stockMember;
ProjectMember() {
}
public ProjectMember(long id, int requiredLength) {
super(id);
this.requiredLength = requiredLength;
}
public int getRequiredLength() {
return requiredLength;
}
public void setRequiredLength(int requiredLength) {
this.requiredLength = requiredLength;
}
@PlanningVariable
public StockMember getStockMember() {
return stockMember;
}
public void setStockMember(StockMember stockMember) {
this.stockMember = stockMember;
}
@Override
public String getLabel() {
return "Project Member " + id;
}
}
public class StockMember
extends AbstractPersistable
implements Labeled {
private int length; // in mm
private String profile;
private int cost; // in dollars
StockMember() {
}
public StockMember(long id, int length, int cost) {
super(id);
this.length = length;
this.cost = cost;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getProfile() {
return this.profile;
}
@Override
@JsonIgnore
public String getLabel() {
return "Stock Member " + id;
}
}
规划解决方案
@PlanningSolution
public class NestMembers extends AbstractPersistable {
private List<StockMember> stockMemberList;
private List<ProjectMember> projectMemberList;
private HardSoftScore score;
NestMembers() {
}
public NestMembers(long id, List<StockMember> stockMemberList,
List<ProjectMember> projectMemberList) {
super(id);
this.stockMemberList = stockMemberList;
this.projectMemberList = projectMemberList;
}
@ValueRangeProvider
@ProblemFactCollectionProperty
public List<StockMember> getStockMemberList() {
return stockMemberList;
}
public void setStockMemberList(List<StockMember> computerList) {
this.stockMemberList = computerList;
}
@PlanningEntityCollectionProperty
public List<ProjectMember> getProjectMemberList() {
return projectMemberList;
}
public void setProjectMemberList(List<ProjectMember> projectMemberList)
{
this.projectMemberList = projectMemberList;
}
@PlanningScore
public HardSoftScore getScore() {
return score;
}
public void setScore(HardSoftScore score) {
this.score = score;
}
约束提供者
public class NestingConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory
constraintFactory) {
return new Constraint[]{
matchProfile(constraintFactory),
requiredLengthTotal(constraintFactory),
memberCost(constraintFactory)
};
}
Constraint requiredLengthTotal(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(ProjectMember.class)
.groupBy(ProjectMember::getStockMember,
sum(ProjectMember::getRequiredLength))
.filter((stockMember, requiredLength) -> requiredLength >
stockMember.getLength())
.penalize(HardSoftScore.ONE_HARD,
(stockMember, requiredLength) -> requiredLength -
stockMember.getLength())
.asConstraint("requiredLength");
}
Constraint matchProfile(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(ProjectMember.class)
.join(StockMember.class).
filter((projectMember, stockMember) ->
!projectMember.getProfile().equals(stockMember.getProfile()))
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("requiredProfileMatch");
}
//
Constraint memberCost(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(StockMember.class)
.ifExists(ProjectMember.class, equal(Function.identity(),
ProjectMember::getStockMember))
.penalize(HardSoftScore.ONE_SOFT, StockMember::getCost)
.asConstraint("cost");
}