Beispiel #1
0
    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
    for p in TASK_PRECEDENCES:
        mdl.add(
            mdl.end_before_start(tasks[(h, find_tasks(p.beforeTask))],
                                 tasks[(h, find_tasks(p.afterTask))]))
    # Alternative workers
    for t in TASKS:
        mdl.add(
            mdl.alternative(
                tasks[(h, t)],
                [wtasks[(h, s)] for s in SKILLS if (s.task == t.name)], 1))
    # Continuity constraints
    for c in CONTINUITIES:
        mdl.add(
            mdl.presence_of(wtasks[(h, find_skills(c.worker, c.task1))]) ==
            mdl.presence_of(wtasks[(h, find_skills(c.worker, c.task2))]))

# No overlap constraint
for w in WORKERS:
    mdl.add(
        mdl.no_overlap(
            [wtasks[(h, s)] for h in HOUSES for s in SKILLS if s.worker == w]))

#-----------------------------------------------------------------------------
# Solve the model and display the result
Beispiel #2
0
# 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
renewables = [mdl.pulse((0, 0), 0) for j in range(NB_RENEWABLE)]
non_renewables = [0 for j in range(NB_NON_RENEWABLE)]
for m in MODES:
    dren = m['demandRenewable']
    dnren = m['demandNonRenewable']
    for j in range(NB_RENEWABLE):
        dem = m['demandRenewable'][j]
        if dem > 0:
            renewables[j] += mdl.pulse(modes[m['id']], dem)
    for j in range(NB_NON_RENEWABLE):
        dem = m['demandNonRenewable'][j]
                               task_machine_intervals[i], 1))
        model.add(
            model.always_in(machine_on_off[m_id], task_machine_intervals[i], 1,
                            1))

        # Add resource usage by task
        for j in range(NUM_RESOURCES):
            machine_resources[m_id][j] += model.pulse(
                task_machine_intervals[i], task['resource_usage'][j])

        # For visualization
        task_intervals_on_machines[m_id].append(
            (task, task_machine_intervals[i]))

    # Only one interval will be effective
    model.add(model.alternative(task_interval, task_machine_intervals))

    task_intervals.append((task, task_interval))

# Add power consumption by tasks
cost_tasks = model.sum([
    model.start_eval(task_int, energy_intervals_array[task['duration'] - 1]) *
    task['power_consumption'] for task, task_int in task_intervals
])

# Add resource capacity constraints
for machine in data['machines']:
    m_id = machine['id']
    for j in range(NUM_RESOURCES):
        model.add(
            machine_resources[m_id][j] <= machine['resource_capacities'][j])
Beispiel #4
0
# посмотрим, что создали
# 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)]

# одна задача - один монтажник
for i in range(ORDERS_COUNT):
    a_t = WAIT_ORDERS[i][1]
    kk = [tasks[p][k] for p in range(WORKERS_COUNT) for k in range(len(tasks[p])) if (tasks[p][k].get_name() == a_t)]
    if len(kk) != 0:
        mdl.add(mdl.alternative(tasks_act[i], kk, 1))

# в один момент времени - одна задача
for i in range(WORKERS_COUNT):
    mdl.add(mdl.no_overlap(tasks[i]))

# все задачи должны быть выполнены
for i in range(ORDERS_COUNT):
    a_t = TASK_TEMPLATE_NAME.format(num=str(i), name=WAIT_ORDERS[i][1])
    mdl.add(mdl.sum([mdl.presence_of(t) for k in tasks for t in k if t.get_name() == a_t]) > 0)

# OF
mdl.add(
    mdl.minimize(mdl.max([mdl.end_of(t) * mdl.presence_of(t) for i, tp in enumerate(tasks) for j, t in enumerate(tp)]))
)
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]]))

# 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')
s2 = mdl.sequence_var(tasks_m2, types=TASK_TYPE, name='M2')
mdl.add(mdl.no_overlap(s1, SETUP_M1, 1))
mdl.add(mdl.no_overlap(s2, SETUP_M2, 1))

# Minimize the number of "long" setup times on machines.
nbLongSetups = 0
Beispiel #6
0
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):
    for t in Tasks[j]:
        mdl.add( 
                mdl.alternative(
                        tasks[j,JOBS[j][2 * t],t], 
                        [mtasks[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 m in Maschines:
#    print([(j,s) for j in range(NB_JOBS) for s in Skills[j] if s[0]==m])
    mdl.add( mdl.no_overlap([mtasks[j,s] for j in range(NB_JOBS) for s in Skills[j] if s[0]==m]) )

# Minimize termination date
mdl.add(mdl.minimize(mdl.max([mdl.end_of(tasks[i,JOBS[i][2 * Tasks[i][-1] ],NB_MACHINES - 1]) for i in range(NB_JOBS)])))

#-----------------------------------------------------------------------------
# Solve the model and display the result
#-----------------------------------------------------------------------------
# Solve model
#print("Solving model....")
Beispiel #7
0
#zadadim obshie
for d in range(numdetails):
    _name = "obtain_parts{}".format(d + 1)
    itvs[(d, 0)] = mdl.interval_var(size=minutes_on_obtain_parts[d],
                                    name=_name)
for d in range(numdetails):
    _name = "repair{}".format(d + 1)
    itvs[(d, 1)] = mdl.interval_var(size=minutes_on_repair[d], name=_name)
for d in range(numdetails):
    _name = "delivery{}".format(d + 1)
    itvs[(d, 2)] = mdl.interval_var(size=minutes_on_delivery[d], name=_name)
#альтернатива между работниками
for i in range(numdetails):
    for j in range(2):
        mdl.add(
            mdl.alternative(itvs[(i, j)],
                            [itvs_3[(i, j)], itvs_2[(i, j)], itvs_1[(i, j)]]))
#навесим последовательность TO DO для 1,2,3
#for h in range(numdetails):
#        mdl.add(mdl.end_before_start(itvs[(h, 1)], itvs[(h, 2)]))
#for h in range(numdetails):
#        mdl.add(mdl.end_before_start(itvs[(h, 0)], itvs[(h, 1)]))
#навесим последовательность жестко
for h in range(numdetails):
    mdl.add(mdl.end_before_start(itvs[(h, 1)], itvs[(h, 2)]))
for h in range(numdetails):
    mdl.add(mdl.end_before_start(itvs[(h, 0)], itvs[(h, 1)]))
for h in range(numdetails):
    mdl.add(mdl.start_at_end(itvs[(h, 1)], itvs[(h, 0)]))
#навесим принадлежность
for h in range(numdetails):
    mdl.add(mdl.span(details[h], [itvs[(h, t)] for t in range(3)]))
Beispiel #8
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
Beispiel #9
0
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]))

# Initialize pulse functions for renewable and non renewable resources
renewables = [mdl.pulse((0, 0), 0) for j in range(NB_RENEWABLE)]
non_renewables = [0 for j in range(NB_NON_RENEWABLE)]
for m in modes_data:
    for j in range(NB_RENEWABLE):
        if m.demand_renewable[j] > 0:
            renewables[j] += mdl.pulse(modes[m], m.demand_renewable[j])
    for j in range(NB_NON_RENEWABLE):
        if m.demand_non_renewable[j] > 0:
            non_renewables[j] += m.demand_non_renewable[j] * mdl.presence_of(
                modes[m])

# Constrain renewable resources capacity
for j in range(NB_RENEWABLE):