如何在or-tools中编写带有区间变量的替代约束?

问题描述 投票:0回答:1

如何在or-tools中编写带有区间变量的替代约束?我认为这样的方法可行,但 AddAlternative 方法不存在。另一个问题是如何知道区间变量是否处于活动状态

from ortools.sat.python import cp_model

# Crear el modelo
model = cp_model.CpModel()

# Crear la variable de intervalo
interval = model.NewIntervalVar(start, end, duration, 'interval')

# Crear los intervalos alternativos
alt_interval1 = model.NewIntervalVar(start1, end1, duration1, 'alt_interval1')
alt_interval2 = model.NewIntervalVar(start2, end2, duration2, 'alt_interval2')

# Agregar los intervalos alternativos a la variable de intervalo
model.AddAlternative(interval, [alt_interval1, alt_interval2])

# Resolver el modelo
solver = cp_model.CpSolver()
status = solver.Solve(model)

我的代码是:

# VARIABLES#
x = [
    model.NewIntervalVar(
        start=model.NewIntVar(es, lf, f"start_{row.id_pozo}"),
        size=model.NewIntVar(es, lf, f"size_{row.id_pozo}"),
        end=model.NewIntVar(es, lf, f"end_{row.id_pozo}"),
        name="pozo_intv_{}".format(row.id_pozo),
    )
    for row in pozos.itertuples()
]

y = [
    model.NewOptionalIntervalVar(
        start=model.NewIntVar(row.dia_inicio, row.dia_fin, f"start_{idx}"),
        size=row.tiempo_total,
        end=model.NewIntVar(row.dia_inicio, row.dia_fin, f"end_{idx}"),
        is_present=True,
        name="pte_intv_{}".format(idx),
    )
    for idx, row in pozo_time_equipment.iterrows()
]
or-tools constraint-programming cp-sat
1个回答
2
投票

这是一个灵活的作业车间问题。在OR工具源中有一个工作示例。基础知识是,首先为每个任务创建主要间隔:

    # Create main interval for the task.
    suffix_name = '_j%i_t%i' % (job_id, task_id)
    start = model.NewIntVar(0, horizon, 'start' + suffix_name)
    duration = model.NewIntVar(min_duration, max_duration,
                               'duration' + suffix_name)
    end = model.NewIntVar(0, horizon, 'end' + suffix_name)
    interval = model.NewIntervalVar(start, duration, end,
                                    'interval' + suffix_name)

然后对于每个替代方案,创建一个额外的间隔:

            alt_suffix = '_j%i_t%i_a%i' % (job_id, task_id, alt_id)
            l_presence = model.NewBoolVar('presence' + alt_suffix)
            l_start = model.NewIntVar(0, horizon, 'start' + alt_suffix)
            l_duration = task[alt_id][0]
            l_end = model.NewIntVar(0, horizon, 'end' + alt_suffix)
            l_interval = model.NewOptionalIntervalVar(
                l_start, l_duration, l_end, l_presence,
                'interval' + alt_suffix)
            l_presences.append(l_presence)

仅当选择了替代项时,替代项才会链接到主间隔:

            # Link the primary/global variables with the local ones.
            model.Add(start == l_start).OnlyEnforceIf(l_presence)
            model.Add(duration == l_duration).OnlyEnforceIf(l_presence)
            model.Add(end == l_end).OnlyEnforceIf(l_presence)

最后,添加一个约束以确保仅选择其中一个替代方案:

        # Select exactly one presence variable.
        model.AddExactlyOne(l_presences)
© www.soinside.com 2019 - 2024. All rights reserved.