Exemple #1
0
def cplex_makespan_model(n: int, m: int, durations, machines) -> CpoModel:
    # n number of jobs, m machines
    # 1 line for un job with tasks on m machines

    naive = np.sum(durations)

    mdl = CpoModel()

    #Une variable est l'intervalle de durée pour une tache
    x = [[
        mdl.interval_var(size=durations[i, j], name="O{}-{}".format(i, j))
        for j in range(m)
    ] for i in range(n)]

    #contrainte end max d'une tache calculée avant
    for i in range(n):
        for j in range(m):
            mdl.add(mdl.end_of(x[i][j]) <= naive)

    #precedence
    for i in range(n):  #for each job
        for j in range(m - 1):  #taches ordonnées
            mdl.add(mdl.end_before_start(x[i][j], x[i][j + 1]))

    # une machine ne peut faire qu'une tache à la fois
    listtaches = [[] for k in range(m)]
    for i in range(n):
        for j in range(m):
            listtaches[machines[i, j]].append(x[i][j])

    for k in range(m):
        mdl.add(mdl.no_overlap(listtaches[k]))

    makespan = mdl.integer_var(0, naive, name="makespan")
    # le makespan est le max des tps pour chaque job
    mdl.add(makespan == mdl.max([mdl.end_of(x[i][m - 1]) for i in range(n)]))

    mdl.add(mdl.minimize(makespan))

    return mdl, x
Exemple #2
0
def recherche_exact(instance, temps):
    '''
    :param temps: int, temps de recherche
    :param instance: nom de l'instance str
    :return: None
    '''
    problem_data, optimum = loader(instance)
    nb_machine = problem_data["nb_machine"]
    nb_jobs = problem_data["nb_jobs"]
    problem = problem_data["problem"]

    machine, durations = separate(problem)

    model = CpoModel(name='Scheduling')

    # Variable
    job_operations = [[model.interval_var(size=durations[j][m],
                                          name="O{}-{}".format(j, m)) for m in range(nb_machine)] for j in
                      range(nb_jobs)]

    # chaque opération doit commencer aprés la fin de la précedente
    for j in range(nb_jobs):
        for s in range(1, nb_machine):
            model.add(model.end_before_start(job_operations[j][s - 1], job_operations[j][s]))

    # Pas d'overlap pour les operations executées sur une même machine
    machine_operations = [[] for m in range(nb_machine)]
    for j in range(nb_jobs):
        for s in range(0, nb_machine):
            machine_operations[machine[j][s]].append(job_operations[j][s])
    for lops in machine_operations:
        model.add(model.no_overlap(lops))

    # Minimiser la date de fin
    model.add(model.minimize(model.max([model.end_of(job_operations[i][nb_machine - 1]) for i in range(nb_jobs)])))

    # Solve model
    print("Solving model....")
    msol = model.solve(TimeLimit=temps)
Exemple #3
0
    dem_non_renewables = m[3 + NB_RENEWABLE:3 + NB_RENEWABLE +
                           NB_NON_RENEWABLE]
    mode = Mode("T{}-M{}".format(taskid, modeid), tasks_data[taskid], dur,
                dem_renewables, dem_non_renewables)
    tasks_data[taskid].modes.append(mode)
    modes_data.append(mode)

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per task
tasks = {t: mdl.interval_var(name=t.name) for t in tasks_data}

# Add precedence constraints
for t in tasks_data:
    for s in t.successors:
        mdl.add(mdl.end_before_start(tasks[t], tasks[tasks_data[s]]))

# Create one optional interval variable per mode
modes = {
    m: mdl.interval_var(name=m.name, optional=True, size=m.duration)
    for m in modes_data
}

# Add mode alternative for each task
for t in tasks_data:
    mdl.add(mdl.alternative(tasks[t], [modes[m] for m in t.modes]))
Exemple #4
0
    os.path.abspath(__file__)) + "/data/flowshop_default.data"
with open(filename, "r") as file:
    NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()]
    JOB_DURATIONS = [[int(v) for v in file.readline().split()]
                     for i in range(NB_JOBS)]

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per job operation
job_operations = [[
    mdl.interval_var(size=JOB_DURATIONS[j][m], name="J{}-M{}".format(j, m))
    for m in range(NB_MACHINES)
] for j in range(NB_JOBS)]

# Force each operation to start after the end of the previous
for j in range(NB_JOBS):
    for m in range(1, NB_MACHINES):
        mdl.add(
            mdl.end_before_start(job_operations[j][m - 1],
                                 job_operations[j][m]))

# Force no overlap for operations executed on a same machine
for m in range(NB_MACHINES):
    mdl.add(mdl.no_overlap([job_operations[j][m] for j in range(NB_JOBS)]))

# Minimize termination date
# Assign an index to tasks
ALL_TASKS = (MASONRY, CARPENTRY, PLUMBING, CEILING, ROOFING, PAINTING, WINDOWS,
             FACADE, GARDEN, MOVING)
for i in range(len(ALL_TASKS)):
    ALL_TASKS[i].id = i

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create interval variable for each building task
tasks = [mdl.interval_var(size=t.duration, name=t.name) for t in ALL_TASKS]

# Add precedence constraints
for p, s in PRECEDENCES:
    mdl.add(mdl.end_before_start(tasks[p.id], tasks[s.id]))

# Cost function
cost = []  # List of individual costs
fearliness = dict()  # Task earliness cost function (for display)
ftardiness = dict()  # Task tardiness cost function (for display)

for t in ALL_TASKS:
    task = tasks[t.id]
    if t.release_date is not None:
        f = CpoSegmentedFunction((-t.earliness_cost, 0),
                                 [(t.release_date, 0, 0)])
Exemple #6
0
def main():
    filename = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "data_in/test_1.txt")
    inst = instance.Instance(filename)

    # input from master problem, now random
    id_profile = 0
    random.seed(42)
    rewards = [random.randint(0, 30000) for i in range(inst.J)]
    #rewards = [random.uniform(0.0, 30000.0) for i in range(inst.J)]
    equivalences = [[0, 1], [2, 3]]
    mutexes = [[2, 1], [4, 3]]
    # input from master problem, now random

    types = inst.profiles[id_profile]
    types.insert(0, inst.INIT)
    types.append(inst.TERM)
    trans_cost = [[0 for i in range(inst.V)] for j in range(inst.V)]
    trans_time = [[0 for i in range(inst.V)] for j in range(inst.V)]
    for i in range(len(inst.edges)):
        for j in range(len(inst.edges[i])):
            trans_cost[i][inst.edges[i][j][
                'to']] = inst.edges[i][j]['C'] * inst.edges[i][j]['t']
            trans_time[i][inst.edges[i][j]['to']] = inst.edges[i][j]['t']
    changeover_cost = 0
    for i in range(1, len(types)):
        changeover_cost += trans_cost[types[i - 1]][types[i]]

    cp = CpoModel()
    primitives = [[] for i in range(inst.J)]
    all_primitives = []
    init = cp.interval_var(start=0)
    init.set_end_max(inst.L)
    total_cost = changeover_cost + inst.vertices[
        inst.INIT]['C'] * cp.length_of(init, 0)
    modes_of_mach = [init
                     ]  # serves only for retrieving starts and ends of modes
    last_shift = init
    for i in range(1, len(types) - 1):
        v = types[i]
        shift = cp.interval_var()
        shift.set_size_min(inst.vertices[v]['t_min'])
        shift.set_size_max(inst.vertices[v]['t_max'])
        shift.set_end_max(inst.L)
        total_cost += inst.vertices[v]['C'] * cp.length_of(shift, 0)
        cp.add(
            cp.start_at_end(shift, last_shift,
                            -trans_time[types[i - 1]][types[i]]))
        last_shift = shift
        modes_of_mach.append(shift)
        for t in range(inst.J):
            if inst.tasks[t]['p'][v] <= inst.L:
                prim = cp.interval_var(size=inst.tasks[t]['p'][v])
                total_cost -= rewards[t] * cp.presence_of(prim)
                prim.set_optional()
                prim.set_start_min(inst.tasks[t]['r'])
                prim.set_end_max(inst.tasks[t]['d'])
                primitives[t].append(prim)
                all_primitives.append(prim)
                cp.add(cp.start_before_start(shift, prim))
                cp.add(cp.end_before_end(prim, shift))
    term = cp.interval_var(end=inst.L)
    total_cost += inst.vertices[inst.TERM]['C'] * cp.length_of(term, 0)
    cp.add(
        cp.start_at_end(term, last_shift,
                        -trans_time[types[len(types) - 2]][inst.TERM]))
    modes_of_mach.append(term)
    cp.add(cp.no_overlap(cp.sequence_var(all_primitives)))
    for t in range(inst.J):
        cp.add(sum([cp.presence_of(p) for p in primitives[t]]) <= 1)
    for eq in equivalences:
        cp.add(
            sum([cp.presence_of(p) for p in primitives[eq[0]]]) == sum(
                [cp.presence_of(p) for p in primitives[eq[1]]]))
    for mut in mutexes:
        cp.add(
            sum([cp.presence_of(p) for p in primitives[mut[0]]]) +
            sum([cp.presence_of(p) for p in primitives[mut[1]]]) <= 1)
    cp.add(cp.minimize(total_cost))

    # set TimeLimit in seconds or delete it for no limit
    # parameters DefaultInferenceLevel and Workers may be beneficial to add
    sol = cp.solve(
        TimeLimit=30,
        LogVerbosity="Quiet")  #, DefaultInferenceLevel='Extended', Workers=1)
    if sol:
        tasks = []
        for t in range(inst.J):
            for pr in primitives[t]:
                p = sol.get_var_solution(pr)
                if p.is_present():
                    tasks.append({
                        "task": t,
                        "start": p.get_start(),
                        "end": p.get_end()
                    })
                    break
        modes = []
        sched_cost = 0
        for t in range(len(modes_of_mach)):
            m = sol.get_var_solution(modes_of_mach[t])
            modes.append({
                "mode": types[t],
                "start": m.get_start(),
                "end": m.get_end()
            })
            sched_cost += inst.vertices[types[t]]['C'] * m.get_length()
        print("Solution status: " + sol.get_solve_status())
        print("Solve time: " + str(sol.get_solve_time()))
        print("Objective: " + str(sol.get_objective_values()[0]))
        print("Schedule cost: " + str(sched_cost))
        print(tasks)
        print(modes)
    else:
        print("No solution found.")
Exemple #7
0
#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Variables of the model
tasks = {}  # dict of interval variable for each house and task
wtasks = {}  # dict of interval variable for each house and skill
for house in HOUSES:
    for task in TASKS:
        v = (0, MAX_SCHEDULE)
        tasks[(house, task)] = mdl.interval_var(v,
                                                v,
                                                size=task.duration,
                                                name="house {} task {}".format(
                                                    house, task))
    for task in SKILLS:
        wtasks[(house, task)] = mdl.interval_var(
            optional=True, name="house {} skill {}".format(house, task))

# Maximization objective of the model
obj2 = mdl.sum([
    s.level * mdl.presence_of(wtasks[(h, s)]) for s in SKILLS for h in HOUSES
])
mdl.add(mdl.maximize(obj2))

# Constraints of the model
for h in HOUSES:
    # Temporal constraints
Exemple #8
0

# Построим модель
mdl = CpoModel()

tasks = []

# заведём задачи по монтажникам
for i in range(WORKERS_COUNT):
    worker_tasks = []
    for j in range(ORDERS_COUNT):
        if all([(a >= b) for a, b in zip(INSTALLERS[i][1:], WAIT_ORDERS[j][2:])]):
            worker_tasks.append(
                mdl.interval_var(size=WAIT_ORDERS[j][0],
                                 name=TASK_TEMPLATE_NAME.format(num=str(j), name=WAIT_ORDERS[j][1]),
                                 start=(0, MAX_SCHEDULE),
                                 end=(0, MAX_SCHEDULE),
                                 optional=True)
            )
    tasks.append(worker_tasks)

# посмотрим, что создали
# print_tasks(tasks)

# Реально выполняемые задачи
tasks_act = [mdl.interval_var(name="T{}_{}".format(str(i), WAIT_ORDERS[i][1]),
                              size=WAIT_ORDERS[i][0],
                              start=(0, MAX_SCHEDULE),
                              end=(0, MAX_SCHEDULE)) for i in range(ORDERS_COUNT)]

# одна задача - один монтажник
# Size of the englobing square
SIZE_SQUARE = 112

# Sizes of the sub-squares
SIZE_SUBSQUARE = [50, 42, 37, 35, 33, 29, 27, 25, 24, 19, 18, 17, 16, 15, 11, 9, 8, 7, 6, 4, 2]
NB_SUBSQUARE = len(SIZE_SUBSQUARE)

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create array of variables for subsquares
vx = [mdl.interval_var(size=SIZE_SUBSQUARE[i], name="X" + str(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)]
vy = [mdl.interval_var(size=SIZE_SUBSQUARE[i], name="Y" + str(i), end=(0, SIZE_SQUARE)) for i in range(NB_SUBSQUARE)]

# Create dependencies between variables
for i in range(len(SIZE_SUBSQUARE)):
    for j in range(i):
        mdl.add(  (mdl.end_of(vx[i]) <= mdl.start_of(vx[j])) | (mdl.end_of(vx[j]) <= mdl.start_of(vx[i]))
                | (mdl.end_of(vy[i]) <= mdl.start_of(vy[j])) | (mdl.end_of(vy[j]) <= mdl.start_of(vy[i])))

# To speed-up the search, create cumulative expressions on each dimension
rx = mdl.sum([mdl.pulse(vx[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)])
mdl.add(mdl.always_in(rx, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE))

ry = mdl.sum([mdl.pulse(vy[i], SIZE_SUBSQUARE[i]) for i in range(NB_SUBSQUARE)])
mdl.add(mdl.always_in(ry, (0, SIZE_SQUARE), SIZE_SQUARE, SIZE_SQUARE))
Exemple #10
0
def floorPlanner(CONFIG, SCHEDULER, RATE, printFlag=0, figFlag=0):
    HEIGHT_REC = 4
    WIDTH_REC = 4
    NUM_RESOURCES = 16

    # Sizes of the hardware resources
    SIZE_HARDWARE = [1 for _ in range(NUM_RESOURCES)]

    RESOUCE_dict = {
        0: 'A72',
        1: 'A53-0',
        2: 'A53-1',
        3: 'FFT',
        4: 'DAP-0',
        5: 'DAP-1',
        6: 'Memory',
        7: 'Cache-1',
        8: 'Cache-2',
        9: 'Cache-3',
        10: 'Cache-4'
    }

    # read from rpt file
    df = pd.read_fwf("inputs/" + CONFIG + "/trace_" + SCHEDULER + "_" + RATE +
                     "/matrix_traffic_" + SCHEDULER + "_" + RATE +
                     ".rpt")  # read file   --- MODIFY HERE
    df = df.drop(df.columns[df.columns.str.contains('unnamed', case=False)],
                 axis=1)  # drop unnamed
    df = df.drop(range(10))  # drop the first 10 lines
    vol = df.values.tolist()
    vol_commu = [list(map(int, i)) for i in vol]

    extend_factor = NUM_RESOURCES - len(vol_commu)
    for i in range(extend_factor):
        RESOUCE_dict[len(vol_commu) + i] = 'empty'

    for _ in range(extend_factor):
        for row in range(len(vol_commu)):
            vol_commu[row].extend([0])
    for _ in range(extend_factor):
        vol_commu.append([0 for _ in range(len(vol_commu[0]))])

    #-----------------------------------------------------------------------------
    # Build the model
    #-----------------------------------------------------------------------------

    # Create model
    mdl = CpoModel()

    # Create array of variables for subsquares
    vx = [
        mdl.interval_var(size=SIZE_HARDWARE[i],
                         name="X" + str(i),
                         end=(0, WIDTH_REC)) for i in range(NUM_RESOURCES)
    ]
    vy = [
        mdl.interval_var(size=SIZE_HARDWARE[i],
                         name="Y" + str(i),
                         end=(0, HEIGHT_REC)) for i in range(NUM_RESOURCES)
    ]

    # Create dependencies between variables
    for i in range(len(SIZE_HARDWARE)):
        for j in range(i):
            mdl.add((mdl.end_of(vx[i]) <= mdl.start_of(vx[j]))
                    | (mdl.end_of(vx[j]) <= mdl.start_of(vx[i]))
                    | (mdl.end_of(vy[i]) <= mdl.start_of(vy[j]))
                    | (mdl.end_of(vy[j]) <= mdl.start_of(vy[i])))

    # Set up the objective
    """
    obj = mdl.minimize( mdl.sum( vol_commu[i][j] * ( mdl.max( [mdl.end_of(vx[i]) - mdl.end_of(vx[j]), mdl.end_of(vx[j]) - mdl.end_of(vx[i])] )\
                                                     + mdl.max( [mdl.start_of(vy[i]) - mdl.end_of(vy[j]), mdl.start_of(vy[j]) - mdl.end_of(vy[i])] ) ) \
                                 for i in range(NUM_RESOURCES) for j in range(NUM_RESOURCES) if vol_commu[i][j]) )
    """
    obj = mdl.minimize( mdl.sum( vol_commu[i][j] * ( mdl.max( [mdl.end_of(vx[i]) - mdl.end_of(vx[j]), mdl.end_of(vx[j]) - mdl.end_of(vx[i])] )\
                                                     + mdl.min([mdl.min([mdl.max( [mdl.start_of(vy[i]) - mdl.end_of(vy[j]), 0] ), mdl.max( [mdl.start_of(vy[j]) - mdl.end_of(vy[i]), 0] )]), 1]) ) \
                                 for i in range(NUM_RESOURCES) for j in range(NUM_RESOURCES) if vol_commu[i][j]) )

    mdl.add(obj)

    # To speed-up the search, create cumulative expressions on each dimension
    rx = mdl.sum(
        [mdl.pulse(vx[i], SIZE_HARDWARE[i]) for i in range(NUM_RESOURCES)])
    mdl.add(mdl.always_in(rx, (0, WIDTH_REC), WIDTH_REC, WIDTH_REC))

    ry = mdl.sum(
        [mdl.pulse(vy[i], SIZE_HARDWARE[i]) for i in range(NUM_RESOURCES)])
    mdl.add(mdl.always_in(ry, (0, HEIGHT_REC), HEIGHT_REC, HEIGHT_REC))

    # Define search phases, also to speed-up the search
    mdl.set_search_phases([mdl.search_phase(vx), mdl.search_phase(vy)])

    #-----------------------------------------------------------------------------
    # Solve the model and display the result
    #-----------------------------------------------------------------------------

    # Solve model
    print("Solving model....")
    msol = mdl.solve(TimeLimit=20, LogPeriod=50000)
    if printFlag:
        print("Solution: ")
        msol.print_solution()

    if msol and visu.is_visu_enabled():
        import matplotlib.pyplot as plt
        import matplotlib.cm as cm
        from matplotlib.patches import Polygon
        import matplotlib.ticker as ticker

        # Plot external square
        if figFlag:
            plt.show()
            print("Plotting squares....")
        fig, ax = plt.subplots()
        plt.plot((0, 0), (0, HEIGHT_REC), (WIDTH_REC, HEIGHT_REC),
                 (WIDTH_REC, 0))
        plt.xlim((0, WIDTH_REC))
        plt.ylim((0, HEIGHT_REC // 2))
        for i in range(len(SIZE_HARDWARE)):
            # Display square i
            sx, sy = msol.get_var_solution(vx[i]), msol.get_var_solution(vy[i])
            (sx_st, sx_ed, sy_st, sy_ed) = (sx.get_start(), sx.get_end(),
                                            sy.get_start(), sy.get_end())

            # transform
            #sx1, sx2, sy1, sy2 = sx_st, sx_ed, sy_st, sy_ed
            sx1 = sx_st + 0.5 if sy_st % 2 else sx_st
            sy1 = sy_st / 2
            sx2, sy2 = sx1 + 0.5, sy1 + 0.5

            poly = Polygon([(sx1, sy1), (sx1, sy2), (sx2, sy2), (sx2, sy1)],
                           fc=cm.Set2(float(i) / len(SIZE_HARDWARE)))
            ax.add_patch(poly)
            # Display identifier of square i at its center
            ax.text(float(sx1 + sx2) / 2,
                    float(sy1 + sy2) / 2,
                    RESOUCE_dict[i],
                    ha='center',
                    va='center')
            ax.xaxis.set_major_locator(ticker.MultipleLocator(0.5))
            ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5))
        plt.margins(0)
        fig.savefig("outputs/MESH/" + CONFIG + "_" + SCHEDULER + "_" + RATE +
                    ".png")
        if figFlag:
            plt.show()
Exemple #11
0
# Extract demand of each task
DEMANDS = [TASKS[t][1:NB_RESOURCES + 1] for t in range(NB_TASKS)]

# Extract successors of each task
SUCCESSORS = [TASKS[t][NB_RESOURCES + 2:] for t in range(NB_TASKS)]


#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create task interval variables
tasks = [mdl.interval_var(name="T{}".format(i + 1), size=DURATIONS[i]) for i in range(NB_TASKS)]

# Add precedence constraints
for t in range(NB_TASKS):
    for s in SUCCESSORS[t]:
        mdl.add(mdl.end_before_start(tasks[t], tasks[s - 1]))

# Constrain capacity of resources
for r in range(NB_RESOURCES):
    resources = [mdl.pulse(tasks[t], DEMANDS[t][r]) for t in range(NB_TASKS) if DEMANDS[t][r] > 0]
    mdl.add(mdl.sum(resources) <= CAPACITIES[r])

# Minimize end of all tasks
mdl.add(mdl.minimize(mdl.max([mdl.end_of(t) for t in tasks])))

Exemple #12
0
    def create_model(self):
        mdl = CpoModel(name = "TAS Scheduling")
        #####################################################
        # Creating interval variables for WEST module
        #####################################################
        i = 0
        MS1_vars = []
        MS4_vars = []
        GTW_vars = []
        WEST_vars = []
        table_occupied_WEST = []

        kits_pulse_for_choice = []
        for i in range(len(self.timeOUEST)):
            min_start_time = int(date_converter.convert_to_work_time(datetime.timestamp(pd.to_datetime(self.req_matOUEST.iloc[i,2]))))

            #print(min_start_time, self.req_matOUEST.iloc[i,2])
            meca_length = int(self.timeOUEST.iloc[i, 2] / 10)
            qc_length = int(self.timeOUEST.iloc[i, 3] / 10)

            kit_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), name = "kitting " + self.timeOUEST.index[i])
            kit_interval1mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_max, name = "kitting 1 op " + self.timeOUEST.index[i], optional = True)
            kit_interval2mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_mid, name = "kitting 2 op " + self.timeOUEST.index[i], optional = True)
            kit_interval3mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_min, name = "kitting 3 op " + self.timeOUEST.index[i], optional = True)

            mdl.add(mdl.alternative(interval = kit_interval, array = [kit_interval1mec, kit_interval2mec, kit_interval3mec]))

            kits_pulse_for_choice += [kit_interval1mec, kit_interval2mec, kit_interval3mec]

            meca_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = meca_length, name = "meca " + self.timeOUEST.index[i])
            qc_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = qc_length, name = "qc " + self.timeOUEST.index[i])

            table_slot_occupied_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = (0, 9999999999999), name = "Table occupied " + self.timeOUEST.index[i])
            table_occupied_WEST += [table_slot_occupied_interval]

            mdl.add(mdl.end_before_start(kit_interval, meca_interval))
            mdl.add(mdl.end_before_start(meca_interval, qc_interval))

            mdl.add(mdl.start_at_end(table_slot_occupied_interval, kit_interval))
            mdl.add(mdl.start_at_end(meca_interval, table_slot_occupied_interval))
            
            WEST_vars += [kit_interval]
            WEST_vars += [meca_interval]
            WEST_vars += [qc_interval]

            if i < 19:
                MS1_vars += [kit_interval]
                MS1_vars += [meca_interval]
                MS1_vars += [qc_interval]

            elif i >= 45:
                GTW_vars += [kit_interval]
                GTW_vars += [meca_interval]
                GTW_vars += [qc_interval]
            
            else:
                MS4_vars += [kit_interval]
                MS4_vars += [meca_interval]
                MS4_vars += [qc_interval]


        ######################################################
        # Creating interval variables for EAST module
        ######################################################
        FOV_vars = []
        MS2_vars = []
        MS3_vars = []
        EAST_vars = []
        table_occupied_EAST = []

        for i in range(len(self.timeEST)):
            min_start_time = int(date_converter.convert_to_work_time(datetime.timestamp(pd.to_datetime(self.req_matOUEST.iloc[i,2]))))

            meca_length = int(self.timeOUEST.iloc[i, 2] / 10)
            qc_length = int(self.timeOUEST.iloc[i, 3] / 10)
            
            kit_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), name = "kitting " + self.timeEST.index[i])
            kit_interval1mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_max, name = "kitting 1 op " + self.timeEST.index[i], optional = True)
            kit_interval2mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_mid, name = "kitting 2 op " + self.timeEST.index[i], optional = True)
            kit_interval3mec = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = self.kitting_time_min, name = "kitting 3 op " + self.timeEST.index[i], optional = True)

            mdl.add(mdl.alternative(interval = kit_interval, array = [kit_interval1mec, kit_interval2mec, kit_interval3mec]))

            kits_pulse_for_choice += [kit_interval1mec, kit_interval2mec, kit_interval3mec]

            meca_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = meca_length, name = "meca " + self.timeEST.index[i])
            qc_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = qc_length, name = "qc " + self.timeEST.index[i])

            table_slot_occupied_interval = mdl.interval_var(start = (min_start_time, self.max_end_timestamp), length = (0, 9999999999999), name = "Table occupied " + self.timeEST.index[i])
            table_occupied_EAST += [table_slot_occupied_interval]

            mdl.add(mdl.end_before_start(kit_interval, meca_interval))
            mdl.add(mdl.end_before_start(meca_interval, qc_interval))

            mdl.add(mdl.start_at_end(table_slot_occupied_interval, kit_interval))
            mdl.add(mdl.start_at_end(meca_interval, table_slot_occupied_interval))

            EAST_vars += [kit_interval]
            EAST_vars += [meca_interval]
            EAST_vars += [qc_interval]
            
            if i < 11:
                FOV_vars += [kit_interval]
                FOV_vars += [meca_interval]
                FOV_vars += [qc_interval]

            elif i >= 25:
                MS3_vars += [kit_interval]
                MS3_vars += [meca_interval]
                MS3_vars += [qc_interval]

            else:
                MS2_vars += [kit_interval]
                MS2_vars += [meca_interval]
                MS2_vars += [qc_interval]

        ##################################################
        # Setting requirement relations between interval variables
        ##################################################
        for task in MS1_vars:
            for i in range(len(self.req_taskOUEST)):
                if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskOUEST.iloc[i, 0])):
                        for other_task in WEST_vars:
                            if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))
        #print("##############################################")
        for task in MS4_vars:
            for i in range(len(self.req_taskOUEST)):
                if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskOUEST.iloc[i, 0])):
                        for other_task in WEST_vars:
                            if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))
        #print("##############################################")
        for task in GTW_vars:
            for i in range(len(self.req_taskOUEST)):
                if (self.req_taskOUEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskOUEST.iloc[i, 0])):
                        for other_task in WEST_vars:
                            if self.req_taskOUEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))
        #print("##############################################")
        for task in MS2_vars:
            for i in range(len(self.req_taskEST)):
                if (self.req_taskEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskEST.iloc[i, 0])):
                        for other_task in EAST_vars:
                            if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))
        #print("##############################################")
        for task in MS3_vars:
            for i in range(len(self.req_taskEST)):
                if (self.req_taskEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskEST.iloc[i, 0])):
                        for other_task in EAST_vars:
                            if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))
        #print("##############################################")
        for task in FOV_vars:
            for i in range(len(self.req_taskEST)):
                if (self.req_taskEST.index[i] in task.name) and "meca" in task.name:
                    for j in range(len(self.req_taskEST.iloc[i, 0])):
                        for other_task in EAST_vars:
                            if self.req_taskEST.iloc[i, 0][j] in other_task.name and "qc" in other_task.name:
                                mdl.add(mdl.end_before_start(other_task, task))

        ##############################################
        # Adding resources constraints
        ##############################################

        all_tasks = EAST_vars + WEST_vars

        meca_resources = [mdl.pulse(task, 1) for task in EAST_vars if "meca" in task.name]
        meca_resources += [mdl.pulse(task, 1) for task in WEST_vars if "meca" in task.name]
        meca_resources += [mdl.pulse(task, 1) for task in kits_pulse_for_choice if "kitting 1 op" in task.name]
        meca_resources += [mdl.pulse(task, 2) for task in kits_pulse_for_choice if "kitting 2 op" in task.name]
        meca_resources += [mdl.pulse(task, 3) for task in kits_pulse_for_choice if "kitting 3 op" in task.name]

        qc_resources = [mdl.pulse(task, 1) for task in EAST_vars if "qc" in task.name]
        qc_resources += [mdl.pulse(task, 1) for task in WEST_vars if "qc" in task.name]

        work_slots_EAST = [mdl.pulse(task, 1) for task in EAST_vars if "qc" in task.name or "meca" in task.name]
        work_slots_WEST = [mdl.pulse(task, 1) for task in WEST_vars if "qc" in task.name or "meca" in task.name]

        kitting_slots_EAST = [mdl.pulse(task, 1) for task in table_occupied_EAST]
        kitting_slots_EAST += [mdl.pulse(task, 1) for task in EAST_vars if "kitting" in task.name]
        kitting_slots_WEST = [mdl.pulse(task, 1) for task in table_occupied_WEST]
        kitting_slots_WEST += [mdl.pulse(task, 1) for task in WEST_vars if "kitting" in task.name]

        mdl.add(mdl.sum(meca_resources) <= 3)
        mdl.add(mdl.sum(qc_resources) <= 1)
        mdl.add(mdl.sum(work_slots_EAST) <= 2)
        mdl.add(mdl.sum(work_slots_WEST) <= 2)
        mdl.add(mdl.sum(kitting_slots_EAST) <= 3)
        mdl.add(mdl.sum(kitting_slots_WEST) <= 3)

        [mdl.add(mdl.start_of(task) % (14*6) < 11*6) for task in all_tasks if "meca" in task.name]

        MS1_meca_qc = [task for task in MS1_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(MS1_meca_qc))

        MS2_meca_qc = [task for task in MS2_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(MS2_meca_qc))

        MS3_meca_qc = [task for task in MS3_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(MS3_meca_qc))

        MS4_meca_qc = [task for task in MS4_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(MS4_meca_qc))

        FOV_meca_qc = [task for task in FOV_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(FOV_meca_qc))

        GTW_meca_qc = [task for task in GTW_vars if (("meca" in task.name) or ("qc" in task.name))]
        mdl.add(mdl.no_overlap(GTW_meca_qc))

        mdl.add(mdl.minimize(mdl.max([mdl.end_of(t) for t in all_tasks]) - mdl.min([mdl.start_of(t) for t in all_tasks])))

        return mdl
Exemple #13
0
    def init_model(self):
        # INPUTS --------------------------------------------------
        inst = self.instance
        id_profile = self.profile_idx
        rewards = self.l_j
        equivalences = self.on_same
        mutexes = self.on_diff
        # END INPUTS ----------------------------------------------

        # MODEL --------------------------------------------------
        types = list(inst.profiles[id_profile])
        types.insert(0, inst.INIT)
        types.append(inst.TERM)
        trans_time = [[0 for i in range(inst.V)] for j in range(inst.V)]
        for i in range(len(inst.edges)):
            for j in range(len(inst.edges[i])):
                trans_time[i][inst.edges[i][j]['to']] = inst.edges[i][j]['t']
        changeover_cost = inst.get_trans_cost(id_profile)

        cp = CpoModel()
        """
        primitives = [[] for i in range(inst.J)]
        all_primitives = []
        init = cp.interval_var(start=0)
        init.set_end_max(inst.L)
        total_cost = changeover_cost + inst.vertices[inst.INIT]['C'] * cp.length_of(init, 0) - self.l_0  # subtract l_0
        modes_of_mach = [init]  # serves only for retrieving starts and ends of modes
        last_shift = init
        for i in range(1, len(types) - 1):
            v = types[i]
            shift = cp.interval_var()
            shift.set_size_min(inst.vertices[v]['t_min'])
            shift.set_size_max(inst.vertices[v]['t_max'])
            shift.set_end_max(inst.L)
            total_cost += inst.vertices[v]['C'] * cp.length_of(shift, 0)
            cp.add(cp.start_at_end(shift, last_shift, -trans_time[types[i - 1]][types[i]]))
            last_shift = shift
            modes_of_mach.append(shift)
            for t in range(inst.J):
                if inst.tasks[t]['p'][v] <= inst.L:
                    prim = cp.interval_var(size=inst.tasks[t]['p'][v])
                    total_cost -= rewards[t] * cp.presence_of(prim)
                    prim.set_optional()
                    prim.set_start_min(inst.tasks[t]['r'])
                    prim.set_end_max(inst.tasks[t]['d'])
                    primitives[t].append(prim)
                    all_primitives.append(prim)
                    cp.add(cp.start_before_start(shift, prim))
                    cp.add(cp.end_before_end(prim, shift))
        term = cp.interval_var(end=inst.L)
        total_cost += inst.vertices[inst.TERM]['C'] * cp.length_of(term, 0)
        cp.add(cp.start_at_end(term, last_shift, -trans_time[types[len(types) - 2]][inst.TERM]))
        modes_of_mach.append(term)
        cp.add(cp.no_overlap(cp.sequence_var(all_primitives)))
        for t in range(inst.J):
            cp.add(sum([cp.presence_of(p) for p in primitives[t]]) <= 1)
        for eq in equivalences:
            cp.add(sum([cp.presence_of(p) for p in primitives[eq[0]]]) == sum(
                [cp.presence_of(p) for p in primitives[eq[1]]]))
        for mut in mutexes:
            cp.add(sum([cp.presence_of(p) for p in primitives[mut[0]]]) + sum(
                [cp.presence_of(p) for p in primitives[mut[1]]]) <= 1)
        """
        #"""
        # MODEL 2
        primitives = [[] for i in range(inst.J)]
        all_primitives = []
        init = cp.interval_var(start=0)
        init.set_end_max(inst.L)
        total_cost = changeover_cost + inst.vertices[
            inst.INIT]['C'] * cp.length_of(init, 0) - self.l_0
        modes_of_mach = [
            init
        ]  # serves only for retrieving starts and ends of modes
        last_shift = init
        for i in range(1, len(types) - 1):
            v = types[i]
            shift = cp.interval_var()
            shift.set_size_min(inst.vertices[v]['t_min'])
            shift.set_size_max(inst.vertices[v]['t_max'])
            shift.set_end_max(inst.L)
            total_cost += inst.vertices[v]['C'] * cp.length_of(shift, 0)
            cp.add(
                cp.start_at_end(shift, last_shift,
                                -trans_time[types[i - 1]][types[i]]))
            last_shift = shift
            modes_of_mach.append(shift)
            sub_tasks = []
            for t in range(inst.J):
                if inst.tasks[t]['p'][v] <= inst.L:
                    prim = cp.interval_var(size=inst.tasks[t]['p'][v])
                    total_cost -= rewards[t] * cp.presence_of(prim)
                    prim.set_optional()
                    prim.set_start_min(inst.tasks[t]['r'])
                    prim.set_end_max(inst.tasks[t]['d'])
                    primitives[t].append(prim)
                    sub_tasks.append(prim)
                    cp.add(cp.start_before_start(shift, prim))
                    cp.add(cp.end_before_end(prim, shift))
            if len(sub_tasks) > 1:
                cp.add(cp.no_overlap(cp.sequence_var(sub_tasks)))
        term = cp.interval_var(end=inst.L)
        total_cost += inst.vertices[inst.TERM]['C'] * cp.length_of(term, 0)
        cp.add(
            cp.start_at_end(term, last_shift,
                            -trans_time[types[len(types) - 2]][inst.TERM]))
        modes_of_mach.append(term)
        for t in range(inst.J):
            cp.add(sum([cp.presence_of(p) for p in primitives[t]]) <= 1)
        for eq in equivalences:
            cp.add(
                sum([cp.presence_of(p) for p in primitives[eq[0]]]) == sum(
                    [cp.presence_of(p) for p in primitives[eq[1]]]))
        for mut in mutexes:
            cp.add(
                sum([cp.presence_of(p) for p in primitives[mut[0]]]) +
                sum([cp.presence_of(p) for p in primitives[mut[1]]]) <= 1)
        #"""
        """
        # MOdel 3
        primitives = [[] for i in range(inst.J)]
        init = cp.interval_var(start=0)
        init.set_end_max(inst.L)
        total_cost = changeover_cost + inst.vertices[inst.INIT]['C'] * cp.length_of(init, 0) - self.l_0
        modes_of_mach = [init]  # serves only for retrieving starts and ends of modes
        last_shift = init
        for i in range(1, len(types) - 1):
            v = types[i]
            shift = cp.interval_var()
            shift.set_size_min(inst.vertices[v]['t_min'])
            shift.set_size_max(inst.vertices[v]['t_max'])
            shift.set_end_max(inst.L)
            total_cost += inst.vertices[v]['C'] * cp.length_of(shift, 0)
            cp.add(cp.start_at_end(shift, last_shift, -trans_time[types[i - 1]][types[i]]))
            last_shift = shift
            modes_of_mach.append(shift)
            for t in range(inst.J):
                if inst.tasks[t]['p'][v] <= inst.L:
                    prim = cp.interval_var(size=inst.tasks[t]['p'][v])
                    prim.set_optional()
                    prim.set_start_min(inst.tasks[t]['r'])
                    prim.set_end_max(inst.tasks[t]['d'])
                    primitives[t].append(prim)
                    cp.add(cp.start_before_start(shift, prim))
                    cp.add(cp.end_before_end(prim, shift))
        term = cp.interval_var(end=inst.L)
        total_cost += inst.vertices[inst.TERM]['C'] * cp.length_of(term, 0)
        cp.add(cp.start_at_end(term, last_shift, -trans_time[types[len(types) - 2]][inst.TERM]))
        modes_of_mach.append(term)
        masters = []
        for t in range(inst.J):
            new_master = cp.interval_var()
            new_master.set_optional()
            masters.append(new_master)
            total_cost -= rewards[t] * cp.presence_of(new_master)
            cp.add(cp.alternative(new_master, primitives[t]))
        cp.add(cp.no_overlap(cp.sequence_var(masters)))
        for eq in equivalences:
            cp.add(cp.presence_of(masters[eq[0]]) == cp.presence_of(masters[eq[1]]))
        for mut in mutexes:
            cp.add(cp.presence_of(masters[mut[0]]) + cp.presence_of(masters[mut[1]]) <= 1)
        """
        cp.add(cp.minimize(total_cost))

        # Set self.model
        self.model = cp
        self.primitives = primitives
        self.modes_of_mach = modes_of_mach
        self.types = types
Exemple #14
0
            for j in range(NB_JOBS)]

# Build list of durations. DURATION[j][s] = duration of the operation s of the job j
DURATION = [[JOBS[j][2 * s + 1] for s in range(NB_MACHINES)]
            for j in range(NB_JOBS)]

# -----------------------------------------------------------------------------
# Build the model
# -----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per job operation
job_operations = [[
    mdl.interval_var(size=DURATION[j][m], name="O{}-{}".format(j, m))
    for m in range(NB_MACHINES)
] for j in range(NB_JOBS)]

# Each operation must start after the end of the previous
for j in range(NB_JOBS):
    for s in range(1, NB_MACHINES):
        mdl.add(
            mdl.end_before_start(job_operations[j][s - 1],
                                 job_operations[j][s]))

# Force no overlap for operations executed on a same machine
machine_operations = [[] for m in range(NB_MACHINES)]
for j in range(NB_JOBS):
    for s in range(0, NB_MACHINES):
        machine_operations[MACHINES[j][s]].append(job_operations[j][s])
            model.end_before_start(on_intervals[m_id][i - 1],
                                   on_intervals[m_id][i], 1))

    # Bind with task intervals
    for on_i in on_intervals[m_id]:
        machine_on_off[m_id] += model.pulse(on_i, 1)
        model.add(
            model.always_constant(tasks_running_on_machines[m_id], on_i, True,
                                  True))

for task in data['tasks']:
    # Master task interval
    task_interval = model.interval_var(
        size=task['duration'],
        start=(task['earliest_start_time'],
               task['latest_end_time'] - task['duration']),
        end=(task['earliest_start_time'] + task['duration'],
             task['latest_end_time']),
        name='task_{}'.format(task['id']))
    # Optional task intervals that belong to each machine
    task_machine_intervals = model.interval_var_list(NUM_MACHINES,
                                                     name='task_{}_on_'.format(
                                                         task['id']),
                                                     optional=True)

    for i in range(NUM_MACHINES):
        m_id = data['machines'][i]['id']

        # Bind with machine switched on intervals
        model.add(
            model.always_equal(tasks_running_on_machines[m_id],
Exemple #16
0
def tw_schedule(time_slot, tasks):
    start_time = time_slot[0]
    end_time = time_slot[1]

    mdl = CpoModel(name="generate_tw")
    # Create model for CP and solve for the first time to obtain initial time windows
    # Decision variables: time interval of each task
    task_vars = {}
    early = lambda x: "task_" + str(x) + "_early"
    late = lambda x: "task_" + str(x) + "_late"
    for id in tasks:
        if tasks[id].exact_time != None:
            # print("exact time: {}".format(tasks[id].exact_time))
            task_vars[early(id)] = mdl.interval_var(start=tasks[id].exact_time,
                                                    size=tasks[id].duration,
                                                    name=early(id))
            task_vars[late(id)] = mdl.interval_var(start=tasks[id].exact_time,
                                                   size=tasks[id].duration,
                                                   name=late(id))
        else:
            task_vars[early(id)] = mdl.interval_var(size=tasks[id].duration,
                                                    name=early(id))
            task_vars[late(id)] = mdl.interval_var(size=tasks[id].duration,
                                                   name=late(id))
    slot = mdl.interval_var(start=start_time,
                            end=end_time)  # Time interval of entire time slot
    # Add Constraints:
    for id in tasks:
        # 1st constraint: all intervals are within start and end time
        mdl.add(mdl.start_before_start(slot, task_vars[early(id)]))
        mdl.add(mdl.end_before_end(task_vars[early(id)], slot))
        mdl.add(mdl.start_before_start(slot, task_vars[late(id)]))
        mdl.add(mdl.end_before_end(task_vars[late(id)], slot))
        # mdl.add(mdl.span(slot, task_vars.values()))

        if tasks[id].precedence_before != []:
            # Tasks that have precedence_before constraints
            # 2nd Constraints: end of precedence_before_task is before start of current task
            for id_before in tasks[id].precedence_before:
                mdl.add(
                    mdl.end_before_start(task_vars[early(id_before)],
                                         task_vars[early(id)]))
                mdl.add(
                    mdl.end_before_start(task_vars[late(id_before)],
                                         task_vars[late(id)]))

    # Add objective:
    obj = mdl.maximize(
        sum([
            mdl.start_of(task_vars[late(id)]) -
            mdl.start_of(task_vars[early(id)]) for id in tasks
        ]))
    mdl.add(obj)

    # Solve model
    # sol = mdl.solve(TimeLimit = 10, LogVerbosity = "Verbose")
    sol = mdl.solve(
        TimeLimit=10,
        LogVerbosity="Quiet",
        agent='local',
        execfile=
        '/Applications/CPLEX_Studio201/cpoptimizer/bin/x86-64_osx/cpoptimizer')
    # sol = mdl.solve()

    if sol:
        # sol.write()
        time_window = {
            id: (sol.get_var_solution(task_vars[early(id)]).get_start(),
                 sol.get_var_solution(task_vars[late(id)]).get_start())
            for id in tasks
        }
    else:
        print("Instance not feasible - earliest start time")
        return {}

    return time_window
Exemple #17
0
numdetails = 12
WorkerNames = ["worker1", "worker2", "worker3"]
TaskNames = ["obtain_parts", "repair", "delivery"]
# minutes_on_repair - число минут, которые тратит работник на починку девайса
minutes_on_repair = [140, 80, 160, 120, 160, 120, 130, 100, 40, 140, 160, 60]
# minutes_on_obtain_parts - число минут, которые тратит работник на поиск запчастей
minutes_on_obtain_parts = [20, 30, 40, 50, 100, 10, 20, 40, 100, 10, 50, 20]
# minutes_on_delivery - число минут, которое уходит на доставку can be done in parallel
minutes_on_delivery = [
    120, 150, 170, 100, 140, 100, 150, 230, 100, 90, 180, 280
]
# euro_penalty - число евро, составляющие штраф за откладку на день
euro_penalty = [100, 80, 120, 100, 80, 120, 120, 90, 100, 80, 150, 13]
mdl = CpoModel()
details = [
    mdl.interval_var(name="Detail{}".format(i + 1)) for i in range(numdetails)
]
TaskNames_ids = {}
itvs_1 = {}
itvs_2 = {}
itvs_3 = {}
itvs = {}
#zadadim treh
for d in range(numdetails):
    _name = "obtain_parts1_{}".format(d + 1)
    itvs_1[(d, 0)] = mdl.interval_var(size=minutes_on_obtain_parts[d],
                                      name=_name,
                                      optional=True)
for d in range(numdetails):
    _name = "repair1_{}".format(d + 1)
    itvs_1[(d, 1)] = mdl.interval_var(size=minutes_on_repair[d],
Exemple #18
0
        if (task_data["skill"] in skills_of_this_worker)
    ]
    for worker_id, skills_of_this_worker in workers_skills.items()
}

deadline = 1000  # in hours

# Create model
mdl = CpoModel(name="scheduling")

# tasks

tasks = {
    task_id: mdl.interval_var(
        name=f"{task_id}, {task_data['skill']}",
        size=task_data["duration"],
        end=(INTERVAL_MIN, deadline),
    )
    for task_id, task_data in tasks_data.items()
}

allocs = {}  # key: task id, value: list of worker-task assignment variables
worker_tasks = {}  # key: worker id, value: list of worker-task assignment variables


for worker_id, task_ids in workers_tasks_eligibility.items():
    for task_id in task_ids:
        wt = mdl.interval_var(name=f"{worker_id}, {task_id}", optional=True)
        worker_tasks[worker_id] = worker_tasks.get(worker_id, [])
        worker_tasks[worker_id].append(wt)
        allocs[task_id] = allocs.get(task_id, [])
def CP_model_subsequence_restricted(params):
##
    NUM_COLORS, NUM_ITEMS, BIN_SIZE, DISCREPANCY, ITEM_SIZES, COLORS, NUM_BINS, Timelimit, SEED = params


    print("*** Running CP Subseq Restricted with instance NUM_COLORS{} NUM_ITEMS{} BIN_SIZE {} DISCREPANCY {} SEED {}".format(
        NUM_COLORS, NUM_ITEMS, BIN_SIZE, DISCREPANCY, SEED))

    mdl = CpoModel()

    ITEMS = [mdl.interval_var(start=[0, sum(ITEM_SIZES)], size=ITEM_SIZES[item], optional=False, name="item_"+str(item)) for item in range(NUM_ITEMS)]
    ITEMS_TO_BINS = [[mdl.interval_var(start=(0, BIN_SIZE-min(ITEM_SIZES)), end=(min(ITEM_SIZES), BIN_SIZE), size=ITEM_SIZES[item], optional=True, name="item{}InBin{}".format(item, bin)) for bin in range(NUM_BINS)] for item in range(NUM_ITEMS)]

    ITEMS_S = mdl.sequence_var(ITEMS, types=COLORS, name="itemSequence")
    BIN_S = [mdl.sequence_var([ITEMS_TO_BINS[item][bin] for item in range(NUM_ITEMS)], types=[COLORS[item] for item in range(NUM_ITEMS)], name="bin{}Sequence".format(bin)) for bin in range(NUM_BINS)]

    # COLORS_S = [[mdl.sequence_var(ITEMS[item][bin] for item in range(NUM_ITEMS) if COLORS[item] == color)] for color in range(NUM_COLORS)]
    BINS_USED = [mdl.binary_var() for bin in range(NUM_BINS)]


    for item in range(NUM_ITEMS):
        # for bin in range(NUM_BINS):
        #     mdl.add_kpi(
        #         mdl.presence_of(ITEMS_TO_BINS[item][bin]),
        #         "item_"+str(item)+" "+str(bin)
        #     )
        mdl.add(
            mdl.sum(
                [mdl.presence_of(
                    ITEMS_TO_BINS[item][bin])
                    for bin in range(NUM_BINS)]
                ) == 1
        )

    # for item in range(NUM_ITEMS):
    #     mdl.add(
    #         mdl.alternative(ITEMS[item], [ITEMS_TO_BINS[item][bin] for bin in range(NUM_BINS)])
    #     )

    for bin in range(NUM_BINS):
        mdl.add(mdl.no_overlap(BIN_S[bin]))


    for item in range(NUM_ITEMS-1):
        mdl.add(
            mdl.end_before_start(ITEMS[item], ITEMS[item+1])
        )

    mdl.add(mdl.no_overlap(ITEMS_S))

    for bin in range(NUM_BINS):
        mdl.add(
            mdl.same_common_subsequence(
                ITEMS_S,
                BIN_S[bin],
            )
        )

    for item in range(NUM_ITEMS):
        for bin in range(NUM_BINS):
            # if (item, bin) in [(17,5), (20, 5), (29, 5)]:
            #     mdl.add_kpi(mdl.type_of_next(BIN_S[bin], ITEMS_TO_BINS[item][bin], lastValue=-1, absentValue=-1), name="typeofnext{}_{}".format(item, bin))
            #
            #     mdl.add_kpi(mdl.type_of_prev(BIN_S[bin], ITEMS_TO_BINS[item][bin], firstValue=-1, absentValue=-1), name="typeofprev{}_{}".format(item, bin))

            mdl.add(
                COLORS[item] != mdl.type_of_next(BIN_S[bin], ITEMS_TO_BINS[item][bin], lastValue=-1, absentValue=-1)
            )

            mdl.add(
                COLORS[item] != mdl.type_of_prev(BIN_S[bin], ITEMS_TO_BINS[item][bin], firstValue=-1, absentValue=-1)
            )

    for bin in range(NUM_BINS):
        mdl.add(
            BINS_USED[bin] ==  mdl.any([
                mdl.presence_of(ITEMS_TO_BINS[item][bin]) for item in range(NUM_ITEMS)
            ])
        )
    for bin in range(NUM_BINS-1):
        mdl.add(
            BINS_USED[bin] >= BINS_USED[bin+1]
        )

    mdl.add(
        mdl.minimize(
            mdl.sum(
                BINS_USED
            )
        )
    )

    # mdl.add(
    #         mdl.sum(
    #             BINS_USED
    #         ) < 48
    # )

    try:

        msol = mdl.solve(TimeLimit = Timelimit)
        mdl._myInstance = (NUM_COLORS, NUM_ITEMS, BIN_SIZE, DISCREPANCY, SEED)

        if msol:

            ITEMS_TO_BINS_S = []
            for bin in range(NUM_BINS):
                b_ = []
                for item in range(NUM_ITEMS):
                    s = msol[ITEMS_TO_BINS[item][bin]]
                    if s:
                        b_.append(s)
                ITEMS_TO_BINS_S.append(b_)
            # return mdl

            seq = msol.get_var_solution(BIN_S[0])

            print(ITEM_SIZES)
            print("CL: ",COLORS)

            Xs = []
            for item in range(NUM_ITEMS):
                for bin in range(NUM_BINS):
                    s = msol[ITEMS_TO_BINS[item][bin]]
                    if s:
                        # print(s)
                        Xs.append(bin)
            print("Xs: ", Xs)

            Xs = np.array(Xs)
            if solution_checker(Xs, params, "restricted_cp_subsequence"):
                write_to_global_cp(msol, mdl, 'restricted_subsequence')

    except Exception as err:
        print(err)
        write_to_global_failed(params, 'restricted_cp_subsequence', is_bad_solution=False)
Exemple #20
0
        if ind != -1:
            checked_cur = [ind_col[ind],i]
            checked.append(checked_cur)
            sum_col.pop(ind)
            ind_col.pop(ind)
        else:
            sum_col.append(pr)
            ind_col.append(i)
    print('found symmetries: ')
    print(checked)
    print('without symmetry: ')
    print(ind_col)
    return checked

#list of intervals
compositions=[mdl.interval_var(size=waittimes[i], end = [0,33], start=[0,33], name="song_"+str(i+1)) for i in range(numcompositions)]
domain=mdl.sequence_var([compositions[i] for i in range(numcompositions)], types=[t for t in range(numcompositions)], name="domain")
mdl.add(mdl.no_overlap(domain))
checked = checksymmetries(players_compositions, 9)

for i,c in enumerate(checked):
    if i ==2:
        mdl.add(mdl.start_before_start(compositions[c[1]],compositions[c[0]]))
    else:
        mdl.add(mdl.start_before_start(compositions[c[0]],compositions[c[1]]))
ENDS = []
STARTS = []
WAITNESS=[]
for k in range(numplayers):
    for j in range(numcompositions):
        print(players_compositions[k][j])
Exemple #21
0
                print("find interval from {} to {}".format(
                    cnst_pr[0], cnst_pr[1]))
                cnst_pr[0] = cnst_pr[1] = fdays * HOURS_IN_DAY + fhours
            elif fval == 0 and last_val == 1:
                cnst_pr[0] = cnst_pr[1] = fdays * HOURS_IN_DAY + fhours
            last_val = fval
    RND_CALENDAR.append(fs)

# -----------------------------------------------------------------------------
# Описание модели
# -----------------------------------------------------------------------------

mdl = CpoModel()
# задача в interval variables
tasks = [
    mdl.interval_var(name="T{}".format(i + 1), size=DURATIONS[i])
    for i in range(NB_TASKS)
]

# ОГРАНИЧЕНИЯ #
# Учтём приоритеты
for i in range(NB_RESOURCES):
    successors_tasks = []
    high_priority = []
    for k, j in enumerate(TASKS):
        if j["rnd"] == i and j["rank"] == 1:
            successors_tasks.append(k)
        if j["rnd"] == i and j["rank"] == 0:
            high_priority.append(k)

    for s in high_priority:
Exemple #22
0
    for j in range(NB_TYPES):
        if SETUP_M1[i][j] < 0:
            SETUP_M1[i][j] = INTERVAL_MAX;
        if SETUP_M2[i][j] < 0:
            SETUP_M2[i][j] = INTERVAL_MAX;


#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Build tasks for machine M1 and M2
tasks_m1 = [mdl.interval_var(name="A{}_M1_TP{}".format(i, TASK_TYPE[i]), optional=True, size=TASK_DUR_M1[i]) for i in range(NB_TASKS)]
tasks_m2 = [mdl.interval_var(name="A{}_M2_TP{}".format(i, TASK_TYPE[i]), optional=True, size=TASK_DUR_M1[i]) for i in range(NB_TASKS)]

# Build actual tasks as an alternative between machines
tasks = [mdl.interval_var(name="A{}_TP{}".format(i, TASK_TYPE[i])) for i in range(NB_TASKS)]
for i in range(NB_TASKS):
    mdl.add(mdl.alternative(tasks[i], [tasks_m1[i], tasks_m2[i]]))

# Build a map to retrieve task id from variable name (for display purpose)
task_id = dict()
for i in range(NB_TASKS):
    task_id[tasks_m1[i].get_name()] = i
    task_id[tasks_m2[i].get_name()] = i

# Constrain tasks to no overlap on each machine
s1 = mdl.sequence_var(tasks_m1, types=TASK_TYPE, name='M1')
def _create_cp_model(all_jobs, job_ids, job_num, all_machines, r_times,
                     d_times, p_intervals, assign):
    """ Prepare the index for decision variables """
    # typle of jobs, form (job_0, job_1, ...)
    jobs = tuple(job_ids)
    """ Parameters model (dictionary) """
    # 1. release time
    release_time = dict(zip(jobs, tuple(r_times)))
    # 2. due time
    due_time = dict(zip(jobs, tuple(d_times)))
    # 3. processing time
    process_time = dict(zip(jobs, tuple(p_intervals)))
    """ Creation of the CP model container """
    cp_model = CpoModel(name="CP-Model")
    """ Creation of variables """
    # for j_id in all_jobs:
    #     for m_id in all_machines:
    #         if assign[(j_id, m_id)].x == 1:
    #             print(assign[(j_id, m_id)])
    # 1. Variable subscript z_i represents machine selected to process job i
    z = {
        j_id: m_id
        for j_id in all_jobs for m_id in all_machines
        if assign[(j_id, m_id)].x == 1
    }
    # print("z: ", z)
    """ DOCPLEX """
    # 1. list of interval variable, is a list of start time of jobs (i.start in CP model)
    start_time_cp = [
        cp_model.interval_var(size=process_time[j_id][z[j_id]],
                              name="start-time-J{}".format(j_id))
        for j_id in all_jobs
    ]
    # if assign[(j_id, z[j_id])].x == 1]
    """ Create constraints """
    # 1. job release time constraint
    cp_model.add(start_of(start_time_cp[i]) >= release_time[i] for i in jobs)

    # 2. job due time constraint
    cp_model.add(
        start_of(start_time_cp[i]) <= due_time[i] - process_time[i][z[i]]
        for i in jobs)

    # 3. duration of processing one job constraint
    cp_model.add(
        size_of(start_time_cp[i]) == process_time[i][z[i]] for i in jobs)

    # 4. assignment of a job to a specific machine as well as sequence of jobs assigned to same machine
    # "requires" in OPL construct
    # job i requires unary resource corresponding to machine which was assigned from MILP
    # force no overlap for jobs
    # Constrain jobs to no overlap on each machine
    # Force no overlap for jobs executed on a same machine
    # disjunctive resource (unary resource): end(J1) <= start(J2) ||end(J2) <= start(J1)
    for job_id1 in range(job_num - 1):
        for job_id2 in range(job_id1 + 1, job_num):
            # print("job id1 & job id2", job_id1, job_id2)
            if z[job_id1] == z[job_id2]:
                cp_model.add(
                    cp_model.logical_or(
                        end_of(start_time_cp[job_id1]) <= start_of(
                            start_time_cp[job_id2]),
                        end_of(start_time_cp[job_id2]) <= start_of(
                            start_time_cp[job_id1])))

    return cp_model, start_time_cp
Exemple #24
0
    def initialize(self):
        model = CpoModel()
        self.model = model
        instance = self.instance
        T = len(instance.intervals)
        first_on = instance.earliest_on_interval_idx
        last_on = instance.latest_on_interval_idx
        init_start_times = self.get_init_start_times(sort_starts=True)
        ub = min(instance.get_ub(), self.get_upper_bound(init_start_times))
        total_proc = sum(j.processing_time for j in instance.jobs)

        # -------------------------------------- Construct the model.
        job_vars = dict()  # Dict[Job, CpoIntervalVar]
        self.job_vars = job_vars
        gap_vars = dict()  # Dict[Tuple[int, int], CpoIntervalVar]
        obj = 0  # objective value
        seq_vars = []  # variables for no-overlap constraint
        stp = model.create_empty_solution(
        )  # starting point of the solving procedure
        step_fns = CpGeneral.get_step_functions(
            instance, first_on,
            last_on)  # Generate seqment function for each processing time.

        first_job_var = model.interval_var(length=0,
                                           optional=False,
                                           name="first_job_var",
                                           start=1)
        seq_vars.append(
            first_job_var)  # dummy job with 0 length, first in the sequence
        last_job_var = model.interval_var(length=0,
                                          optional=False,
                                          name="last_job_var",
                                          end=T - 1)
        seq_vars.append(
            last_job_var)  # dummy job with 0 length, last in the sequence

        # variables for jobs -------------------------------------------------------------------------------------------
        for job in instance.jobs:
            var = model.interval_var(length=job.processing_time,
                                     optional=False,
                                     name="j[{:d}]".format(job.id))
            model.add(cpmod.start_of(var) >=
                      first_on)  # earliest possible start time is first_on
            model.add(cpmod.end_of(var) <=
                      last_on + 1)  # latest possible end time is last_on
            job_vars[job] = var
            seq_vars.append(var)

            if self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 0:  # Optional :
                alternatives = []
                for t in range(first_on, T):
                    if t <= last_on - (
                            job.processing_time - 1
                    ):  # (-1) because unit job can be processed in last_on
                        var = model.interval_var(start=t,
                                                 length=job.processing_time,
                                                 optional=True,
                                                 name="j[{:d},{:d}]".format(
                                                     t, job.id))
                        alternatives.append(var)
                        obj += cpmod.presence_of(
                            var) * instance.cumulative_energy_cost[t][
                                t + job.processing_time -
                                1] * instance.on_power_consumption

                # add a present variable for the job
                model.add(cpmod.alternative(job_vars[job], alternatives))
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 1:  # Logical :
                for t in range(T):
                    if first_on <= t <= last_on - (job.processing_time - 1):
                        obj += (cpmod.start_of(var, absentValue=-1)
                                == t) * instance.cumulative_energy_cost[t][
                                    t + job.processing_time -
                                    1] * instance.on_power_consumption
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 2:  # Element :
                energy = [
                    instance.cumulative_energy_cost[t][t +
                                                       job.processing_time -
                                                       1] *
                    instance.on_power_consumption if
                    (first_on <= t <= last_on -
                     (job.processing_time - 1)) else 0 for t in range(T)
                ]
                obj += cpmod.element(energy, cpmod.start_of(var))
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 3:  # Overlap :
                for t in range(T):  # add overlaps to objective
                    if first_on <= t <= last_on:
                        obj += cpmod.overlap_length(
                            var, (t, t + 1)) * instance.intervals[
                                t].energy_cost * instance.on_power_consumption
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 4:  # Step function :
                obj += cpmod.start_eval(var, step_fns[job.processing_time])
            else:
                raise Exception(
                    "Given JobInObjectiveModelling method {0} is not supported."
                    .format(
                        self.
                        specialized_solver_config["JobInObjectiveModelling"]))

        # add variables for gaps ---------------------------------------------------------------------------------------
        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 0:  # Fixed :
            for t_s in range(1, T):
                for t_e in range(t_s + 1, T):
                    if instance.has_switching_cost(t_s, t_e):
                        if instance.get_gap_lower_bound(
                                t_s,
                                t_e) > ub:  # skip gaps that are too costly
                            continue

                        sw_cost = instance.optimal_switching_costs[t_s][t_e]

                        var = model.interval_var(start=t_s,
                                                 end=t_e,
                                                 optional=True,
                                                 name="gap[{:d},{:d}]".format(
                                                     t_s, t_e))
                        gap_vars[t_s, t_e] = var

                        seq_vars.append(var)
                        obj += cpmod.presence_of(
                            var
                        ) * sw_cost  # if the gap is present, add cost to objective
        elif self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 1:  # Free :
            gaps_by_lengths = {i: [] for i in range(1, T - 1)}
            for gap_len in range(1, T - total_proc - 1):
                costs = [
                    instance.optimal_switching_costs[t][t + gap_len]
                    if instance.optimal_switching_costs[t][t + gap_len]
                    is not None else
                    len(instance.intervals) * instance.on_power_consumption +
                    1  # TODO : max value
                    for t in range(T) if t + gap_len < T
                ]
                costs[0] = 0  # TODO: for absent value

                for i in range(int(T / gap_len)):
                    var = model.interval_var(optional=True,
                                             length=gap_len,
                                             name="gap[{:d},{:d}]".format(
                                                 gap_len, i))
                    model.add(cpmod.start_of(var, absentValue=1) >= 1)
                    model.add(cpmod.end_of(var) <= T - 1)
                    obj += cpmod.element(costs, cpmod.start_of(var))
                    gaps_by_lengths[gap_len].append(var)

                    seq_vars.append(var)

                # force order on the gaps
                for cur, nxt in zip(gaps_by_lengths[gap_len],
                                    gaps_by_lengths[gap_len][1:]):
                    model.add(cpmod.presence_of(cur) >= cpmod.presence_of(nxt))
                    model.add(cpmod.end_before_start(cur, nxt))
        elif self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 2:  # No :
            # Gaps will be added to the objective after introducing the sequence variable
            pass
        else:
            raise Exception(
                "Given GapsInObjectiveModelling method {0} is not supported.".
                format(self.
                       specialized_solver_config["GapsInObjectiveModelling"]))

        # add no overlap constraint ------------------------------------------------------------------------------------
        seq = model.sequence_var(seq_vars, name="seq")
        model.add(cpmod.no_overlap(seq))

        model.add(cpmod.first(seq, first_job_var))
        model.add(cpmod.last(seq, last_job_var))

        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 2:  # No :
            gap_costs = (
                [0 for _ in range(T)] +  # gap_len == 0
                [
                    instance.optimal_switching_costs[gap_s][gap_s + gap_len]
                    if gap_s + gap_len <= T - 1 and
                    instance.optimal_switching_costs[gap_s][gap_s + gap_len]
                    is not None else INT_MAX for gap_len in range(1, T)
                    for gap_s in range(T)
                ])

            for job in instance.jobs:
                job_var = self.job_vars[job]
                obj += cpmod.element(
                    gap_costs,
                    (cpmod.start_of_next(seq, job_var, T - 1) -
                     cpmod.end_of(job_var)) * T + cpmod.end_of(job_var))
            obj += cpmod.element(gap_costs,
                                 cpmod.start_of_next(seq, first_job_var) * T)

        # constrain lengths to fill the whole horizon ------------------------------------------------------------------
        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] != 2:  # gaps are modelled
            if self.specialized_solver_config[
                    "FillAllModelling"] == 0:  # SumLengths :
                model.add(
                    sum([cpmod.length_of(var) for var in seq_vars]) == T - 2)
            elif self.specialized_solver_config[
                    "FillAllModelling"] == 1:  # Pulse :
                cumul_func = 0
                for var in seq_vars:
                    if var is not first_job_var and var is not last_job_var:
                        cumul_func += cpmod.pulse(var, 1)
                model.add(cpmod.always_in(cumul_func, (1, T - 1), 1, 1))
            elif self.specialized_solver_config[
                    "FillAllModelling"] == 2:  # StartOfNext :
                for var in seq_vars:
                    if var is not last_job_var:
                        model.add(
                            cpmod.start_of_next(
                                seq, var, lastValue=T, absentValue=0) ==
                            cpmod.end_of(var, absentValue=0))
            else:
                raise Exception(
                    "Given FillAllModelling method {0} is not supported.".
                    format(self.specialized_solver_config["FillAllModelling"]))

        # set objective
        model.minimize(obj)

        # - init start times.
        # if init_start_times is not None:
        #     for job in instance.jobs:
        #         stp.add_interval_var_solution(job_vars[job], presence=True, start=init_start_times[job])
        #
        #     # gaps in the schedule
        #     gaps = self.get_gaps_in_schedule(init_start_times)
        #
        #     for g_s, g_e in gaps:
        #         stp.add_interval_var_solution(gap_vars[g_s, g_e], presence=True, start=g_s)
        #
        #     # set starting point
        #     model.set_starting_point(stp)

        # force ordering of the jobs
        jobs_by_lengths = self.get_job_by_lengths()
        for lst in jobs_by_lengths.values():
            for j_cur, j_nxt in zip(lst, lst[1:]):
                model.add(
                    cpmod.end_before_start(job_vars[j_cur], job_vars[j_nxt]))
Exemple #25
0
Skills = [[("M"+str(JOBS[j][2 * s]),s) for s in range(NB_MACHINES)] for j in range(NB_JOBS)  ]
#append abilities of additional 5 machines
for j in range(NB_JOBS):
    for i in range(len(Skills[j])):
        if int(Skills[j][i][0][-1:]) < IDENTICAL_MACHINES_NUM+1:
            for f in range(flag-1):
                add_s = ('M' + str(int(Skills[j][i][0][-1:]))+'e'+str(f+1), Skills[j][i][1])
                Skills[j].append(add_s)
Precedences = [(i, i+1) for i in range(NB_MACHINES-1)]

tasks = {}
mtasks = {}
for j in range(NB_JOBS):
    for i,t in enumerate(Tasks[j]):
#        print((j,JOBS[j][2 * t],t),JOBS[j][2 * Tasks[j][-1] ])
        tasks[(j,JOBS[j][2 * t],t)] = mdl.interval_var(size = Durations[j][i], name="J{}-M{}".format(j, JOBS[j][2 * t]))
#    print("SKILLS")
    for s in Skills[j]:
#        print((j,s),"J{}-{}".format(j, s))
        mtasks[(j,s)] = mdl.interval_var(optional=True, name=str(j))#"J{}-{}".format(j, s)

for j in range(NB_JOBS):
#    print(j)
    for p in Precedences:
#        print((j,JOBS[j][2 * p[0]]),(j,JOBS[j][2 * p[1]]))
        mdl.add( mdl.end_before_start(tasks[j,JOBS[j][2 * p[0]],p[0]], tasks[j,JOBS[j][2 * p[1]],p[1]]) )
#for j in range(NB_JOBS):
#    for t in Tasks[j]:
#        print( (j,JOBS[j][2 * t]), [(j,s) for s in Skills[j] if s[0][:len('M'+str(JOBS[j][2 * t])) ] == 'M'+str(JOBS[j][2 * t]) and s[0][len('M'+str(JOBS[j][2 * t])): len('M'+str(JOBS[j][2 * t]))+1] in 'e'] )

for j in range(NB_JOBS):
Exemple #26
0
expressed through precedence constraints.

Please refer to documentation for appropriate setup of solving configuration.
"""

from docplex.cp.model import CpoModel
import docplex.cp.utils_visu as visu

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

masonry = mdl.interval_var(name='masonry', size=35)
carpentry = mdl.interval_var(name='carpentry', size=15)
plumbing = mdl.interval_var(name='plumbing', size=40)
ceiling = mdl.interval_var(name='ceiling', size=15)
roofing = mdl.interval_var(name='roofing', size=5)
painting = mdl.interval_var(name='painting', size=10)
windows = mdl.interval_var(name='windows', size=5)
facade = mdl.interval_var(name='facade', size=10)
garden = mdl.interval_var(name='garden', size=5)
moving = mdl.interval_var(name='moving', size=5)

# Add precedence constraints
mdl.add(mdl.end_before_start(masonry, carpentry))
mdl.add(mdl.end_before_start(masonry, plumbing))
mdl.add(mdl.end_before_start(masonry, ceiling))
mdl.add(mdl.end_before_start(carpentry, roofing))
# Task type
TASK_TYPE = [
    8, 1, 6, 3, 4, 8, 8, 4, 3, 5, 9, 4, 1, 5, 8, 8, 4, 1, 9, 2, 6, 0, 8, 9, 1,
    0, 1, 7, 5, 9, 3, 1, 9, 3, 0, 7, 0, 7, 1, 4, 5, 7, 4, 0, 9, 1, 5, 4, 5, 1
]

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Build tasks for machine M1 and M2
tasks_m1 = [
    mdl.interval_var(name="A{}_M1_TP{}".format(i, TASK_TYPE[i]), optional=True)
    for i in range(NB_TASKS)
]
tasks_m2 = [
    mdl.interval_var(name="A{}_M2_TP{}".format(i, TASK_TYPE[i]), optional=True)
    for i in range(NB_TASKS)
]

# Build actual tasks as an alternative between machines
tasks = [
    mdl.interval_var(name="A{}_TP{}".format(i, TASK_TYPE[i]),
                     size=TASK_DURATION[i]) for i in range(NB_TASKS)
]
for i in range(NB_TASKS):
    mdl.add(mdl.alternative(tasks[i], [tasks_m1[i], tasks_m2[i]]))
Exemple #28
0
MODES = []
for t in TASKS:
   for i, m in enumerate(t['modes']):
       m['id'] = "T{}-M{}".format(t['id'], i + 1)
       MODES.append(m)


#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per task
tasks = {t['id']: mdl.interval_var(name="T{}".format(t['id'])) for t in TASKS}

# Add precedence constraints
for t in TASKS:
    for s in t['successors']:
        mdl.add(mdl.end_before_start(tasks[t['id']], tasks[s]))

# Create one optional interval variable per task mode and add alternatives for tasks
modes = {}  # Map of all modes
for t in TASKS:
    tmds = [mdl.interval_var(name=m['id'], optional=True, size=m['duration']) for m in t['modes']]
    mdl.add(mdl.alternative(tasks[t['id']], tmds))
    for m in tmds:
        modes[m.name] = m

# Initialize pulse functions for renewable and non renewable resources
Exemple #29
0
for i in range(len(PRODUCT_WEIGHT)):
    p = []
    for j in range(SIZE_SHELF["x"] * SHELF_COUNT):
        p.append(E[int(j / SIZE_SHELF["x"])] * PRODUCT_WEIGHT[i])
    SHELVES_PRODUCT_MATRIX.append(p)

# -----------------------------------------------------------------------------
# Описание модели
# -----------------------------------------------------------------------------
mdl = CpoModel()

# Создадим массивы продуктов по сторонам
vx = [
    mdl.interval_var(size=WEIGHT_SIZE_A[i],
                     name="X" + str(i),
                     end=(0, SIZE_SHELF["x"] * SHELF_COUNT))
    for i in range(NB_WEIGHTS)
]
vy = [
    mdl.interval_var(size=WEIGHT_SIZE_B[i],
                     name="Y" + str(i),
                     end=(0, SIZE_SHELF["y"] * 1)) for i in range(NB_WEIGHTS)
]

# Запретим пересекать границы полок и учтём температуры
for i in range(NB_WEIGHTS):
    mdl.add(
        mdl.forbid_extent(vx[i], get_allowable_area(SHELVES, 'x',
                                                    PRODUCT_T[i])))