计算调度问题中的雇佣天数 [英] Calculate hired days in a scheduling problem

查看:94
本文介绍了计算调度问题中的雇佣天数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在调度问题中,我还想尽量减少总雇佣天数.

In a scheduling problem I also want to minimize the total hired days.

如果员工在某一天之前和之后工作,则他/她在某一天被雇用.

A employee is hired in a given day if he/she works before that day and also after that day.

这是一个小的工作示例:

Here is a small working example:

import random
from ortools.sat.python import cp_model

model = cp_model.CpModel()
solver = cp_model.CpSolver()

employees = range(3)
days = range(10)

works_day = {(e, d): model.NewBoolVar(f'{e}_works_{d}')
             for e in employees for d in days}
hired_day = {(e, d): model.NewBoolVar(f'{e}_employed_{d}')
             for e in employees for d in days}

# random example
for boolean in works_day.values():
    model.Add(boolean == random.choice([0, 1]))

# give value to hired_day
add_hired_days()

# solve
print('Variables:', len(model.Proto().variables))
print('Constraints:', len(model.Proto().constraints))
status = solver.Solve(model)

for e in employees:
    print()
    print('Employee', e)
    for d in days:
        print('Works', solver.Value(works_day[e, d]),
              'Hired', solver.Value(hired_day[e, d]))

add_hired_days 在哪里:

def add_hired_days():
    for idx, d in enumerate(days):
        for e in employees:
            model.AddImplication(works_day[e, d], hired_day[e, d])
            previous = [works_day[e, d] for d in days[:idx + 1]]
            following = [works_day[e, d] for d in days[idx:]]

            # too many variables
            works_previous = model.NewBoolVar('')
            works_following = model.NewBoolVar('')

            model.AddBoolOr(previous).OnlyEnforceIf(works_previous)
            model.AddBoolAnd([d.Not() for d in previous
                              ]).OnlyEnforceIf(works_previous.Not())

            model.AddBoolOr(following).OnlyEnforceIf(works_following)
            model.AddBoolAnd([d.Not() for d in following
                              ]).OnlyEnforceIf(works_following.Not())

            model.AddBoolAnd([works_previous, works_following
                              ]).OnlyEnforceIf(hired_day[e, d])
            model.AddBoolOr([works_previous.Not(),
                             works_following.Not()
                             ]).OnlyEnforceIf(hired_day[e, d].Not())

有没有办法在不创建这么多变量和约束的情况下做到这一点?

Is there any way to do this without creating this many variables and constraints?

推荐答案

如果员工一个月工作 n 天,他需要被雇佣 n - 2 次.

if an employee works n days in a month, he needs to be hired n - 2 times.

这篇关于计算调度问题中的雇佣天数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆