解决包含许多预先分配的作业

时间:2016-06-28 16:24:05

标签: modeling solver constraint-programming choco

我想解决的问题包括 800任务,必须分配给 120名工作人员。工人必须有资格完成任务,每周只有一定的工作时间。大约80%的作业已经预先分配。这意味着它们应该被保留,但如果其他20%无法解决,则可能违反预先分配。
我已经有一个使用Choco解算器的模型,如果违反预先分配并且目标是最小化惩罚,则使用惩罚。但是我认为这不是很有效,因为解算器不会通过分配预先指定的变量来启动搜索策略。我已经在这里专门针对Choco问了这个问题(How to define propagation starting point in Choco 3.3)。

但是还有另一个解决方案可以更轻松地完成吗?编写自己的求解器可能最好吗? 我很感激任何建议。

编辑: 我曾尝试编写自己的Choco策略。对于一个小问题,它工作正常,但对于大问题,它没有找到解决方案。我不确定我是否允许在getDecision中执行所有操作(例如检查isInstantiated),我找不到任何关于如何编写扩展AbstractStrategy策略的文档或教程。我很欣赏可能出现问题的任何指示。 (prios矩阵中的绝对优先级越高,变量应该越早分配。如果优先级为负,则应分配0,如果为正,则应分配1。最高优先级为9999)

    public class PriorityStrategy extends AbstractStrategy<IntVar> {

        int[] prios;

        // Search strategy parameters
        VariableSelector<IntVar> variableSelector;
        IntValueSelector valueSelectorLB;
        IntValueSelector valueSelectorUB;
        DecisionOperator<IntVar> decisionOperator;

        // object recycling management
        PoolManager<IntDecision> decisionPool;

        int currentIndex = -1;
        HashMap<IntVar, Integer> bestsMap = new HashMap<IntVar, Integer>();

        public PriorityStrategy(IntVar[] vars, int[] prios) {
            super(vars);
            this.prios = prios;
            valueSelectorLB = new IntDomainMin();
            valueSelectorUB = new IntDomainMax();
            variableSelector = new Random<IntVar>(123); //new Occurrence<IntVar>();
            this.decisionPool = new PoolManager<>();
        }

        @Override
        public Decision<IntVar> getDecision() {
             IntVar next = null;
             List<IntVar> bests = new ArrayList<IntVar>();

             int bestPrio = 0;
             for (int i = 0; i < vars.length; i++) {
                int currentPrio = Math.abs(prios[i]);
                if (currentPrio >= bestPrio && !vars[i].isInstantiated() || 
                        (next == null && !vars[i].isInstantiated())) {
                    if(currentPrio == 9999) {
                        currentIndex = i;
                        bests.clear();
                        bestsMap.clear();
                        return computeDecision(vars[i]);
                    }
                    if(currentPrio > bestPrio) {
                        bestPrio = currentPrio;
                        bests.clear();
                        bestsMap.clear();
                    }
                    bests.add(vars[i]);
                    bestsMap.put(vars[i], i);
                }
            }
            if(bests.size()>0) {
                next = variableSelector.getVariable(bests.toArray(new IntVar[bests.size()]));
                currentIndex = bestsMap.get(next);
            }
            return computeDecision(next);
        }

        @Override
        public Decision<IntVar> computeDecision(IntVar variable) {
            if (variable == null || variable.isInstantiated()) {
                return null;
            }
            int currentVal;
            if(prios[currentIndex] > 0){
                currentVal = valueSelectorUB.selectValue(variable);
            } else {
                currentVal = valueSelectorLB.selectValue(variable);         
            }
            System.out.println("Idx " + currentIndex);
            IntDecision current = decisionPool.getE();
            if (current == null) {
                current = new IntDecision(decisionPool);
            }
            current.set(variable, currentVal, DecisionOperator.int_eq);
            return current;
        }

    }

1 个答案:

答案 0 :(得分:0)

为什么不改变求解器的搜索策略,以便它以预先指定的变量开始?它在文档中描述。