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
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
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()
# 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])
# 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:
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)
# 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))
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)