如何在 optplanner 中排除某些匹配项

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

我有一个要求,我需要在数据子集内进行规划。例如,我有一定等级的钢梁库存。在计划时,我需要将可用的横梁放入库存,前提是它们与配置文件匹配。

我如何使用约束流来做到这一点。任何例子将不胜感激。

我似乎不了解约束流。

只有在配置文件匹配时,我才需要将 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");
}
optaplanner
© www.soinside.com 2019 - 2024. All rights reserved.