Beispiel #1
0
    def solve(self):
        mdl = CpoModel()

        power = [2**i for i in range(0, self.U + 1)]
        M = mdl.integer_var_list(self.n + 1, 0, self.U, "M")
        T = mdl.integer_var_list(self.n + 1, 0, power[self.U], "T")

        mdl.add(mdl.element(power, M[i]) == T[i] for i in range(0, self.n + 1))
        mdl.add(T[i] >= T[0] for i in range(0, self.n + 1))

        mdl.minimize(
            mdl.sum(self.H[i] * T[i] / self.beta + self.K[i] /
                    (T[i] / self.beta) for i in range(0, self.n + 1)))

        # Solve model
        print("Solving model....")
        msol = mdl.solve(
            TimeLimit=10,
            agent='local',
            execfile=
            '/Applications/CPLEX_Studio1210/cpoptimizer/bin/x86-64_osx/cpoptimizer'
        )

        # Print solution
        if msol:
            stdout.write("Total cost : " +
                         str(msol.get_objective_values()[0]) + "\n")
            stdout.write("T: [")
            for t in T:
                stdout.write(" {}".format(msol[t]))
            stdout.write("]\n")
            stdout.write("M: [")
            for m in M:
                stdout.write(" {}".format(msol[m]))
            stdout.write("]\n")
            return msol.get_objective_values()[0]
        else:
            stdout.write("Solve status: {}\n".format(msol.get_solve_status()))
            return None
Beispiel #2
0
def solve_seer_ilp(companies,
                   facilities,
                   customers,
                   facilityDemands,
                   costs,
                   alpha=1,
                   log_verbose='Quiet'):
    assert alpha >= 0  # ensure trace-off factor is >= 0, which show the contribution of representative cost
    assert log_verbose in ['Quiet', 'Terse', 'Normal', 'Verbose']
    n_company = len(companies)
    n_facility = len(facilities)
    n_customer = len(customers)
    n_type = len(facilityDemands)

    mdl = CpoModel()

    customerSupplier = mdl.integer_var_list(n_customer, 0, n_facility - 1,
                                            'customerSupplier')
    openFacility = mdl.integer_var_list(n_facility, 0, 1, 'openFacility')
    facilityType = mdl.integer_var_list(n_facility, 0, n_type, 'facilityType')
    customerType = mdl.integer_var_list(n_customer, 0, n_type - 1,
                                        'customerType')
    openCompany = mdl.integer_var_list(n_company, 0, 1, 'openCompany')
    company2id = {companies[i].name: i for i in range(n_company)}
    type2id = {facilityDemands[i].type: i for i in range(n_type)}
    facilityCompany = [
        company2id[facilities[i].company] for i in range(n_facility)
    ]

    validFacilityType = np.zeros((n_facility, n_type + 1))
    validFacilityType[:, n_type] = 1
    for i in range(n_facility):
        validFacilityType[i, type2id[facilities[i].type]] = 1

    for i in range(n_customer):
        mdl.add(mdl.element(openFacility, customerSupplier[i]) == 1)
        mdl.add(
            mdl.element(customerType, i) == mdl.element(
                facilityType, customerSupplier[i]))
        mdl.add(
            mdl.element(mdl.element(customerType, i), validFacilityType[i]) ==
            1)

    for i in range(n_facility):
        mdl.add(
            mdl.element(mdl.element(facilityType, i), validFacilityType[i]) ==
            1)
        mdl.add(
            mdl.element(openFacility, i) <= mdl.element(
                openCompany, facilityCompany[i]))
        mdl.add((mdl.element(openFacility, i) == 1) == (
            mdl.element(facilityType, i) < n_type))

    for i in range(n_type):
        mdl.add(mdl.count(facilityType, i) == facilityDemands[i].demand)

    # Objective
    total_cost = mdl.scal_prod(openCompany, [c.cost for c in companies])
    for i in range(n_customer):
        total_cost += mdl.element(customerSupplier[i], alpha * costs[i])
    mdl.add(mdl.minimize(total_cost))

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

    # Solve model
    msol = mdl.solve(TimeLimit=TIME_LIMIT, LogVerbosity=log_verbose)

    selectedFacilities = []
    selectedCompanies = []
    if msol:
        for i in range(n_facility):
            if msol[facilityType[i]] < n_type:
                selectedFacilities.append(i)
                if facilityCompany[i] not in selectedCompanies:
                    selectedCompanies.append(facilityCompany[i])
    return msol, selectedFacilities, selectedCompanies
Beispiel #3
0
load = [
    mdl.integer_var(0, capacity[p], "PlantLoad_" + str(p))
    for p in range(nbLocation)
]

# Associate plant openness to its load
for p in range(nbLocation):
    mdl.add(open[p] == (load[p] > 0))

# Add constraints
mdl.add(mdl.pack(load, cust, demand))

# Add objective
obj = mdl.scal_prod(fixedCost, open)
for c in range(nbCustomer):
    obj += mdl.element(cust[c], cost[c])
mdl.add(mdl.minimize(obj))

#-----------------------------------------------------------------------------
# Solve the model, tracking objective with a callback
#-----------------------------------------------------------------------------


class MyCallback(CpoCallback):
    def invoke(self, solver, event, jsol):
        # Get important elements
        obj_val = jsol.get_objective_values()
        obj_bnds = jsol.get_objective_bounds()
        obj_gaps = jsol.get_objective_gaps()
        solvests = jsol.get_solve_status()
        srchsts = jsol.get_search_status()
Beispiel #4
0
# Create one variable per store to contain the index of its supplying warehouse

NB_WAREHOUSES = len(WAREHOUSES)

supplier = mdl.integer_var_list(NB_STORES, 0, NB_WAREHOUSES - 1, "supplier")

# Create one variable per warehouse to indicate if it is open (1) or not (0)

open = mdl.integer_var_list(NB_WAREHOUSES, 0, 1, "open")

# Add constraints stating that the supplying warehouse of each store must be open

for s in supplier:

    mdl.add(mdl.element(open, s) == 1)

# Add constraints stating that the number of stores supplied by each warehouse must not exceed its capacity

for wx in range(NB_WAREHOUSES):

    mdl.add(mdl.count(supplier, wx) <= WAREHOUSES[wx].capacity)

# Build an expression that computes total cost

total_cost = mdl.scal_prod(open, [w.cost for w in WAREHOUSES])

for sx in range(NB_STORES):

    total_cost = total_cost + mdl.element(supplier[sx], SUPPLY_COST[sx])
Beispiel #5
0
# The orders are allocated to the slabs with capacity
mdl.add(mdl.pack(slab_use, production_slab, [o.weight for o in ORDERS]))

# Constrain max number of colors produced by each slab
for s in range(MAX_SLABS):
    su = 0
    for c in allcolors:
        lo = False
        for i, o in enumerate(ORDERS):
            if o.color == c:
                lo |= (production_slab[i] == s)
        su += lo
    mdl.add(su <= MAX_COLOR_PER_SLAB)

# Minimize the total loss
total_loss = sum([mdl.element(slab_use[s], loss) for s in range(MAX_SLABS)])
mdl.add(mdl.minimize(total_loss))

# Set search strategy
mdl.set_search_phases([mdl.search_phase(production_slab)])

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

# Solve model
print("Solving model....")
msol = mdl.solve(FailLimit=100000, TimeLimit=10)

# Print solution
if msol:
Beispiel #6
0
supplyCost = [[20, 24, 11, 25, 30], [28, 27, 82, 83, 74], [74, 97, 71, 96, 70],
              [2, 55, 73, 69, 61], [46, 96, 59, 83, 4], [42, 22, 29, 67, 59],
              [1, 5, 73, 59, 56], [10, 73, 13, 43, 96], [93, 35, 63, 85, 46],
              [47, 65, 55, 71, 95]]

# Define model.
wl = CpoModel()

# Define decision variables.
openwarehouse = wl.integer_var_list(nbWarehouses, 0, 1, "openwarehouse")
warehouseservesstore = wl.integer_var_list(nbStores, 0, nbWarehouses - 1,
                                           "warehouseservesstore")

# Define constraints.
for s in warehouseservesstore:
    wl.add(wl.element(openwarehouse, s) == 1)

for w in range(nbWarehouses):
    wl.add(wl.count(warehouseservesstore, w) <= capacity[w])

# Define objective.
fixedArray = []
for i in range(nbWarehouses):
    fixedArray.append(fixed)
total_cost = wl.scal_prod(openwarehouse, fixedArray)
for s in range(nbStores):
    total_cost = total_cost + wl.element(warehouseservesstore[s],
                                         supplyCost[s])

wl.add(wl.minimize(total_cost))
# that will be further minimized with the additional machine
# costs.

# This solution is consistent with the second phase,
# set it as starting point
model.set_starting_point(msol.get_solution())
bounds = msol.get_objective_bounds()
model.remove(cost_tasks)

cost_overall = cost_tasks

for machine in data['machines']:
    m_id = machine['id']
    # Add machine idle consumption
    cost_overall += model.sum([
        (model.element(energy_sum_array, model.end_of(on_i)) -
         model.element(energy_sum_array, model.start_of(on_i))) *
        machine['idle_consumption'] for on_i in on_intervals[m_id]
    ])

    # Add power up/down cost
    on_off_cost = machine['power_up_cost'] + machine['power_down_cost']
    cost_overall += model.sum([
        on_off_cost * model.presence_of(on_interval)
        for on_interval in on_intervals[m_id]
    ])

# We can be sure that the lower bound of
# first phase is a lower bound of this phase
model.add(cost_overall >= bounds[0])
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
for i in range(NB_TASKS):
    tpi = TASK_TYPE[i]
    isLongSetup1 = [
        1 if 30 <= SETUP_M1[tpi][j] else 0 for j in range(NB_TYPES)
    ] + [0]
    isLongSetup2 = [
        1 if 30 <= SETUP_M2[tpi][j] else 0 for j in range(NB_TYPES)
    ] + [0]
    nbLongSetups += mdl.element(
        mdl.type_of_next(s1, tasks_m1[i], NB_TYPES, NB_TYPES), isLongSetup1)
    nbLongSetups += mdl.element(
        mdl.type_of_next(s2, tasks_m2[i], NB_TYPES, NB_TYPES), isLongSetup2)

mdl.add(mdl.minimize(nbLongSetups))

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


def compact(name):
    # Example: A31_M1_TP1 -> 31
    task, foo = name.split('_', 1)
    return task[1:]
states = []
for s in range(NB_MOVES + 1):
    states.append(mdl.integer_var_list(SIZE, HOLE, BLUE, "State_" + str(s) + "_"))

# Create variables representing from index and to index for each move
fromIndex = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "From_")
toIndex   = mdl.integer_var_list(NB_MOVES, 0, SIZE - 1, "To_")

# Add constraints between each state
for m in range(NB_MOVES):
    fvar = fromIndex[m]
    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)
Beispiel #10
0
# Identification of which customer is assigned to a delivery
customerOfDelivery = mdl.integer_var_list(maxDeliveries, 0, nbCustomers,
                                          "customerOfTruck")
# Transition cost for each delivery
transitionCost = mdl.integer_var_list(maxDeliveries - 1, 0, 1000,
                                      "transitionCost")

# transitionCost[i] = transition cost between configurations i and i+1
for i in range(1, maxDeliveries):
    auxVars = (truckConfigs[i - 1], truckConfigs[i], transitionCost[i - 1])
    mdl.add(mdl.allowed_assignments(auxVars, CONFIGURATION_TRANSITION_COST))

# Constrain the volume of the orders in each truck
mdl.add(mdl.pack(load, where, volumes, nbDeliveries))
for i in range(0, maxDeliveries):
    mdl.add(load[i] <= mdl.element(truckConfigs[i], maxTruckConfigLoad))

# Compatibility between the product type of an order and the configuration of its truck
for j in range(0, nbOrders):
    configOfContainer = mdl.integer_var(
        ALLOWED_CONTAINER_CONFIGS[productType[j]])
    mdl.add(configOfContainer == mdl.element(truckConfigs, where[j]))

# Only one customer per delivery
for j in range(0, nbOrders):
    mdl.add(mdl.element(customerOfDelivery, where[j]) == CUSTOMER_ORDERS[j][0])

# Non-used deliveries are at the end
for j in range(1, maxDeliveries):
    mdl.add((load[j - 1] > 0) | (load[j] == 0))
Beispiel #11
0
    for j in range(i):
        if ((PRODUCT_CATS[i], PRODUCT_CATS[j]) in INCOMPATIBLE_GROUPS) or (
            (PRODUCT_CATS[j], PRODUCT_CATS[i]) in INCOMPATIBLE_GROUPS):
            print("Find incompatible group ({}, {})".format(
                PRODUCT_NAMES[i], PRODUCT_NAMES[j]))
            mdl.add(
                mdl.logical_not((mdl.start_of(vx[i]) == mdl.end_of(vx[j]))
                                | (mdl.start_of(vx[j]) == mdl.end_of(vx[i]))
                                | (mdl.start_of(vy[i]) == mdl.end_of(vy[j]))
                                | (mdl.start_of(vy[j]) == mdl.end_of(vy[i]))))

# OF - минимум энергии, необходимой для поддержания температурных режимов продуктов на полках
mdl.add(
    mdl.minimize(
        mdl.sum(
            mdl.element(SHELVES_PRODUCT_MATRIX[t], mdl.start_of(vx[t]))
            for t in range(len(vx)))))

mdl.set_search_phases([mdl.search_phase(vx), mdl.search_phase(vy)])

# -----------------------------------------------------------------------------
# Решение solver'ом и вывод
# -----------------------------------------------------------------------------
print("Solving model....")
msol = mdl.solve(
    FailLimit=100000000,
    TimeLimit=60 * 3,
    LogVerbosity="Terse",  # use "Quiet" or "Terse"
    #RandomSeed=random.randint(1, 1000),
    OptimalityTolerance=1.0,
    RelativeOptimalityTolerance=0.005)