Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 添加';至少休息一天';约束_Python_Or Tools - Fatal编程技术网

Python 添加';至少休息一天';约束

Python 添加';至少休息一天';约束,python,or-tools,Python,Or Tools,下面我简化了一个我正在尝试做的例子。我有一个每周的时间表和几个不同的“时段”要填补,在这里我最大限度地利用分配给每个时段的每个人的给定值 我试图添加一个约束条件,即他们每人都可以休息一天。我见过类似的问题,但我很难把它们翻译成这样,所以任何帮助都是感激的 我的想法是,我可以取每个人每天的最大值,即他们当前分配的任何一天的最大值为1,然后将所有天的最大值相加,并尝试使其小于或等于2(3天中的2天) 它为所有3天分配最大值。您不能对ortools创建的变量使用Max、min或 要对这些约束进行建模,

下面我简化了一个我正在尝试做的例子。我有一个每周的时间表和几个不同的“时段”要填补,在这里我最大限度地利用分配给每个时段的每个人的给定值

我试图添加一个约束条件,即他们每人都可以休息一天。我见过类似的问题,但我很难把它们翻译成这样,所以任何帮助都是感激的

我的想法是,我可以取每个人每天的最大值,即他们当前分配的任何一天的最大值为1,然后将所有天的最大值相加,并尝试使其小于或等于2(3天中的2天)


它为所有3天分配最大值。

您不能对ortools创建的变量使用
Max、min或

要对这些约束进行建模,只需创建中间变量就更容易了

工作日={
(person,day):model.NewBoolVar(f“{person}-{day}”)
为人处事
日复一日
}
对于人物中的人物:
对于以天为单位的天:
以天[日]为单位的小时:
作业[(人、天、小时)]=model.NewBoolVar(
f“{person}-{day}-{hour}”
)
模型.可加性(
作业[(人、日、时)],工作日[人、日]
)
对于人物中的人物:

model.Add(sum(以天为单位的工作日[人,日])您不能对ortools创建的变量使用
max、min或和

要对这些约束进行建模,只需创建中间变量就更容易了

工作日={
(person,day):model.NewBoolVar(f“{person}-{day}”)
为人处事
日复一日
}
对于人物中的人物:
对于以天为单位的天:
以天[日]为单位的小时:
作业[(人、天、小时)]=model.NewBoolVar(
f“{person}-{day}-{hour}”
)
模型.可加性(
作业[(人、日、时)],工作日[人、日]
)
对于人物中的人物:

model.Add(sum(工作日[人,天]以天为单位)这是完美的,有助于我做许多其他类似的事情!我没有考虑过使用这样的AddImplication,非常酷。是的,只是不要忘记这只是一个暗示,根据你想做什么,你可能还需要编写
model.Add(sum)(作业[(人,天,小时)],以天为单位[day])==0。仅限nForceif(工作日[person,day].Not())
最后一个等式由AddImplication隐含。您需要的是相反的:
model.AddBoolOr([assignments[…])。仅限nForceif(工作日)
。这是完美的,并且有助于我做许多其他类似的事情!我没有考虑过使用这样的AddImplication,非常酷。是的,请不要忘记这只是一个暗示,取决于你想做什么,你可能还必须编写
模型。添加(天中小时的总和(任务[(人,天,小时)]==0).OnlyEnforceIf(工作日[person,day].Not())
最后一个等式由AddImplication隐含。您需要的是相反的:
model.AddBoolOr([assignments[…])。OnlyEnforceIf(工作日)
from ortools.sat.python import cp_model

model = cp_model.CpModel()

assignments = {}

people = ['Max','Josh']

days = {
    'Monday':['7','8','9','10'],
    'Tuesday':['6','7','8','9','10'],
    'Wednesday':['7','8','9','10']
}

default_thing_we_like = 50

thing_we_like_per_employee_per_slot = {
    ('Max','Monday','7'): 100,
    ('Max','Tuesday','7'): 150,
    ('Max','Wednesday','7'): 200,
}

# make vars
for person in people:
    for day in days:
        for hour in days[day]:
            assignments[(person,day,hour)] = model.NewBoolVar(f'{person}-{day}-{hour}')

# fill each spot
for day in days:
    for hour in days[day]:
        model.Add(sum(assignments[(person,day,hour)] for person in people) == 1)

# everyone should get at least one of these days off
for person in people:
    for day in days:
        model.Add(sum(max(assignments.get((person,day,hour),0) for hour in days[day]) for day in days) <= 2)

solver = cp_model.CpSolver()

model.Maximize(sum(thing_we_like_per_employee_per_slot.get((person, day, hour),default_thing_we_like) * assignments[(person,day,hour)]
                                                    for hour in days[day]
                                                    for day in days
                                                    for person in people
                                                    ))


solution_printer = cp_model.ObjectiveSolutionPrinter()
status = solver.SolveWithSolutionCallback(model, solution_printer)

if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    ret_slots = []
    for person in people:
        print(f"{person} is working: ")
        for day in days:
            for hour in days[day]:
                if (solver.Value(assignments[(person,day,hour)])):
                    print(f"{day} at {hour} with",thing_we_like_per_employee_per_slot.get((person, day, hour),default_thing_we_like),"things we like.")
else:
    print("uh oh")
Solution 0, time = 0.00 s, objective = 900
Max is working: 
Monday at 7 with 100 things we like.
Monday at 9 with 50 things we like.
Tuesday at 6 with 50 things we like.
Tuesday at 7 with 150 things we like.
Tuesday at 8 with 50 things we like.
Tuesday at 9 with 50 things we like.
Tuesday at 10 with 50 things we like.
Wednesday at 7 with 200 things we like.
Wednesday at 8 with 50 things we like.
Wednesday at 9 with 50 things we like.
Wednesday at 10 with 50 things we like.
Josh is working: 
Monday at 8 with 50 things we like.
Monday at 10 with 50 things we like.
for person in people:
    model.Add(sum(works_day[person, day] for day in days) <= 2)