# Phase 1
#
# Cost of tasks is calculated here without concerning ourselves
# about the machine costs.

task_intervals_on_machines = {m['id']: [] for m in data['machines']}
task_intervals = []

for machine in data['machines']:
    m_id = machine['id']

    # Sequencing of intervals
    num_intervals = len(on_intervals[m_id])
    for i in range(1, num_intervals):
        model.add(
            model.if_then(model.presence_of(on_intervals[m_id][i]),
                          model.presence_of(on_intervals[m_id][i - 1])))
        model.add(
            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'],
def CP_model_restricted(params):
    ##
    NUM_COLORS, NUM_ITEMS, BIN_SIZE, DISCREPANCY, ITEM_SIZES, COLORS, NUM_BINS, Timelimit, SEED = params
    mdl = CpoModel()

    X = [mdl.integer_var(min=0, max=NUM_BINS) for item in range(NUM_ITEMS)]

    CP = mdl.integer_var_list(NUM_BINS, min=0, max=BIN_SIZE)

    for bin in range(NUM_BINS - 1):
        mdl.add(CP[bin] >= CP[bin + 1])

    mdl.add(pack(CP, [X[item] for item in range(NUM_ITEMS)], ITEM_SIZES))

    CC = [
        mdl.integer_var_list(NUM_COLORS, min=0, max=BIN_SIZE)
        for bin in range(NUM_BINS)
    ]

    for color in range(NUM_COLORS):
        mdl.add(
            distribute([CC[bin][color] for bin in range(NUM_BINS)], [
                X[item] for item in range(NUM_ITEMS) if COLORS[item] == color
            ], [bin for bin in range(NUM_BINS)]))

    for bin in range(NUM_BINS):

        TC = mdl.sum(CC[bin])
        MC = mdl.max(CC[bin])
        # mdl.add_kpi(TC, name="TC_{}".format(bin))
        # mdl.add_kpi(MC, name="MC_{}".format(bin))

        # mdl.add(
        #     (TC+mdl.mod(TC, 2))/2  >= MC
        #
        # )
        # mdl.add(
        #     (TC - mdl.mod(TC, NUM_COLORS))/NUM_COLORS >= MC
        # )

        # mdl.add(
        #     mdl.sum(
        #         CC[bin][color] > 0 for color in range(NUM_COLORS)
        #     ) <= MAX_COLORS_IN_BIN
        # )

    for item in range(NUM_ITEMS):
        for item2 in range(item + 1, NUM_ITEMS):
            if COLORS[item] == COLORS[item2]:
                mdl.add(
                    mdl.if_then(
                        X[item] == X[item2],
                        mdl.any([
                            X[i] == X[item]
                            for i in range(item + 1, item2 + 1)
                            if COLORS[i] != COLORS[item]
                        ])
                        # mdl.count([mdl.element(COLORS, i) for i in range(item, item2+1)], abs(COLORS[item] -1)) > 0
                    ))

    # mdl.add(
    #     mdl.minimize(count_different(X))
    # )

    # bins_used = mdl.sum(CP[bin] > 0 for bin in range(NUM_BINS))
    # mdl.add(
    #     mdl.minimize(
    #         bins_used
    #     )
    # )

    mdl.add(mdl.minimize(mdl.max(X) + 1))

    try:
        msol = mdl.solve(TimeLimit=20)
        mdl._myInstance = (NUM_COLORS, NUM_ITEMS, BIN_SIZE, DISCREPANCY, SEED)
        #
        # print(ITEM_SIZES)
        # print(COLORS)
        #

        # print([msol[X[item]] for item in range(NUM_ITEMS)])

        Xs = np.array([msol[X[i]] for i in range(NUM_ITEMS)])
        if solution_checker(Xs, COLORS, ITEM_SIZES, BIN_SIZE, SEED,
                            'restricted_cp_binary'):
            write_to_global_cp(msol, mdl, 'restricted_binary')

    except Exception as err:
        print(err)
        write_to_global_failed(NUM_COLORS,
                               NUM_ITEMS,
                               BIN_SIZE,
                               DISCREPANCY,
                               SEED,
                               'restricted_cp_binary',
                               is_bad_solution=False)
示例#3
0
visit must be done, among all days of the scheduling horizon.

sum over l (x_{k,i,j}^{l} + y_{k,i,j}^{l} <= 1) ; \forall (k, i, j)

(2) If a patient is admitted, all his/her visit sessions must be done.
Hence, only if z_i == 1 the constraint above must hold
It's possible to manually force an admittance to happen, if it has waited
long enough, just by setting z_i=1 for patient i.
'''
for pat in patient_list:  # i
    for doc in pat.visit_vars_dict:  # k
        nb_doc_sessions = len(pat.visit_vars_dict[doc])  # j
        for j in range(nb_doc_sessions):
            cons = mdl.if_then(
                pat.is_admitted_var == 1,
                mdl.sum(pat.visit_vars_dict[doc][j].x_vars[l] +
                        pat.visit_vars_dict[doc][j].y_vars[l]
                        for l in range(pat.nb_visit_days)) == 1)
            # print(cons)
            mdl.add(cons)
'''
CONSTRAINT:
For the same patient and doctor, at least some visit sessions must happen
in the morning. This is because children become tired in the afternoon, and 
harder to work with, which makes it more difficult for the doctor to conduct
diagnosis. Hence each doctor wants to do at least some visits of the same
patient in the morning.

sum_sum_j_l( y_{k,i,j}^{l}) <= sum_sum_j_l(x_{k,i,j}^{l}) + 1 ; \forall (k, i)
'''
for pat in patient_list:  # i
    tvar = toIndex[m]
    fromState = states[m]
    toState = states[m + 1]
    # Constrain location of holes
    mdl.add(mdl.element(fromState, tvar) == HOLE)
    # Constrain move size and direction
    delta = tvar - fvar
    mdl.add(mdl.allowed_assignments(delta, [-2, -1, 1, 2]))
    peg = mdl.element(fromState, fvar)
    mdl.add( ((peg == RED) & (delta > 0)) | ((peg == BLUE) & (delta < 0)) )
    # Make moves
    mdl.add(mdl.element(toState, tvar) == mdl.element(fromState, fvar))
    mdl.add(mdl.element(toState, fvar) == HOLE)
    # Force equality of other positions
    for p in range(SIZE):
        mdl.add(mdl.if_then((p != fvar) & (p != tvar), fromState[p] == toState[p]))

# Set initial position
for p in range(NB_PEGS):
    mdl.add(states[0][p] == RED)
    mdl.add(states[0][p + NB_PEGS + 1] == BLUE)
mdl.add(states[0][NB_PEGS] == HOLE)

# Force last state to be final
expr = states[NB_MOVES][NB_PEGS] == HOLE
for p in range(NB_PEGS):
    expr &= states[NB_MOVES][p] == BLUE
    expr &= states[NB_MOVES][p + NB_PEGS + 1] == RED
mdl.add(expr)

示例#5
0
            Result.append(mass[i_use2][j])
    return Result
def get_or_on_neigh(neigh):
    if len(neigh) == 2:
        return (mdl.equal(neigh[0],0) | mdl.equal(neigh[1],0))
    elif len(neigh) == 3:
        return (mdl.equal(neigh[0],0) | mdl.equal(neigh[1],0) | mdl.equal(neigh[2],0))
    elif len(neigh) == 4:
        return (mdl.equal(neigh[0],0) | mdl.equal(neigh[1],0) | mdl.equal(neigh[2],0) | mdl.equal(neigh[3],0))
    else:
       raise IndexError('Что-то пошло не так') 
        
for i in range(SIZE_X):
    for j in range(SIZE_Y):
        neigh = get_neigh(mass_v,  i, j)
        expr = mdl.if_then(mdl.equal(mass_v[i][j],1), get_or_on_neigh(neigh))
        mdl.add(expr)
        
def get_neighbours_with_checked(mass, i, j, checked):
    Y_SIZE = len(mass[0])
    X_SIZE = len(mass)
    Result = []
    i_use1 = i + 1
    j_use1 = j + 1
    i_use2 = i - 1
    j_use2 = j - 1
    if i - 1 < 0:
        i_use2 = i + 1  
    if i + 1 >= X_SIZE:
        i_use1 = i - 1 
    if j + 1 >= Y_SIZE: