Skip to content

Commit 8b9282b

Browse files
committed
Improvements
1 parent 277193a commit 8b9282b

File tree

9 files changed

+103
-75
lines changed

9 files changed

+103
-75
lines changed

src/main/java/ai/timefold/solver/benchmarks/examples/common/app/CommonApp.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package ai.timefold.solver.benchmarks.examples.common.app;
22

3+
import java.io.File;
4+
import java.nio.file.Path;
5+
import java.util.Collections;
6+
import java.util.Set;
7+
38
import ai.timefold.solver.benchmarks.examples.common.persistence.AbstractSolutionImporter;
49
import ai.timefold.solver.core.api.domain.solution.PlanningSolution;
510
import ai.timefold.solver.core.api.solver.SolverConfigOverride;
611
import ai.timefold.solver.core.api.solver.SolverFactory;
712
import ai.timefold.solver.core.config.solver.termination.TerminationConfig;
813
import ai.timefold.solver.persistence.common.api.domain.solution.SolutionFileIO;
914

10-
import java.io.File;
11-
import java.nio.file.Path;
12-
import java.util.Collections;
13-
import java.util.Set;
14-
1515
/**
1616
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
1717
*/

src/main/java/ai/timefold/solver/benchmarks/examples/conferencescheduling/score/ConferenceSchedulingConstraintProvider.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import ai.timefold.solver.core.api.score.stream.Constraint;
5151
import ai.timefold.solver.core.api.score.stream.ConstraintFactory;
5252
import ai.timefold.solver.core.api.score.stream.ConstraintProvider;
53+
import ai.timefold.solver.core.api.score.stream.PrecomputeFactory;
54+
import ai.timefold.solver.core.api.score.stream.bi.BiConstraintStream;
5355

5456
/**
5557
* Provides the constraints for the conference scheduling problem.
@@ -150,15 +152,20 @@ Constraint talkMutuallyExclusiveTalksTags(ConstraintFactory factory) {
150152
}
151153

152154
Constraint consecutiveTalksPause(ConstraintFactory factory) {
153-
return factory.forEachUniquePair(Talk.class,
154-
filtering((talk1, talk2) -> talk2.hasMutualSpeaker(talk1)))
155+
return factory.precompute(this::speakerTalks)
156+
.filter((talk1, talk2) -> talk1.getTimeslot() != null && talk2.getTimeslot() != null)
155157
.ifExists(ConferenceConstraintProperties.class,
156158
filtering((talk1, talk2, config) -> !talk1.getTimeslot().pauseExists(talk2.getTimeslot(),
157159
config.getMinimumConsecutiveTalksPauseInMinutes())))
158160
.penalize(HardSoftScore.ofHard(1), Talk::combinedDurationInMinutes)
159161
.asConstraint(CONSECUTIVE_TALKS_PAUSE);
160162
}
161163

164+
private BiConstraintStream<Talk, Talk> speakerTalks(PrecomputeFactory factory) {
165+
return factory.forEachUnfilteredUniquePair(Talk.class)
166+
.filter(Talk::hasMutualSpeaker);
167+
}
168+
162169
Constraint crowdControl(ConstraintFactory factory) {
163170
return factory.forEach(Talk.class)
164171
.filter(talk -> talk.getCrowdControlRisk() > 0)

src/main/java/ai/timefold/solver/benchmarks/examples/machinereassignment/score/MachineReassignmentConstraintProvider.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package ai.timefold.solver.benchmarks.examples.machinereassignment.score;
22

3+
import static ai.timefold.solver.core.api.score.stream.ConstraintCollectors.sumLong;
4+
import static ai.timefold.solver.core.api.score.stream.Joiners.equal;
5+
import static ai.timefold.solver.core.api.score.stream.Joiners.filtering;
6+
7+
import java.util.function.BiFunction;
8+
39
import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrBalancePenalty;
410
import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrGlobalPenaltyInfo;
511
import ai.timefold.solver.benchmarks.examples.machinereassignment.domain.MrMachine;
@@ -13,12 +19,6 @@
1319
import ai.timefold.solver.core.api.score.stream.ConstraintFactory;
1420
import ai.timefold.solver.core.api.score.stream.ConstraintProvider;
1521

16-
import java.util.function.BiFunction;
17-
18-
import static ai.timefold.solver.core.api.score.stream.ConstraintCollectors.sumLong;
19-
import static ai.timefold.solver.core.api.score.stream.Joiners.equal;
20-
import static ai.timefold.solver.core.api.score.stream.Joiners.filtering;
21-
2222
public class MachineReassignmentConstraintProvider implements ConstraintProvider {
2323

2424
@Override
@@ -63,8 +63,8 @@ protected Constraint maximumCapacity(ConstraintFactory factory) {
6363

6464
protected Constraint serviceConflict(ConstraintFactory factory) {
6565
return factory.forEachUniquePair(MrProcessAssignment.class,
66-
equal(MrProcessAssignment::getMachine, MrProcessAssignment::getMachine),
67-
equal(MrProcessAssignment::getService, MrProcessAssignment::getService))
66+
equal(MrProcessAssignment::getMachine, MrProcessAssignment::getMachine),
67+
equal(MrProcessAssignment::getService, MrProcessAssignment::getService))
6868
.penalize(HardSoftLongScore.ONE_HARD)
6969
.asConstraint(MrConstraints.SERVICE_CONFLICT);
7070
}
@@ -94,7 +94,7 @@ protected Constraint serviceDependency(ConstraintFactory factory) {
9494
equal((serviceDependency, processFrom) -> serviceDependency.getToService(),
9595
MrProcessAssignment::getService),
9696
filtering((serviceDependency, processFrom,
97-
processTo) -> !processFrom.getNeighborhood().equals(processTo.getNeighborhood())))
97+
processTo) -> !processFrom.getNeighborhood().equals(processTo.getNeighborhood())))
9898
.penalize(HardSoftLongScore.ONE_HARD)
9999
.asConstraint(MrConstraints.SERVICE_DEPENDENCY);
100100
}
@@ -107,7 +107,7 @@ protected Constraint transientUsage(ConstraintFactory factory) {
107107
return factory.forEach(MrMachineCapacity.class)
108108
.filter(MrMachineCapacity::isTransientlyConsumed)
109109
.join(factory.forEach(MrProcessAssignment.class)
110-
.filter(MrProcessAssignment::isMoved),
110+
.filter(MrProcessAssignment::isMoved),
111111
equal(MrMachineCapacity::getMachine, MrProcessAssignment::getOriginalMachine))
112112
.groupBy((machineCapacity, processAssignment) -> machineCapacity,
113113
sumLong((machineCapacity, processAssignment) -> processAssignment

src/main/java/ai/timefold/solver/benchmarks/examples/meetingscheduling/score/MeetingSchedulingConstraintProvider.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,9 @@ protected Constraint avoidOvertime(ConstraintFactory constraintFactory) {
6565
}
6666

6767
protected Constraint requiredAttendanceConflict(ConstraintFactory constraintFactory) {
68-
return constraintFactory
69-
.forEachUniquePair(RequiredAttendance.class,
70-
equal(RequiredAttendance::getPerson))
71-
.join(MeetingAssignment.class,
72-
equal((leftRequiredAttendance, rightRequiredAttendance) -> leftRequiredAttendance.getMeeting(),
73-
MeetingAssignment::getMeeting))
68+
return constraintFactory.precompute(MeetingSchedulingConstraintProvider::requiredAttendanceAssignmentLeft)
69+
.filter((leftRequiredAttendance, rightRequiredAttendance,
70+
assignment) -> assignment.getStartingTimeGrain() != null)
7471
.join(MeetingAssignment.class,
7572
equal((leftRequiredAttendance, rightRequiredAttendance, leftAssignment) -> rightRequiredAttendance
7673
.getMeeting(),
@@ -87,6 +84,15 @@ protected Constraint requiredAttendanceConflict(ConstraintFactory constraintFact
8784
.asConstraint("Required attendance conflict");
8885
}
8986

87+
private static TriConstraintStream<RequiredAttendance, RequiredAttendance, MeetingAssignment>
88+
requiredAttendanceAssignmentLeft(PrecomputeFactory factory) {
89+
return factory.forEachUnfilteredUniquePair(RequiredAttendance.class,
90+
equal(RequiredAttendance::getPerson))
91+
.join(MeetingAssignment.class,
92+
equal((leftRequiredAttendance, rightRequiredAttendance) -> leftRequiredAttendance.getMeeting(),
93+
MeetingAssignment::getMeeting));
94+
}
95+
9096
protected Constraint requiredRoomCapacity(ConstraintFactory constraintFactory) {
9197
return constraintFactory.forEachIncludingUnassigned(MeetingAssignment.class)
9298
.filter(meetingAssignment -> meetingAssignment.getRequiredCapacity() > meetingAssignment.getRoomCapacity())
@@ -140,13 +146,9 @@ protected Constraint requiredAndPreferredAttendanceConflict(ConstraintFactory co
140146
}
141147

142148
protected Constraint preferredAttendanceConflict(ConstraintFactory constraintFactory) {
143-
return constraintFactory
144-
.forEachUniquePair(PreferredAttendance.class,
145-
equal(PreferredAttendance::getPerson))
146-
.join(constraintFactory.forEachIncludingUnassigned(MeetingAssignment.class)
147-
.filter(assignment -> assignment.getStartingTimeGrain() != null),
148-
equal((leftAttendance, rightAttendance) -> leftAttendance.getMeeting(),
149-
MeetingAssignment::getMeeting))
149+
return constraintFactory.precompute(MeetingSchedulingConstraintProvider::preferredAttendanceAssignmentLeft)
150+
.filter((leftPreferredAttendance, rightPreferredAttendance,
151+
assignment) -> assignment.getStartingTimeGrain() != null)
150152
.join(constraintFactory.forEachIncludingUnassigned(MeetingAssignment.class)
151153
.filter(assignment -> assignment.getStartingTimeGrain() != null),
152154
equal((leftAttendance, rightAttendance, leftAssignment) -> rightAttendance.getMeeting(),
@@ -163,6 +165,14 @@ protected Constraint preferredAttendanceConflict(ConstraintFactory constraintFac
163165
.asConstraint("Preferred attendance conflict");
164166
}
165167

168+
private static TriConstraintStream<PreferredAttendance, PreferredAttendance, MeetingAssignment>
169+
preferredAttendanceAssignmentLeft(PrecomputeFactory factory) {
170+
return factory.forEachUnfilteredUniquePair(PreferredAttendance.class,
171+
equal(PreferredAttendance::getPerson))
172+
.join(MeetingAssignment.class,
173+
equal((leftAttendance, rightAttendance) -> leftAttendance.getMeeting(), MeetingAssignment::getMeeting));
174+
}
175+
166176
// ************************************************************************
167177
// Soft constraints
168178
// ************************************************************************

0 commit comments

Comments
 (0)