做网站用什么前端框架,wordpress 换行,小红书关键词热度查询,网站建设方案平台选择上篇
排产#xff0c;原则上也就是分配时间#xff0c;分配资源#xff1b;保证资源日历约束#xff0c;保证工艺路线约束。我们看一下如何实现optaplanner 优化的 定义一个move, 一个move可能改变了分配到的资源#xff0c;也可能改变了一个资源上的顺序。改变即意味着优…上篇
排产原则上也就是分配时间分配资源保证资源日历约束保证工艺路线约束。我们看一下如何实现optaplanner 优化的 定义一个move, 一个move可能改变了分配到的资源也可能改变了一个资源上的顺序。改变即意味着优化的可能原本分配的资源把后工序移到前面来。前后各算一个score. 通过socreDirector中定义的beforeVariableChanged/afterVariableChanged再更新另一个资源上的链同时前后继续scoreDirector触发另一个shadow variable: Start time通过StartTimeUpdatingVariableListener触发改变。这里的改变保证了不同资源上的job满足工艺路线的约束 模型
如何建模对一个优化问题非常关键
Chain Structure: The previousAllocation can now be either a Resource (anchor) or another Allocation Resource becomes a shadow variable automatically updated based on the chain This creates a clean chain: Resource - Allocation1 - Allocation2 - … Move Simplification: No need for separate resource change moves Single ChainChangeMove handles both resource changes and sequence changes When moving to a different resource, just set the previous to be the resource When moving within same resource, set previous to be another allocation Benefits: Simpler code structure Fewer variables to maintain More efficient move generation Better encapsulation of the chaining logic Automatic resource updates through shadow variable 过程
本文我们继续试图学习optaplanner来进行排产规划。
When a move changes an allocation’s resource and/or sequence: When OptaPlanner/timefold selects a move: Check if move is doable (isMoveDoable) Verify resource compatibilityCheck for circular dependenciesValidate sequence constraints Execute the move (doMove) Update primary planning variablesShadow variable listener triggersStart/end times cascade update Score calculation Check hard constraints Resource conflictsJob dependenciesResource compatibility Evaluate soft constraints MakespanSetup timesResource preferences Accept/Reject move based on score If better: keep changeIf worse: maybe keep (based on meta-heuristic) The previousAllocation shadow variable is updated first This triggers the AnchorShadowVariable (resource) to update The StartTimeUpdatingVariableListener then recalculates timing Chain Update Process: When an allocation moves to a new resource: a. It disconnects from its old chain (previous/next allocations are relinked) b. Inserts into new resource’s chain at specified position c. Updates shadow variables (resource, start time) for moved allocation d. Recursively updates all downstream allocations in both chains Impact on Route Dependencies: The StartTimeUpdatingVariableListener ensures timing consistency When start time changes, it propagates updates down the chain If jobs have dependencies across resources, you’ll need additional constraints Can add precedence constraints between related jobs 例如 Before: Resource1 - Allocation1 - Allocation2 - Allocation3 Resource2 - Allocation4 - Allocation5 After: Resource1 - Allocation1 - Allocation3 Resource2 - Allocation4 - Allocation2 - Allocation5 The system will: Update Allocation2’s previousAllocation to Allocation4 Update Allocation2’s resource to Resource2 Recalculate start times for Allocation2 and all subsequent allocations Update Allocation3’s previousAllocation to Allocation1 Recalculate start times in Resource1’s chain 细节
当一个move发生的时候 isMoveDoable() is checkeddoMove() is called if move is doableScore is calculated after each changeMove is accepted/rejected based on score During doMove() beforeVariableChanged() notifies ScoreDirectorChain updates occurafterVariableChanged() notifies ScoreDirectorShadow variables update automaticallyScore calculator runs automatically Score calculation triggers: After every genuine variable changeAfter shadow variables updateAfter variable listeners complete their updatesBefore move acceptance/rejection decision // Move implementation for changing position in chain
public class ChainChangeMove extends AbstractMoveJobShopSchedule {private final Allocation allocation;private final Object newPrevious; // Can be Resource or AllocationOverrideprotected void doMoveOnGenuineVariables(ScoreDirectorJobShopSchedule scoreDirector) {Object oldPrevious allocation.getPreviousAllocation();Allocation nextAllocation findNextAllocation(allocation);// Remove allocation from old chain positionif (nextAllocation ! null) {scoreDirector.beforeVariableChanged(nextAllocation, previousAllocation);nextAllocation.setPreviousAllocation(oldPrevious);scoreDirector.afterVariableChanged(nextAllocation, previousAllocation);}// Insert allocation at new chain positionAllocation newNext null;if (newPrevious instanceof Allocation) {newNext findNextAllocation((Allocation) newPrevious);}// Update the moved allocations previousscoreDirector.beforeVariableChanged(allocation, previousAllocation);allocation.setPreviousAllocation(newPrevious);scoreDirector.afterVariableChanged(allocation, previousAllocation);// Update the next allocations previous if it existsif (newNext ! null) {scoreDirector.beforeVariableChanged(newNext, previousAllocation);newNext.setPreviousAllocation(allocation);scoreDirector.afterVariableChanged(newNext, previousAllocation);}}
}ScoreDirector manages this process scoreDirector.beforeVariableChanged() → Make changes → scoreDirector.afterVariableChanged() → Shadow updates → Score calculation → Move acceptance For chain moves specifically: a. Original chain score is calculated b. Move changes are applied c. New chain score is calculated d. Downstream impacts are scored e. Total impact determines move acceptance