当前位置: 首页 > 知识库问答 >
问题:

解决一个有许多预先分配的作业

丁韬
2023-03-14

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

但是,有没有其他解决方案可以更容易地做到这一点?也许我最好自己写一个解决方案?如有任何建议,我将不胜感激。

编辑:我试着写我自己的巧克力策略。对于一个小问题,它工作得很好,但对于一个大问题,它找不到解决方案。我不确定我在getDecision中所做的一切是否都被允许(例如检查是否安装了),而且我找不到任何关于如何编写策略的文档或教程。如果有人能给我指点问题所在,我将不胜感激。(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个答案

韦阳晖
2023-03-14

为什么不更改解算器的搜索策略,使其从预先指定的变量开始?文档中对此进行了描述。

 类似资料:
  • 问题内容: 我想交换两个秒- 而在此例,并做到在一个没有线的库函数。 所以我从这里开始: 输出是预期的。到目前为止一切都很好。 接下来是: 输出再次符合预期。到目前为止还不错。 然后最后这个: 在此阶段,输出变为。现在我知道这是由于当时未完成分配而导致的-为什么会发生这种情况?为什么不实际分配给变量,以使其成为最后一次分配? 问题答案: 让我们尝试扩展您的最后一个表达式。 评估为 需要注意的是表达

  • 我想要和的配置。对的授权是,而对的授权是(Separatley这两种配置都运行良好)。 预期行为: 请求 /v2/api/**将使用中给出的过滤器进行过滤,其中jwt被验证并创建上下文 所有其他请求都将使用ssl客户端证书验证。 它现在的工作方式——任何请求都会在之前触发AddFilterb,并因缺少jwt令牌而被拒绝。 我的配置类:

  • 如何精确匹配img标记的多个实例?我读了一些关于preg_match的教程,但从未真正理解。 我以此为基础: 我做了一个小的像正则表达式: 在这之后,我就卡住了。我如何继续匹配所有直到两个字符串的末尾? 我在PHP网站上发现了数组部分: 使用我的代码,我如何获得图像URL和alt标签? 谢谢

  • 我有一个不太典型的场景,我不知道如何继续: 有两个车站位于两个不同的位置 两个站点需要相同的资源 一旦释放,资源将从一个站点移动到另一个站点。所以它一直从1号站到2号站再到1号站等等,直到它再次被抓获。这是通过从发布块的资源进程端口添加链接来建模的。因此,除非条件适用,否则它不会完全释放。条件是有代理在同一资源的捕获块队列中等待。因此,它应该继续移动,直到再次需要它。棘手的部分是,该资源有两个抓取

  • 若一条代码不能向量化,你可以通过预分配任何输出结果已保存其中的向量或数组以加快for 循环。例如,这个代码用zeros函数把for循环产生的向量预分配。这使得for循环的执行显著加快。 r = zeros(32,1); for n = 1:32 r(n) = rank(magic(n)); end 上例中若没有使用预分配,MATLAB的注释器利用每次循环扩大r向量。向量预分配排除了该步骤

  • 我正在开发一个graqphqlapi,它通过Mongoose从MongoDB获取数据。现在我遇到的问题是GraphQL不使用查询来解析字段,而是使用字段解析程序,因为没有设置ID,所以字段解析程序无法工作。 TypeDefs: 解析程序: 功能: 查询: 结果: