微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 OR 工具解决多参与者分配问题

如何解决使用 OR 工具解决多参与者分配问题

我正在尝试使用 Python 中的 OR 工具(OR 工具的新手)解决类似于 https://developers.google.com/optimization/assignment/assignment_groups 的赋值问题。也就是说,我想将会议分配到 4 个时间段,供 3 ​​个与会者使用。我被告知参加者 1 应参加 M1、M2、M3,参加者 2 应参加 M2、M3、M5,参加者 3 应参加 M3、M4、M5。其他限制是没有一个时间段有多个会议(对于每个与会者),并且每个会议都被分配到一个时间段(对于每个与会者)。为简单起见,我假设每位与会者有 4 个空闲时间段。

!pip install ortools
from ortools.sat.python import cp_model # CP-SAT solver (primary constraint solver of ORtools)
from ortools.linear_solver import pywraplp
from __future__ import print_function
from ortools.sat.python import cp_model

model = cp_model.CpModel()
num_meetings = 5
num_slots = 4



#attendees X meetings
my_array = [[1,1,1],[0,1]]

#meetings X attendees
my_array_2 = [[0],[1,2],[2],2]]

# Declare the variables.
a = []
for i in range(3):
  b = []
  for j in range(num_meetings):
    c = []
    for k in range(num_slots):
      c.append(model.NewIntvar(0,"a[%i,%i,%i]" % (i,j,k)))
    b.append(c)
  a.append(b)
a_array = [a[i][j][k] for i in range(3) for j in range(num_meetings) for k in range(num_slots)]


#Define the attendees of each meeting:
for d in range(3):
    for s in range(num_meetings):
        model.Add(sum(a[d][s][k] for k in range(num_slots)) == my_array[d][s])

#Requirement 1: no timeslot has more than one meeting mapped to it,for d in range(3):
    for k in range(num_slots):
        model.Add(sum(a[d][s][k] for s in range(num_meetings)) <= 1)

#Requirement 2:
#this should force the attendees with the same meetings to have the same time slot
for i in range(num_meetings):
  print('meeting',i+1)
  print('------------')
  for j in range(len(my_array_2[i])):
    print('attendee',my_array_2[i][j]+1)
    model.Add(sum(a[my_array_2[i][j]][i][k] for k in range(num_slots)) == 1)
  print('------------')



#call the solver:
solver = cp_model.cpsolver()
status = solver.solve(model)
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
  print('Solved')
else:
  print(status)


#print the solutions
for i in range(3):
  for j in range(num_meetings):
    for k in range(num_slots):
      if solver.Value(a[i][j][k]) == 1:
        print('user',i+1,'meeting',j+1,'slot',k+1,'value:',solver.Value(a[i][j][k]))

求解器工作到一定程度,因为它正确分配了每个会议,没有与会者在同一时间段有多个会议。但是,由于某种原因,该解决方案强制前 3 个时间段内的所有会议,导致最后一个时间段对每个与会者都是免费的。这会导致与会者参加同一个会议,但每个人都在不同的时间段中。理想情况下,要求 2 会强制同一会议的与会者在同一时间段开会。

解决方法

  1. 如果问题因为容量不可行,则没有额外的约束使其可行
  2. 您正在向同一变量列表中添加 3 个不兼容的 AddAllowedAssignment() 约束。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。