如何用Or-Tools CP-SAT定义目标函数以最小化使用的唯一会议室数?
使用OR-Tools SAT最小化使用的会议室总数
你已经搭建了会议调度的基础模型,现在要实现最小化使用的不同会议室总数,核心思路是引入辅助布尔变量标记每个会议室是否被使用,再将这些变量的和作为目标函数最小化。具体实现如下:
步骤说明
1. 添加辅助布尔变量
为每个会议室创建一个布尔变量,用来标记该会议室是否有任何会议预订:
model = cp_model.CpModel() bookings = {} for m in meetings: for t in timeslots: for r in rooms: bookings[(m, t, r)] = model.NewBoolVar(f"{m}_{t}_{r}") # 新增:为每个会议室创建"是否被使用"的布尔变量 room_used = {} for r in rooms: room_used[r] = model.NewBoolVar(f"room_used_{r}")
2. 绑定会议室使用状态与预订情况
添加约束,确保会议室的"已使用"标记和实际预订情况严格对应:
# 保留原有约束 # 1. 每个会议必须举办一次 for m in meetings: model.AddExactlyOne(bookings[(m, t, r)] for r in rooms for t in timeslots) # 2. 无重复预订:同一时间段-会议室组合不能被两个会议占用 for t in timeslots: for r in rooms: model.AddAtMostOne(bookings[(m, t, r)] for m in meetings) # 新增约束:关联会议室使用状态与预订数据 for r in rooms: total_bookings = sum(bookings[(m, t, r)] for m in meetings for t in timeslots) # 若会议室标记为已使用,则必须有至少一次预订 model.Add(total_bookings >= 1).OnlyEnforceIf(room_used[r]) # 若会议室未被标记为已使用,则必须无任何预订 model.Add(total_bookings == 0).OnlyEnforceIf(room_used[r].Not())
3. 设置最小化目标函数
将所有"已使用"标记变量的总和作为目标,最小化这个值:
model.Minimize(sum(room_used[r] for r in rooms))
结果验证
求解完成后,可直接通过辅助变量快速计算使用的会议室数量:
solver = cp_model.CpSolver() status = solver.Solve(model) if status == cp_model.OPTIMAL: total_rooms_used = sum(solver.Value(room_used[r]) for r in rooms) print(f"Total rooms used: {total_rooms_used}")
内容的提问来源于stack exchange,提问作者Leszek Pachura
相关产品推荐
相关产品推荐

