You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google Apps Script的LinearOptimizationService中设置「每个工人恰好分配一个任务」的约束以求解指派问题

Fixing the "Each Worker Gets Exactly One Task" Constraint in Google Apps Script LinearOptimizationService

我看到你在尝试用Google Apps Script的LinearOptimizationService实现指派问题,目前的代码已经处理了「每个任务恰好分配给一个工人」的约束,但还没设置「每个工人必须恰好分配一个任务」——其实这个修改非常简单,只需要调整现有约束的上下界就行。

具体修改点

你当前针对工人的约束设置的是最多分配一个任务(上下界为0, 1),只需要把这段代码里的约束上下界都改成1,就能强制每个工人必须被分配恰好一个任务:

找到这段代码:

// Each worker is assigned to at most one task.
for (let i = 0; i < costMatrix.length; ++i) {
  constraint = engine.addConstraint(0, 1);
  for (let j = 0; j < costMatrix[0].length; ++j) {
    constraint.setCoefficient(`x${i}${j}`, 1);
  }
}

把engine.addConstraint(0, 1)改成engine.addConstraint(1, 1)即可。

修正后的完整代码

function myFunction() { 
  // Create the variables 
  var engine = LinearOptimizationService.createEngine(); 
  const costMatrix = [[7,5,4,8,3] ,[2,5,6,7,1] ,[2,8,9,5,2] ,[2,5,6,7,1] ,[2,8,1,5,9]] 
  const capacities = [1,1,1,1,1] 
  
  // initialize the decision variables 
  x = new Array(costMatrix.length); 
  for (let i=0; i<costMatrix.length; i++){ 
    x[i] = new Array(costMatrix[0].length); 
    for (let j=0; j<costMatrix[0].length; j++){ 
      x[i][j] = engine.addVariable(`x${i}${j}`, 0, 1, LinearOptimizationService.VariableType.INTEGER); 
    } 
  } 
  
  // Updated: Each worker is assigned to exactly one task.
  for (let i = 0; i < costMatrix.length; ++i) { 
    constraint = engine.addConstraint(1, 1); // Changed lower bound from 0 to 1
    for (let j = 0; j < costMatrix[0].length; ++j) { 
      constraint.setCoefficient(`x${i}${j}`, 1); 
    } 
  } 
  
  // Each task is assigned to exactly one worker. 
  for (let j = 0; j < costMatrix[0].length; ++j) { 
    constraint = engine.addConstraint(1, 1); 
    for (let i = 0; i < costMatrix.length; ++i) { 
      constraint.setCoefficient(`x${i}${j}`, 1); 
    } 
  } 
  
  // Set objective coefficients
  for (let i = 0; i < costMatrix.length; ++i) { 
    for (let j = 0; j < costMatrix[0].length; ++j) { 
      engine.setObjectiveCoefficient(`x${i}${j}`, costMatrix[i][j]); 
    } 
  } 
  
  engine.setMinimization() 
  
  // Solve the linear program 
  var solution = engine.solve(30); 
  if (!solution.isValid()) { 
    throw 'No solution ' + solution.getStatus(); 
  } 
  
  Logger.log('ObjectiveValue: ' + solution.getObjectiveValue()); 
  for (let i=0; i<costMatrix.length; i++){ 
    for (let j=0; j<costMatrix[0].length; j++){ 
      Logger.log(`Value of: x${i}${j} ` + solution.getVariableValue(`x${i}${j}`)); 
    } 
  } 
}

为什么这样修改

你的场景是标准的指派问题(工人数量和任务数量相等,都是5个),需要满足两个双向约束:

  • 每个任务必须恰好分配给一个工人(你已经正确实现)
  • 每个工人必须恰好分配一个任务(就是我们修正的部分)

修改后,求解器会找到总成本最小的完美匹配,确保所有工人和任务都被充分分配,不会出现闲置的工人或未被处理的任务。

内容的提问来源于stack exchange,提问作者A. Albinus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:17:50