为什么我的MIP求解器不采用“ NA”值?

时间:2019-07-18 11:47:06

标签: python optimization constraint-programming

我有下面的求解器,如果我用cost数组中的整数替换'NA'值并取出if语句检查该值是否为'NA',否则抛出关键错误。 >

我已经坚持了好几个小时,而且我知道这很简单,但却无法理解!

我还是Google OR-工具和优化的新手,所以很想知道我使用的是正确的工具/求解器,还是有更好/更高效的工具。

def main():
  solver = pywraplp.Solver('SolveAssignmentProblemMIP',
                           pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)

  cost = [[15.25, 18.50, 'NA', 17.25],
          [18.50, 19.50, 26.50, 21.00],
          [12.50, 'NA', 'NA', 'NA'],
          ['NA', 'NA', 23.50, 'NA'],
          ['NA', 'NA', 'NA', 16.50]
         ]


  num_workers = len(cost)
  num_tasks = len(cost[1])

  x = {}

  for i in range(0, num_workers):
    for j in range(0, num_tasks):
      if cost[i][j] != 'NA':
        x[i, j] = solver.BoolVar('x[%i,%i]' % (i, j))

  # Objective
  solver.Minimize(solver.Sum([cost[i][j] *  x[i,j] for i in range(num_workers)
                                                  for j in range(num_tasks)]))

  # Constraints

  # Each worker is assigned to at most 1 task.

  for i in range(num_workers):
    solver.Add(solver.Sum([x[i, j] for j in range(num_tasks)]) <= 1)

  # Each task is assigned to exactly one worker.

  for j in range(num_tasks):
    solver.Add(solver.Sum([x[i, j] for i in range(num_workers)]) == 1)

  sol = solver.Solve()

  print('Total cost = ', solver.Objective().Value())
  print()
  for i in range(num_workers):
    for j in range(num_tasks):
      if x[i, j].solution_value() > 0:
        print('Vessel %d assigned to Voyage %d.  Cost = %d' % (
              i,
              j,
              cost[i][j]))

  print()
  print("Time = ", solver.WallTime(), " milliseconds")
if __name__ == '__main__':
  main()

KeyError                                  Traceback (most recent call last)
<ipython-input-52-2f567281d1e6> in <module>()
     56   print("Time = ", solver.WallTime(), " milliseconds")
     57 if __name__ == '__main__':
---> 58   main()

1 frames
<ipython-input-52-2f567281d1e6> in main()
     26 
     27   # Objective
---> 28   solver.Minimize(solver.Sum([cost[i][j] *  x[i,j] for i in range(num_workers)
     29                                                   for j in range(num_tasks)]))
     30 

<ipython-input-52-2f567281d1e6> in <listcomp>(.0)
     27   # Objective
     28   solver.Minimize(solver.Sum([cost[i][j] *  x[i,j] for i in range(num_workers)
---> 29                                                   for j in range(num_tasks)]))
     30 
     31   # Constraints

KeyError: (0, 2)

1 个答案:

答案 0 :(得分:0)

您只生成变量x[i,j],其中cost[i][j]不是NA。因此,您需要在所有地方添加保护。在您的目标中:

solver.Minimize(solver.Sum([cost[i][j] *  x[i,j] for i in range(num_workers)
                                              for j in range(num_tasks)]))

你跑遍了所有的i,j。相反,您应该仅在cost[i][j]不是NA的i,j上运行。例如

solver.Minimize(solver.Sum([cost[i][j] *  x[i,j] for i in range(num_workers)
                                              for j in range(num_tasks) 
                                              if cost[i][j] != 'NA']))