Skip to content

Commit 1ef7e2c

Browse files
perf: ignore updating consistency of entities when ignoring inconsistent solutions
1 parent 7ad4ac9 commit 1ef7e2c

2 files changed

Lines changed: 23 additions & 12 deletions

File tree

core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/AffectedEntitiesUpdater.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ final class AffectedEntitiesUpdater<Solution_>
2121
// Internal state; expensive to create, therefore we reuse.
2222
private final LoopedTracker loopedTracker;
2323
private final BitSet visited;
24+
private final boolean ignoreInconsistentSolutions;
2425
private final PriorityQueue<BaseTopologicalOrderGraph.NodeTopologicalOrder> changeQueue;
26+
private boolean consistencyProcessed;
27+
2528

2629
AffectedEntitiesUpdater(BaseTopologicalOrderGraph graph, List<GraphNode<Solution_>> nodeList,
2730
BaseTopologicalOrderGraph.NodeTopologicalOrder[] nodeTopologicalOrders,
2831
Function<Object, List<GraphNode<Solution_>>> entityToContainingNode,
29-
int entityCount, ChangedVariableNotifier<Solution_> changedVariableNotifier) {
32+
int entityCount, ChangedVariableNotifier<Solution_> changedVariableNotifier,
33+
boolean ignoreInconsistentSolutions) {
3034
this.graph = graph;
3135
this.nodeList = nodeList;
3236
this.nodeTopologicalOrders = nodeTopologicalOrders;
@@ -36,6 +40,8 @@ final class AffectedEntitiesUpdater<Solution_>
3640
createNodeToEntityNodes(entityCount, nodeList, entityToContainingNode));
3741
this.visited = new BitSet(instanceCount);
3842
this.changeQueue = new PriorityQueue<>(instanceCount);
43+
this.ignoreInconsistentSolutions = ignoreInconsistentSolutions;
44+
this.consistencyProcessed = false;
3945
}
4046

4147
static <Solution_> int[][] createNodeToEntityNodes(int entityCount,
@@ -98,6 +104,7 @@ public void accept(BitSet changed) {
98104

99105
// Prepare for the next time updateChanged() is called.
100106
// No need to clear changeQueue, as that already finishes empty.
107+
consistencyProcessed = true;
101108
loopedTracker.clear();
102109
visited.clear();
103110
}
@@ -129,19 +136,22 @@ private boolean updateEntityShadowVariables(GraphNode<Solution_> entityVariable,
129136

130137
// Do not need to update anyChanged here; the graph already marked
131138
// all nodes whose looped status changed for us
132-
var groupEntities = shadowVariableReferences.get(0).groupEntities();
133-
var groupEntityIds = entityVariable.groupEntityIds();
134139

135-
if (groupEntities != null) {
136-
for (var i = 0; i < groupEntityIds.length; i++) {
137-
var groupEntity = groupEntities[i];
138-
var groupEntityId = groupEntityIds[i];
140+
if (!ignoreInconsistentSolutions || !consistencyProcessed) {
141+
var groupEntities = shadowVariableReferences.get(0).groupEntities();
142+
var groupEntityIds = entityVariable.groupEntityIds();
143+
144+
if (groupEntities != null) {
145+
for (var i = 0; i < groupEntityIds.length; i++) {
146+
var groupEntity = groupEntities[i];
147+
var groupEntityId = groupEntityIds[i];
148+
anyChanged |=
149+
updateLoopedStatusOfEntity(groupEntity, groupEntityId, entityConsistencyState);
150+
}
151+
} else {
139152
anyChanged |=
140-
updateLoopedStatusOfEntity(groupEntity, groupEntityId, entityConsistencyState);
153+
updateLoopedStatusOfEntity(entity, entityVariable.entityId(), entityConsistencyState);
141154
}
142-
} else {
143-
anyChanged |=
144-
updateLoopedStatusOfEntity(entity, entityVariable.entityId(), entityConsistencyState);
145155
}
146156

147157
for (var shadowVariableReference : shadowVariableReferences) {

core/src/main/java/ai/timefold/solver/core/impl/domain/variable/declarative/DefaultVariableReferenceGraph.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public DefaultVariableReferenceGraph(VariableReferenceGraphBuilder<Solution_> ou
3737
affectedEntitiesUpdater =
3838
new AffectedEntitiesUpdater<>(graph, nodeList, nodeTopologicalOrders,
3939
entityToVariableReferenceMap::get,
40-
outerGraph.entityToEntityId.size(), outerGraph.changedVariableNotifier);
40+
outerGraph.entityToEntityId.size(), outerGraph.changedVariableNotifier,
41+
ignoreInconsistentSolutions);
4142
}
4243

4344
@Override

0 commit comments

Comments
 (0)