英文:
OptaPlanner optimizing Construction Heuristic phase for @PlanningEntity with 2 or more @PlanningVariable in java
问题
I understand that you want a translation of the provided text. Here's the translated content:
"I need to schedule tasks for employees. My approach works well enough for a small number of workers and tasks (default). I read that I need to change the construction heuristic scaling, so I tried the answer from this Stack Overflow answer and from this part of the documentation. It did not work, so I tried an approach from this blog, but it still did not work. I just want to point out that I implemented it in Java because that is a requirement of my project.
Here is the link to my GitHub repo, where you can have an insight into the bigger picture of my solution.
I think that my first approach is the closest to the answer, and the solution to my problem lies in my constraint provider, but I have been struggling for a long time, and it seems that I am only further away from the answer.
So this is my first approach to solving this problem:
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
ChangeMoveSelectorConfig changeMoveSelectorConfig1 = new ChangeMoveSelectorConfig();
ValueSelectorConfig valueSelectorConfig1 = new ValueSelectorConfig();
valueSelectorConfig1.setVariableName("startTime");
changeMoveSelectorConfig1.setValueSelectorConfig(valueSelectorConfig1);
phaseConfig.setMoveSelectorConfigList(Arrays.asList(changeMoveSelectorConfig, changeMoveSelectorConfig1));
SolverConfig solverConfig = new SolverConfig().withPhaseList(List.of(phaseConfig));
...```
And this is the log that I got when debugging.
```...
Construction Heuristic phase (0) ended: time spent (130), best score (0hard/0medium/0soft), score calculation speed (291272/sec), step total (82).
Solving ended: time spent (130), best score (0hard/0medium/0soft), score calculation speed (172530/sec), phase total (1), environment mode (REPRODUCIBLE), move thread count (NONE).
As you can see, the construction heuristic phase iterated through all my tasks and tried to assign some values, but all values remain null. At the end, I will provide my Constraint Provider.
Second approach:
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig = new QueuedEntityPlacerConfig();
EntitySelectorConfig entitySelectorConfig = new EntitySelectorConfig();
entitySelectorConfig.setCacheType(SelectionCacheType.PHASE);
entitySelectorConfig.setEntityClass(Task.class);
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
ChangeMoveSelectorConfig changeMoveSelectorConfig2 = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig2.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig2 = new ValueSelectorConfig();
valueSelectorConfig2.setVariableName("startTime");
changeMoveSelectorConfig2.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig.setMoveSelectorConfigList(Arrays.asList(changeMoveSelectorConfig, changeMoveSelectorConfig2));
phaseConfig.setEntityPlacerConfig(queuedEntityPlacerConfig);
SolverConfig solverConfig = new SolverConfig().withPhaseList(List.of(phaseConfig));
...```
And third approach:
```...
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig = new QueuedEntityPlacerConfig();
EntitySelectorConfig entitySelectorConfig = new EntitySelectorConfig();
entitySelectorConfig.setCacheType(SelectionCacheType.PHASE);
entitySelectorConfig.setEntityClass(Task.class);
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig.setMoveSelectorConfigList(List.of(changeMoveSelectorConfig));
phaseConfig.setEntityPlacerConfig(queuedEntityPlacerConfig);
ConstructionHeuristicPhaseConfig phaseConfig2 = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig2 = new QueuedEntityPlacerConfig();
ChangeMoveSelectorConfig changeMoveSelectorConfig2 = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig2.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig2 = new ValueSelectorConfig();
valueSelectorConfig2.setVariableName("startTime");
changeMoveSelectorConfig2.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig2.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig2.setMoveSelectorConfigList(List.of(changeMoveSelectorConfig2));
phaseConfig2.setEntityPlacerConfig(queuedEntityPlacerConfig2);
SolverConfig solverConfig = new SolverConfig().withPhaseList(Arrays.asList(phaseConfig, phaseConfig2));
...```
The logs for the second and third approaches are identical and can be found in the GitHub repo [here](https://github.com/jova5/opta-planner-job-schdule).
As you can see, in the second and third approaches, the constraint provider phase does not even iterate through my tasks.
And this is the Constraint Provider:
```java
public class JobScheduleConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[]{
noMoreTaskThanWorkingMinutes(constraintFactory),
everyTaskShouldBeAssigned(constraintFactory),
everyTaskShouldBeAssignedToEmployeeWithAdequateSkill(constraintFactory),
tasksDontOverlap(constraintFactory),
everyTaskShouldBeInitialized(constraintFactory),
everyTaskShouldBeInitializedWithTime(constraintFactory),
};
}
public Constraint noMoreTaskThanWorkingMinutes(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Employee.class)
.filter(employee -> employee.getSumMinutesOfAssignedTasks() >
employee.getWorkingMinutes())
.penalize(HardMediumSoftScore.ONE_HARD)
.asConstraint("noMoreTaskThanWorkingMinutes");
}
public Constraint everyTaskShouldBeAssigned(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Task.class)
.filter(task -> task.get
<details>
<summary>英文:</summary>
I need to schedule tasks for employees. My approach works good enough for small number of workers and tasks (default). I read that I need to change construction heuristic scaling so I tried answer from [this](https://stackoverflow.com/questions/70666268/how-to-speed-up-construction-phase-whilst-having-an-trivial-overlapping-constrai) stackoverflow answer and from [this](https://www.optaplanner.org/docs/optaplanner/latest/construction-heuristics/construction-heuristics.html#scalingConstructionHeuristics) part of documentation. It did not work, then I tried approach from [this](https://stackoverflow.com) blog, but it still did not work. I just want to point out that I did the implementation in Java because that is requirement of my project.
Here is the (https://github.com/jova5/opta-planner-job-schdule) to my github repo, where you will have an insight into the bigger picture of my solution.
I think that my first approach is the closest to answer and that solution to my problem lies in my constraint provider, but I am bagging my had for a long time and it seems that I am only further away from answer.
So this is my first approach to solving this problem.
...
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
ChangeMoveSelectorConfig changeMoveSelectorConfig1 = new ChangeMoveSelectorConfig();
ValueSelectorConfig valueSelectorConfig1 = new ValueSelectorConfig();
valueSelectorConfig1.setVariableName("startTime");
changeMoveSelectorConfig1.setValueSelectorConfig(valueSelectorConfig1);
phaseConfig.setMoveSelectorConfigList(Arrays.asList(changeMoveSelectorConfig,changeMoveSelectorConfig1));
SolverConfig solverConfig = new SolverConfig().withPhaseList(List.of(phaseConfig));
...
And this is log that I got when debugging.
Solving started: time spent (43), best score (0hard/0medium/0soft), environment mode (REPRODUCIBLE), move thread count (NONE), random (JDK with seed 0).
CH step (0), time spent (64), score (0hard/0medium/0soft), selected move count (6), picked move (Task_0 Employee: null Start Time: null {null -> null}).
CH step (1), time spent (72), score (0hard/0medium/0soft), selected move count (541), picked move (Task_0 Employee: null Start Time: null {null -> null}).
CH step (2), time spent (73), score (0hard/0medium/0soft), selected move count (6), picked move (Task_1 Employee: null Start Time: null {null -> null}).
CH step (3), time spent (74), score (0hard/0medium/0soft), selected move count (541), picked move (Task_1 Employee: null Start Time: null {null -> null}).
CH step (4), time spent (74), score (0hard/0medium/0soft), selected move count (6), picked move (Task_2 Employee: null Start Time: null {null -> null}).
CH step (5), time spent (76), score (0hard/0medium/0soft), selected move count (541), picked move (Task_2 Employee: null Start Time: null {null -> null}).
CH step (6), time spent (76), score (0hard/0medium/0soft), selected move count (6), picked move (Task_3 Employee: null Start Time: null {null -> null}).
CH step (7), time spent (77), score (0hard/0medium/0soft), selected move count (541), picked move (Task_3 Employee: null Start Time: null {null -> null}).
CH step (8), time spent (77), score (0hard/0medium/0soft), selected move count (6), picked move (Task_4 Employee: null Start Time: null {null -> null}).
CH step (9), time spent (78), score (0hard/0medium/0soft), selected move count (541), picked move (Task_4 Employee: null Start Time: null {null -> null}).
CH step (10), time spent (79), score (0hard/0medium/0soft), selected move count (6), picked move (Task_5 Employee: null Start Time: null {null -> null}).
CH step (11), time spent (80), score (0hard/0medium/0soft), selected move count (541), picked move (Task_5 Employee: null Start Time: null {null -> null}).
CH step (12), time spent (80), score (0hard/0medium/0soft), selected move count (6), picked move (Task_6 Employee: null Start Time: null {null -> null}).
CH step (13), time spent (81), score (0hard/0medium/0soft), selected move count (541), picked move (Task_6 Employee: null Start Time: null {null -> null}).
CH step (14), time spent (81), score (0hard/0medium/0soft), selected move count (6), picked move (Task_7 Employee: null Start Time: null {null -> null}).
CH step (15), time spent (82), score (0hard/0medium/0soft), selected move count (541), picked move (Task_7 Employee: null Start Time: null {null -> null}).
CH step (16), time spent (82), score (0hard/0medium/0soft), selected move count (6), picked move (Task_8 Employee: null Start Time: null {null -> null}).
CH step (17), time spent (84), score (0hard/0medium/0soft), selected move count (541), picked move (Task_8 Employee: null Start Time: null {null -> null}).
CH step (18), time spent (84), score (0hard/0medium/0soft), selected move count (6), picked move (Task_9 Employee: null Start Time: null {null -> null}).
CH step (19), time spent (85), score (0hard/0medium/0soft), selected move count (541), picked move (Task_9 Employee: null Start Time: null {null -> null}).
CH step (20), time spent (85), score (0hard/0medium/0soft), selected move count (6), picked move (Task_10 Employee: null Start Time: null {null -> null}).
CH step (21), time spent (86), score (0hard/0medium/0soft), selected move count (541), picked move (Task_10 Employee: null Start Time: null {null -> null}).
CH step (22), time spent (86), score (0hard/0medium/0soft), selected move count (6), picked move (Task_11 Employee: null Start Time: null {null -> null}).
CH step (23), time spent (88), score (0hard/0medium/0soft), selected move count (541), picked move (Task_11 Employee: null Start Time: null {null -> null}).
CH step (24), time spent (88), score (0hard/0medium/0soft), selected move count (6), picked move (Task_12 Employee: null Start Time: null {null -> null}).
CH step (25), time spent (90), score (0hard/0medium/0soft), selected move count (541), picked move (Task_12 Employee: null Start Time: null {null -> null}).
CH step (26), time spent (91), score (0hard/0medium/0soft), selected move count (6), picked move (Task_13 Employee: null Start Time: null {null -> null}).
CH step (27), time spent (92), score (0hard/0medium/0soft), selected move count (541), picked move (Task_13 Employee: null Start Time: null {null -> null}).
CH step (28), time spent (92), score (0hard/0medium/0soft), selected move count (6), picked move (Task_14 Employee: null Start Time: null {null -> null}).
CH step (29), time spent (93), score (0hard/0medium/0soft), selected move count (541), picked move (Task_14 Employee: null Start Time: null {null -> null}).
CH step (30), time spent (93), score (0hard/0medium/0soft), selected move count (6), picked move (Task_15 Employee: null Start Time: null {null -> null}).
CH step (31), time spent (94), score (0hard/0medium/0soft), selected move count (541), picked move (Task_15 Employee: null Start Time: null {null -> null}).
CH step (32), time spent (95), score (0hard/0medium/0soft), selected move count (6), picked move (Task_16 Employee: null Start Time: null {null -> null}).
CH step (33), time spent (96), score (0hard/0medium/0soft), selected move count (541), picked move (Task_16 Employee: null Start Time: null {null -> null}).
CH step (34), time spent (96), score (0hard/0medium/0soft), selected move count (6), picked move (Task_17 Employee: null Start Time: null {null -> null}).
CH step (35), time spent (97), score (0hard/0medium/0soft), selected move count (541), picked move (Task_17 Employee: null Start Time: null {null -> null}).
CH step (36), time spent (97), score (0hard/0medium/0soft), selected move count (6), picked move (Task_18 Employee: null Start Time: null {null -> null}).
CH step (37), time spent (98), score (0hard/0medium/0soft), selected move count (541), picked move (Task_18 Employee: null Start Time: null {null -> null}).
CH step (38), time spent (99), score (0hard/0medium/0soft), selected move count (6), picked move (Task_19 Employee: null Start Time: null {null -> null}).
CH step (39), time spent (100), score (0hard/0medium/0soft), selected move count (541), picked move (Task_19 Employee: null Start Time: null {null -> null}).
CH step (40), time spent (100), score (0hard/0medium/0soft), selected move count (6), picked move (Task_20 Employee: null Start Time: null {null -> null}).
CH step (41), time spent (101), score (0hard/0medium/0soft), selected move count (541), picked move (Task_20 Employee: null Start Time: null {null -> null}).
CH step (42), time spent (102), score (0hard/0medium/0soft), selected move count (6), picked move (Task_21 Employee: null Start Time: null {null -> null}).
CH step (43), time spent (103), score (0hard/0medium/0soft), selected move count (541), picked move (Task_21 Employee: null Start Time: null {null -> null}).
CH step (44), time spent (103), score (0hard/0medium/0soft), selected move count (6), picked move (Task_22 Employee: null Start Time: null {null -> null}).
CH step (45), time spent (104), score (0hard/0medium/0soft), selected move count (541), picked move (Task_22 Employee: null Start Time: null {null -> null}).
CH step (46), time spent (105), score (0hard/0medium/0soft), selected move count (6), picked move (Task_23 Employee: null Start Time: null {null -> null}).
CH step (47), time spent (106), score (0hard/0medium/0soft), selected move count (541), picked move (Task_23 Employee: null Start Time: null {null -> null}).
CH step (48), time spent (106), score (0hard/0medium/0soft), selected move count (6), picked move (Task_24 Employee: null Start Time: null {null -> null}).
CH step (49), time spent (107), score (0hard/0medium/0soft), selected move count (541), picked move (Task_24 Employee: null Start Time: null {null -> null}).
CH step (50), time spent (107), score (0hard/0medium/0soft), selected move count (6), picked move (Task_25 Employee: null Start Time: null {null -> null}).
CH step (51), time spent (109), score (0hard/0medium/0soft), selected move count (541), picked move (Task_25 Employee: null Start Time: null {null -> null}).
CH step (52), time spent (109), score (0hard/0medium/0soft), selected move count (6), picked move (Task_26 Employee: null Start Time: null {null -> null}).
CH step (53), time spent (111), score (0hard/0medium/0soft), selected move count (541), picked move (Task_26 Employee: null Start Time: null {null -> null}).
CH step (54), time spent (111), score (0hard/0medium/0soft), selected move count (6), picked move (Task_27 Employee: null Start Time: null {null -> null}).
CH step (55), time spent (113), score (0hard/0medium/0soft), selected move count (541), picked move (Task_27 Employee: null Start Time: null {null -> null}).
CH step (56), time spent (113), score (0hard/0medium/0soft), selected move count (6), picked move (Task_28 Employee: null Start Time: null {null -> null}).
CH step (57), time spent (114), score (0hard/0medium/0soft), selected move count (541), picked move (Task_28 Employee: null Start Time: null {null -> null}).
CH step (58), time spent (115), score (0hard/0medium/0soft), selected move count (6), picked move (Task_29 Employee: null Start Time: null {null -> null}).
CH step (59), time spent (116), score (0hard/0medium/0soft), selected move count (541), picked move (Task_29 Employee: null Start Time: null {null -> null}).
CH step (60), time spent (116), score (0hard/0medium/0soft), selected move count (6), picked move (Task_30 Employee: null Start Time: null {null -> null}).
CH step (61), time spent (118), score (0hard/0medium/0soft), selected move count (541), picked move (Task_30 Employee: null Start Time: null {null -> null}).
CH step (62), time spent (118), score (0hard/0medium/0soft), selected move count (6), picked move (Task_31 Employee: null Start Time: null {null -> null}).
CH step (63), time spent (119), score (0hard/0medium/0soft), selected move count (541), picked move (Task_31 Employee: null Start Time: null {null -> null}).
CH step (64), time spent (119), score (0hard/0medium/0soft), selected move count (6), picked move (Task_32 Employee: null Start Time: null {null -> null}).
CH step (65), time spent (120), score (0hard/0medium/0soft), selected move count (541), picked move (Task_32 Employee: null Start Time: null {null -> null}).
CH step (66), time spent (120), score (0hard/0medium/0soft), selected move count (6), picked move (Task_33 Employee: null Start Time: null {null -> null}).
CH step (67), time spent (121), score (0hard/0medium/0soft), selected move count (541), picked move (Task_33 Employee: null Start Time: null {null -> null}).
CH step (68), time spent (121), score (0hard/0medium/0soft), selected move count (6), picked move (Task_34 Employee: null Start Time: null {null -> null}).
CH step (69), time spent (122), score (0hard/0medium/0soft), selected move count (541), picked move (Task_34 Employee: null Start Time: null {null -> null}).
CH step (70), time spent (123), score (0hard/0medium/0soft), selected move count (6), picked move (Task_35 Employee: null Start Time: null {null -> null}).
CH step (71), time spent (124), score (0hard/0medium/0soft), selected move count (541), picked move (Task_35 Employee: null Start Time: null {null -> null}).
CH step (72), time spent (124), score (0hard/0medium/0soft), selected move count (6), picked move (Task_36 Employee: null Start Time: null {null -> null}).
CH step (73), time spent (125), score (0hard/0medium/0soft), selected move count (541), picked move (Task_36 Employee: null Start Time: null {null -> null}).
CH step (74), time spent (125), score (0hard/0medium/0soft), selected move count (6), picked move (Task_37 Employee: null Start Time: null {null -> null}).
CH step (75), time spent (126), score (0hard/0medium/0soft), selected move count (541), picked move (Task_37 Employee: null Start Time: null {null -> null}).
CH step (76), time spent (126), score (0hard/0medium/0soft), selected move count (6), picked move (Task_38 Employee: null Start Time: null {null -> null}).
CH step (77), time spent (127), score (0hard/0medium/0soft), selected move count (541), picked move (Task_38 Employee: null Start Time: null {null -> null}).
CH step (78), time spent (128), score (0hard/0medium/0soft), selected move count (6), picked move (Task_39 Employee: null Start Time: null {null -> null}).
CH step (79), time spent (128), score (0hard/0medium/0soft), selected move count (541), picked move (Task_39 Employee: null Start Time: null {null -> null}).
CH step (80), time spent (128), score (0hard/0medium/0soft), selected move count (6), picked move (Task_40 Employee: null Start Time: null {null -> null}).
CH step (81), time spent (129), score (0hard/0medium/0soft), selected move count (541), picked move (Task_40 Employee: null Start Time: null {null -> null}).
Construction Heuristic phase (0) ended: time spent (130), best score (0hard/0medium/0soft), score calculation speed (291272/sec), step total (82).
Solving ended: time spent (130), best score (0hard/0medium/0soft), score calculation speed (172530/sec), phase total (1), environment mode (REPRODUCIBLE), move thread count (NONE).
As you can see construction heuristic phase iterated through all my tasks and tried to assign some value, but all value remain null. At the end I will provide my ConstructionProvider.
Second approach:
...
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig = new QueuedEntityPlacerConfig();
EntitySelectorConfig entitySelectorConfig = new EntitySelectorConfig();
entitySelectorConfig.setCacheType(SelectionCacheType.PHASE);
entitySelectorConfig.setEntityClass(Task.class);
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
ChangeMoveSelectorConfig changeMoveSelectorConfig2 = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig2.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig2 = new ValueSelectorConfig();
valueSelectorConfig2.setVariableName("startTime");
changeMoveSelectorConfig2.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig.setMoveSelectorConfigList(Arrays.asList(changeMoveSelectorConfig, changeMoveSelectorConfig2));
phaseConfig.setEntityPlacerConfig(queuedEntityPlacerConfig);
SolverConfig solverConfig = new SolverConfig().withPhaseList(List.of(phaseConfig));
...
And third approach:
...
ConstructionHeuristicPhaseConfig phaseConfig = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig = new QueuedEntityPlacerConfig();
EntitySelectorConfig entitySelectorConfig = new EntitySelectorConfig();
entitySelectorConfig.setCacheType(SelectionCacheType.PHASE);
entitySelectorConfig.setEntityClass(Task.class);
ChangeMoveSelectorConfig changeMoveSelectorConfig = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setVariableName("employee");
changeMoveSelectorConfig.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig.setMoveSelectorConfigList(List.of(changeMoveSelectorConfig));
phaseConfig.setEntityPlacerConfig(queuedEntityPlacerConfig);
ConstructionHeuristicPhaseConfig phaseConfig2 = new ConstructionHeuristicPhaseConfig();
QueuedEntityPlacerConfig queuedEntityPlacerConfig2 = new QueuedEntityPlacerConfig();
ChangeMoveSelectorConfig changeMoveSelectorConfig2 = new ChangeMoveSelectorConfig();
changeMoveSelectorConfig2.setEntitySelectorConfig(entitySelectorConfig);
ValueSelectorConfig valueSelectorConfig2 = new ValueSelectorConfig();
valueSelectorConfig2.setVariableName("startTime");
changeMoveSelectorConfig2.setValueSelectorConfig(valueSelectorConfig);
queuedEntityPlacerConfig2.setEntitySelectorConfig(entitySelectorConfig);
queuedEntityPlacerConfig2.setMoveSelectorConfigList(List.of(changeMoveSelectorConfig2));
phaseConfig2.setEntityPlacerConfig(queuedEntityPlacerConfig2);
SolverConfig solverConfig = new SolverConfig().withPhaseList(Arrays.asList(phaseConfig, phaseConfig2));
...
Log for second ant third approach are identical and it will be available in github repo [here](https://github.com/jova5/opta-planner-job-schdule).
As you can see, in second and third approach constraint provider phase does not even iterate through my tasks.
And this is ConstraintProvider:
public class JobScheduleConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
return new Constraint[]{
noMoreTaskThanWorkingMinutes(constraintFactory),
everyTaskShouldBeAssigned(constraintFactory),
everyTaskShouldBeAssignedToEmployeeWithAdequateSkill(constraintFactory),
tasksDontOverlap(constraintFactory),
everyTaskShouldBeInitialized(constraintFactory),
everyTaskShouldBeInitializedWithTime(constraintFactory),
};
}
public Constraint noMoreTaskThanWorkingMinutes(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Employee.class)
.filter(employee -> employee.getSumMinutesOfAssignedTasks() >
employee.getWorkingMinutes())
.penalize(HardMediumSoftScore.ONE_HARD)
.asConstraint("noMoreTaskThanWorkingMinutes");
}
public Constraint everyTaskShouldBeAssigned(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Task.class)
.filter(task -> task.getEmployee() != null)
.reward(HardMediumSoftScore.ONE_MEDIUM)
.asConstraint("everyTaskShouldBeAssigned");
}
public Constraint everyTaskShouldBeAssignedToEmployeeWithAdequateSkill(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Task.class)
.filter(task -> {
if (task.getEmployee() == null) {
return false;
}
return !task.getEmployee().getSkills().contains(task.getSkillRequired());
})
.penalize(HardMediumSoftScore.ONE_HARD)
.asConstraint("everyTaskShouldBeAssignedToEmployeeWithAdequateSkill");
}
public Constraint everyTaskShouldBeInitialized(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Task.class)
.filter(task -> task.getEmployee() == null)
.penalize(HardMediumSoftScore.ONE_MEDIUM)
.asConstraint("everyTaskShouldBeInitialized");
}
public Constraint everyTaskShouldBeInitializedWithTime(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Task.class)
.filter(task -> task.getStartTime() == null)
.penalize(HardMediumSoftScore.ONE_MEDIUM)
.asConstraint("everyTaskShouldBeInitializedWithTime");
}
public Constraint tasksDontOverlap(ConstraintFactory constraintFactory) {
return constraintFactory.forEach(Employee.class)
.filter(Employee::checkIfTasksOverlap)
.penalize(HardMediumSoftScore.ONE_HARD)
.asConstraint("tasksDontOverlap");
}
}
I were expecting that all my tasks would be assigned in construction heuristic phase, but that was not the case. Default approach (Cartesian) does not scale well but it works an it assigns all tasks, so I tried Sequential approach, but as you can see it does not work.
Thank you all for your time.
I am sorry for such a long question.
</details>
# 答案1
**得分**: 1
你的问题很可能出在可空计划变量上。你的计划变量可以保持未分配状态,而约束提供者没有惩罚来修复这一点。求解器将它们保持未分配状态,因为没有激励它采取其他方式。
你有两个选择:
- 不要使变量可空。我建议这样做,因为你的约束明确表明你希望每个变量都被分配。
- 使用 `forEachIncludingNullVars(...)` 而不是 `forEach(...)`,它将包括具有空变量的实体,最终使您的约束在未分配变量上触发。
<details>
<summary>英文:</summary>
Your problem most likely lies in nullable planning variables. Your planning variables can remain unassigned, and there is no penalty in your constraint provider to fix that. The solver is leaving them unassigned, as it has no incentive to do otherwise.
You have two options:
- Don't make the variables nullable. I'd recommend that, because your constraints make it clear that you want every variable assigned.
- Use `forEachIncludingNullVars(...)` instead of `forEach(...)`, which will include entities with null variables, which will finally make your constraints trigger on unassigned variables.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论