def minimum_resources(task: ElasticTask, allocation_priority: NonElasticResourcePriority) -> Tuple[int, int, int]: """ Find the optimal non_elastic speeds of the task :param task: The task to use :param allocation_priority: The non-elastic value function to value the speeds :return: non_elastic speeds """ model = CpoModel('non_elasticSpeedsPrioritisation') loading_speed = model.integer_var(min=1, name='loading speed') compute_speed = model.integer_var(min=1, name='compute speed') sending_speed = model.integer_var(min=1, name='sending speed') model.add(task.required_storage / loading_speed + task.required_computation / compute_speed + task.required_results_data / sending_speed <= task.deadline) model.minimize(allocation_priority.evaluate(loading_speed, compute_speed, sending_speed)) model_solution = model.solve(log_output=None) assert model_solution.get_solve_status() == SOLVE_STATUS_FEASIBLE or \ model_solution.get_solve_status() == SOLVE_STATUS_OPTIMAL, \ (model_solution.get_solve_status(), task.__str__()) assert 0 < model_solution.get_value(loading_speed) and \ 0 < model_solution.get_value(compute_speed) and \ 0 < model_solution.get_value(sending_speed), \ (model_solution.get(loading_speed), model_solution.get(compute_speed), model_solution.get(sending_speed)) return model_solution.get_value(loading_speed), \ model_solution.get_value(compute_speed), \ model_solution.get_value(sending_speed)
def elastic_feasible_allocation( task_server_allocations: Dict[Server, List[ElasticTask]], time_limit: int = 60 ) -> Optional[Dict[ElasticTask, Tuple[int, int, int]]]: """ Checks whether a task to server allocation is a feasible solution to the problem :param task_server_allocations: The current task allocation :param time_limit: The time limit to solve the problem within :return: An optional dictionary of the task to the tuple of resource speeds """ model = CpoModel("Allocation Feasibility") loading_speeds: Dict[ElasticTask, CpoVariable] = {} compute_speeds: Dict[ElasticTask, CpoVariable] = {} sending_speeds: Dict[ElasticTask, CpoVariable] = {} for server, tasks in task_server_allocations.items(): for task in tasks: loading_speeds[task] = model.integer_var( min=1, max=server.bandwidth_capacity, name=f'Task {task.name} loading speed') compute_speeds[task] = model.integer_var( min=1, max=server.computation_capacity, name=f'Task {task.name} compute speed') sending_speeds[task] = model.integer_var( min=1, max=server.bandwidth_capacity, name=f'Task {task.name} sending speed') model.add((task.required_storage / loading_speeds[task]) + (task.required_computation / compute_speeds[task]) + (task.required_results_data / sending_speeds[task]) <= task.deadline) model.add( sum(task.required_storage for task in tasks) <= server.storage_capacity) model.add( sum(compute_speeds[task] for task in tasks) <= server.computation_capacity) model.add( sum((loading_speeds[task] + sending_speeds[task]) for task in tasks) <= server.bandwidth_capacity) model_solution = model.solve(log_output=None, TimeLimit=time_limit) if model_solution.get_solve_status() == SOLVE_STATUS_FEASIBLE: return { task: (model_solution.get_value(loading_speeds[task]), model_solution.get_value(compute_speeds[task]), model_solution.get_value(sending_speeds[task])) for tasks in task_server_allocations.values() for task in tasks } else: return None
def allocate(self, task: ElasticTask, server: Server) -> Tuple[int, int, int]: """ Determines the resource speed for the task on the server but finding the smallest :param task: The task :param server: The server :return: A tuple of resource speeds """ """ Initial version that attempts brute force however too computationally expensive when the discretisation of the server resources is too high return min(((s, w, r) for s in range(1, server.available_bandwidth + 1) for w in range(1, server.available_computation + 1) for r in range(1, server.available_bandwidth - s + 1) if task.required_storage * w * r + s * task.required_computation * r + s * w * task.required_results_data <= task.deadline * s * w * r), key=lambda bid: self.resource_evaluator(task, server, bid[0], bid[1], bid[2]))""" # TODO possible to use KKT model = CpoModel('resource allocation') loading = model.integer_var(min=1, max=server.available_bandwidth - 1) compute = model.integer_var(min=1, max=server.available_computation) sending = model.integer_var(min=1, max=server.available_bandwidth - 1) model.add( task.required_storage * compute * sending + loading * task.required_computation * sending + loading * compute * task.required_results_data <= task.deadline * loading * compute * sending) model.add(loading + sending <= server.available_bandwidth) model.minimize( self.resource_evaluator(task, server, loading, compute, sending)) model_solution = model.solve(log_output=None) if model_solution.get_solve_status() != SOLVE_STATUS_FEASIBLE and \ model_solution.get_solve_status() != SOLVE_STATUS_OPTIMAL: print( f'Resource allocation fail - status: {model_solution.get_solve_status()} ' f'for {str(task)} and {str(server)}') raise Exception( f'Resource allocation for a task is infeasible, ' f'model solution is {model_solution.get_solve_status()}. ' f'The task setting is {task.save()} and ' f'the server setting has available bandwidth of {server.available_bandwidth} and ' f'available computation of {server.available_computation} ' f'(storage: {server.available_storage})') return model_solution.get_value(loading), model_solution.get_value( compute), model_solution.get_value(sending)
def ALBP(TaskTime, nbStations, PrecedenceTasks): """ Prepare the data for modeling """ # tasks set TASKS = range(len(TaskTime)) # workstations set WORKSTATIONS = range(nbStations) """ Build the model """ # Create CPO model myModel = CpoModel() # Assign tasks to workstation WhichWorkstation = myModel.integer_var_list(len(TaskTime), 0, nbStations - 1) # Cycle time CycleTime = myModel.integer_var(max(TaskTime), sum(TaskTime)) # Add station load constraints for k in WORKSTATIONS: myModel.add(sum(TaskTime[i] * (WhichWorkstation[i] == k) for i in TASKS) <= CycleTime) # Add precedence constraints for i in TASKS: for j in PrecedenceTasks[i]: myModel.add(WhichWorkstation[j] <= WhichWorkstation[i]) # Create model objective myModel.add(myModel.minimize(CycleTime)) """ Solve model """ solution = myModel.solve(FailLimit=100000, TimeLimit=10) """ Print solution """ return solution
def test_cplex(): model = CpoModel('test') x = model.integer_var(name='x') model.minimize(5 * x**2 - 10 * x + 1) solution = model.solve() assert solution.get_solve_status() == SOLVE_STATUS_OPTIMAL
def convert_fixed_task(tasks: List[Task]): """ Converts tasks to fixed tasks Args: tasks: List of tasks Returns: List of fixed tasks """ fixed_tasks = [] for task in tasks: model = CpoModel('FixedTask') loading_speed = model.integer_var(min=1, name='loading speed') compute_speed = model.integer_var(min=1, name='compute speed') sending_speed = model.integer_var(min=1, name='sending speed') model.add((task.required_storage / loading_speed) + (task.required_computation / compute_speed) + (task.required_results_data / sending_speed) <= ( task.deadline - task.auction_time)) model.minimize(1.2**loading_speed + 1.2**compute_speed + 1.2**sending_speed) model_solution = model.solve(log_output=None, TimeLimit=3) if model_solution.get_solve_status( ) != SOLVE_STATUS_FEASIBLE or model_solution.get_solve_status( ) != SOLVE_STATUS_OPTIMAL: fixed_tasks.append( FixedTask(name=task.name, auction_time=task.auction_time, deadline=task.deadline, required_storage=task.required_storage, required_computation=task.required_computation, required_results_data=task.required_results_data, fixed_loading_speed=model_solution.get_value( loading_speed), fixed_compute_speed=model_solution.get_value( compute_speed), fixed_sending_speed=model_solution.get_value( sending_speed))) else: print(f'Error: {model_solution.get_solve_status()}') return fixed_tasks
def solve(storage_budget: List[float], query_size: List[float], query_latency: List[List[float]]): """ Solve result placement with ILP. :param storage_budget: (1 x n_storage) array of storage budgets. :param query_size: (1 x n_query) array of sizes of query. :param query_latency: (n_query x n_storage) array of latencies for each query when placed on each storage. """ n_storage = len(storage_budget) n_query = len(query_size) # Init variables mdl = CpoModel() X = [[ mdl.integer_var(min=0, max=1, name="C" + str(i) + str(j)) for j in range(n_storage) ] for i in range(n_query)] # Objective: minimize delay obj = mdl.sum([ X[i][j] * query_latency[i][j] for j in range(n_storage) for i in range(n_query) ]) mdl.add(mdl.minimize(obj)) # Constraint 1: cannot exceed mem size for j in range(n_storage): mdl.add( mdl.sum([X[i][j] * query_size[i] for i in range(n_query)]) <= storage_budget[j]) # Constraint 2: each query at least placed somewhere for i in range(n_query): mdl.add(mdl.sum([X[i][j] for j in range(n_storage)]) == 1) print('Solving model....') msol = mdl.solve(TimeLimit=10) if msol: sol = [[msol[X[i][j]] for j in range(n_storage)] for i in range(n_query)] print('Solution found:') print_grid(sol) else: print('No solution found')
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
context.solver.agent = 'local' context.solver.local.execfile = '/home/a15001/cplex/cpoptimizer/bin/x86-64_linux/cpoptimizer' from read import read_instance matrix = read_instance() mdl = CpoModel() x = [[[0] * 9] * 9] * 9 for l in range(0, 8): for c in range(0, 8): for v in range(0, 8): x[l][c][v] = mdl.integer_var(0, 1) for i in range(len(matrix)): for j in range(len(matrix[i])): if matrix[i][j] != 0: mdl.add(x[i][j][matrix[i][j] - 1] == 1) # Restrição de linha for c in range(0, 8): for v in range(0, 8): expr = 0 for l in range(0, 8): expr = expr + x[l][c][v] mdl.add(expr == 1)
#----------------------------------------------------------------------------- # Size of the square SQUARE_SIZE = 16 #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Create grid of variables GRNG = range(SQUARE_SIZE) grid = [[mdl.integer_var(min=0, max=SQUARE_SIZE - 1, name="C_{}_{}".format(l, c)) for l in GRNG] for c in GRNG] # Add alldiff constraints for lines for l in GRNG: mdl.add(mdl.all_diff([grid[l][c] for c in GRNG])) # Add alldiff constraints for columns for c in GRNG: mdl.add(mdl.all_diff([grid[l][c] for l in GRNG])) # Add alldiff constraints for diagonals mdl.add(mdl.all_diff([grid[l][l] for l in GRNG])) mdl.add(mdl.all_diff([grid[l][SQUARE_SIZE - l - 1] for l in GRNG])) # Force first line to natural sequence for c in GRNG:
#----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- mdl = CpoModel() # Create variables identifying which location serves each customer cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") # Create variables indicating which plant location is open open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") # Create variables indicating load of each plant 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))
from docplex.cp.model import CpoModel from docplex.cp.model import CpoParameters mdl = CpoModel(name='buses') nbbus40 = mdl.integer_var(0, 1000, name='nbBus40') nbbus30 = mdl.integer_var(0, 1000, name='nbBus30') mdl.add(nbbus40 * 40 + nbbus30 * 30 >= 300) mdl.minimize(nbbus40 * 500 + nbbus30 * 400) param = CpoParameters() param.set_TimeLimit(20) param.TimeLimit = 20 #use parameters param for model mdl mdl.set_parameters(param) msol = mdl.solve() print(msol[nbbus40], " buses 40 seats") print(msol[nbbus30], " buses 30 seats") #read params from model mdl param2 = mdl.get_parameters() print("time limit = ", param2["TimeLimit"]) print("time limit = ", param2.get_attribute("TimeLimit")) for i in param2: print(i, " = ", param2[i]) """ which gives
print(len(macros[0].positionList_x)) for i in range(0, len(macros[0].positionList_x)): print(str(macros[0].positionList_x[i]) + '\t' + str(macros[0].positionList_y[i])) ''' # -------------------- # Build Model # -------------------- # Create Model mdl = CpoModel() # Create Variables - move steps new_index_map = dict() for macro in unique_macros: for term in macro.terms: new_index = mdl.integer_var(0, len(macro.positionList_x), term.name) new_index_map[term.name] = new_index ''' # Create Variable - macro.cpo_center.x/y : fix to macro.center.x/y in constraint for macro in macros: macro.cpo_center.x = mdl.integer_var(domain = (macro.center.x, macro.center.x)) macro.cpo_center.y = mdl.integer_var(domain = (macro.center.y, macro.center.y)) ''' # Apply possible movements in each term in each macro and update new cpo_location after movements for macro in macros: for term in macro.terms: cplex_helpers.moveTermUpdate(mdl, macro, term, new_index_map) # TODO: Rotation # TODO: Multi-copies
The problem involves choosing colors for the countries on a map in such a way that at most four colors (blue, white, yellow, green) are used and no neighboring countries are the same color. In this exercise, you will find a solution for a map coloring problem with six countries: Belgium, Denmark, France, Germany, Luxembourg, and the Netherlands. Please refer to documentation for appropriate setup of solving configuration. """ from docplex.cp.model import CpoModel # Create CPO model mdl = CpoModel() # Create model variables containing colors of the countries Belgium = mdl.integer_var(0, 3, "Belgium") Denmark = mdl.integer_var(0, 3, "Denmark") France = mdl.integer_var(0, 3, "France") Germany = mdl.integer_var(0, 3, "Germany") Luxembourg = mdl.integer_var(0, 3, "Luxembourg") Netherlands = mdl.integer_var(0, 3, "Netherlands") ALL_COUNTRIES = (Belgium, Denmark, France, Germany, Luxembourg, Netherlands) # Create constraints mdl.add(Belgium != France) mdl.add(Belgium != Germany) mdl.add(Belgium != Netherlands) mdl.add(Belgium != Luxembourg) mdl.add(Denmark != Germany) mdl.add(France != Germany) mdl.add(France != Luxembourg)
l += 1 while l < HEIGHT and PUZZLE[l][c] == ' ': l += 1 res += 1 return res #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Create one binary variable for presence of bulbs in cells bulbs = [[mdl.integer_var(min=0, max=1, name="C{}_{}".format(l, c)) for c in range(WIDTH)] for l in range(HEIGHT)] # Force number of bulbs in black cells to zero for l in range(HEIGHT): for c in range(WIDTH): if PUZZLE[l][c] != ' ': mdl.add(bulbs[l][c] == 0) # Force number of bulbs around numbered cells for l in range(HEIGHT): for c in range(WIDTH): v = PUZZLE[l][c] if v.isdigit(): mdl.add(mdl.sum(bulbs[l2][c2] for l2, c2 in get_neighbors(l, c)) == int(v)) # Avoid multiple bulbs on adjacent empty cells
(0, 0, 5, 0, 0, 0, 0, 0, 7), ) #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Grid range GRNG = range(9) # Create grid of variables grid = [[ mdl.integer_var(min=1, max=9, name="C" + str(l) + str(c)) for l in GRNG ] for c in GRNG] # Add alldiff constraints for lines for l in GRNG: mdl.add(mdl.all_diff([grid[l][c] for c in GRNG])) # Add alldiff constraints for columns for c in GRNG: mdl.add(mdl.all_diff([grid[l][c] for l in GRNG])) # Add alldiff constraints for sub-squares ssrng = range(0, 9, 3) for sl in ssrng: for sc in ssrng: mdl.add(
vol = df.values.tolist() vol_commu = [list(map(int,i)) for i in vol] ''' vol_commu = [[0 for _ in range(NUM_RESOURCES)] for _ in range(NUM_RESOURCES)] vol_commu[0][1] = 10000 vol_commu[0][2] = 10000 ''' #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create model mdl = CpoModel() # Create array of variables for subsquares vx = [mdl.integer_var(min=0, max=max(WIDTH_REC,HEIGHT_REC), name="x" + str(i)) for i in range(NUM_RESOURCES)] vy = [mdl.integer_var(min=0, max=max(WIDTH_REC,HEIGHT_REC), name="y" + str(i)) for i in range(NUM_RESOURCES)] vz = [mdl.integer_var(min=0, max=1, name="z" + str(i)) for i in range(NUM_RESOURCES)] # 0 non-rotate. 1 rotate vxy = [[mdl.integer_var(min=0, max=1, name="xy_{}.{}".format(i, j)) for j in range(NUM_RESOURCES)] for i in range(NUM_RESOURCES)] H = mdl.integer_var(min=0, max=HEIGHT_REC, name="H") # Create dependencies between variables (add them one by one) for i in range(NUM_RESOURCES): for j in range(NUM_RESOURCES): mdl.add((vx[i] + (1-vz[i])*SIZE_WIDTH[i] + vz[i]*SIZE_HEIGHT[i] <= WIDTH_REC)) for i in range(NUM_RESOURCES): for j in range(NUM_RESOURCES): mdl.add((vy[i] + (1-vz[i])*SIZE_HEIGHT[i] + vz[i]*SIZE_WIDTH[i] <= H)) for i in range(NUM_RESOURCES-1):
str(pat.id) + '_' + str(ses_idx) # construct the variable domain using global index list time_seg_idx # fetch all indices for any day existing in visiting days (but # not the general treatment days, because they include doctors # team visits as well, and that should not be used for patient # visit purposes.) domain = [] for day in days: sub_domain = util.get_start_end_time_idx( day, day, time_seg_idx) domain.extend( list(range(sub_domain[0], sub_domain[-1] + 1))) vis.s_var = mdl.integer_var(name=name, min=domain[0], max=domain[-1]) # add binary variables for morning and afternoon possibility for day in days: name = 'x_' + str(doc.id) + '_' + str(pat.id) + \ '_' + str(ses_idx) + '_' + str(day) vis.x_vars.append(mdl.binary_var(name=name)) name = 'y_' + str(doc.id) + '_' + str(pat.id) + \ '_' + str(ses_idx) + '_' + str(day) vis.y_vars.append(mdl.binary_var(name=name)) # add day binary vars in a next for loop nested into this one
import random e_x,e_y = [5],[0] SIZE_X = 10 SIZE_Y = 10 Nblack = 544 NWhite = SIZE_X * SIZE_Y - Nblack - 1 calc_white = 0 EXITS_X = list(e_x) EXITS_Y = list(e_y) mdl = CpoModel() mass_v_str = [] mass_v = [] for i in range(SIZE_X): for j in range(SIZE_Y): if [i,j] != [*EXITS_X, *EXITS_Y]: v = mdl.integer_var(domain=(0,1), name='sq_' + str(i) + '_' + str(j)) else: v = mdl.integer_var(domain=(0,0), name='sq_' + str(i) + '_' + str(j)) mass_v_str.append(v) mass_v.append(mass_v_str) mass_v_str = [] def checkin(indexes, mas): try: ind = mas.index(indexes) return 0 except: return 1 def get_neigh(mass, i, j): Y_SIZE = len(mass[0]) X_SIZE = len(mass) Result = []
#----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- mdl = CpoModel() # Create variables identifying which location serves each customer cust = mdl.integer_var_list(nbCustomer, 0, nbLocation - 1, "CustomerLocation") # Create variables indicating which plant location is open open = mdl.integer_var_list(nbLocation, 0, 1, "OpenLocation") # Create variables indicating load of each plant 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)) # Add KPIs
#===============CREATE MODEL=============== mdl = CpoModel(name = "bin-packing-variant") #===============SETUP DECISION VARIABLES=============== #array of integer variables saying which bin an item goes into wheres = [] bin_idx_of_dump_item = 0 for item in items: bin_list = () for bin in bins[0:nb_bins]: if(alloc_constraint[item.id, bin.id] == 1): bin_list += int(bin.id), #add the last bin (the big one) bin_list += nb_bins, wheres.append(mdl.integer_var(domain=(bin_list), name = "whereItem"+str(item.id))) #===============SETUP CONSTRAINTS=============== #one pack constraint for each dimension for k in range(2): #each bin's load can range(0..bin size) loads = [mdl.integer_var(0,bins[int(bin.id)].size[k], name="sizeBin"+str(bin.id)+",d"+str(k)) for bin in bins] mdl.add(mdl.pack(loads, wheres, [item.size[k] for item in items])) #===============SETUP OBJECTIVE=============== #maximize number of items allocated to all bins EXCEPT the big bin #nb_allocated_items = mdl.sum([(wheres[int(item.id)] != nb_bins) for item in items]) #maximize x_1 * x_2 * ... *x_n, where x_1, x_2,..., x_n is the number of items in bin 1, 2, ..., n product_x = 1 for bin in bins[0:len(bins)-1]:
def optimal_task_price(new_task: ElasticTask, server: Server, time_limit: int, debug_results: bool = False): """ Calculates the task price :param new_task: The new task :param server: The server :param time_limit: Time limit for the cplex :param debug_results: debug the results :return: task price and task speeds """ assert 0 < time_limit, f'Time limit: {time_limit}' assert new_task.required_storage <= server.storage_capacity model = CpoModel(f'{new_task.name} Task Price') # Add the new task to the list of server allocated tasks tasks = server.allocated_tasks + [new_task] # Create all of the resource speeds variables loading_speeds = {task: model.integer_var(min=1, max=task.loading_ub()) for task in tasks} compute_speeds = {task: model.integer_var(min=1, max=task.compute_ub()) for task in tasks} sending_speeds = {task: model.integer_var(min=1, max=task.sending_ub()) for task in tasks} # Create all of the allocation variables however only on the currently allocated tasks allocation = {task: model.binary_var(name=f'{task.name} Task allocated') for task in server.allocated_tasks} # Add the deadline constraint for task in tasks: model.add((task.required_storage / loading_speeds[task]) + (task.required_computation / compute_speeds[task]) + (task.required_results_data / sending_speeds[task]) <= task.deadline) # Add the server resource constraints model.add(sum(task.required_storage * allocated for task, allocated in allocation.items()) + new_task.required_storage <= server.storage_capacity) model.add(sum(compute_speeds[task] * allocated for task, allocated in allocation.items()) + compute_speeds[new_task] <= server.computation_capacity) model.add(sum((loading_speeds[task] + sending_speeds[task]) * allocated for task, allocated in allocation.items()) + (loading_speeds[new_task] + sending_speeds[new_task]) <= server.bandwidth_capacity) # The optimisation function model.maximize(sum(task.price * allocated for task, allocated in allocation.items())) # Solve the model with a time limit model_solution = model.solve(log_output=None, TimeLimit=time_limit) # If the model solution failed then return an infinite price if model_solution.get_solve_status() != SOLVE_STATUS_FEASIBLE and \ model_solution.get_solve_status() != SOLVE_STATUS_OPTIMAL: print(f'Cplex model failed - status: {model_solution.get_solve_status()} ' f'for new {str(new_task)} and {str(server)}') return math.inf, {} # Get the max server profit that the model finds and calculate the task price through a vcg similar function new_server_revenue = model_solution.get_objective_values()[0] task_price = max(server.revenue - new_server_revenue + server.price_change, server.initial_price) # Get the resource speeds and task allocations speeds = { task: (model_solution.get_value(loading_speeds[task]), model_solution.get_value(compute_speeds[task]), model_solution.get_value(sending_speeds[task]), model_solution.get_value(allocation[task]) if task in allocation else True) for task in tasks } debug(f'Sever: {server.name} - Prior revenue: {server.revenue}, new revenue: {new_server_revenue}, ' f'price change: {server.price_change} therefore task price: {task_price}', debug_results) return task_price, speeds
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)
#----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Configuration of the truck for each delivery truckConfigs = mdl.integer_var_list(maxDeliveries, 0, nbTruckConfigs - 1, "truckConfigs") # In which delivery is an order where = mdl.integer_var_list(nbOrders, 0, maxDeliveries - 1, "where") # Load of a truck load = mdl.integer_var_list(maxDeliveries, 0, maxLoad, "load") # Number of deliveries that are required nbDeliveries = mdl.integer_var(0, maxDeliveries) # 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):
nbKids = 300 # Indexes busSize = 0 busCost = 1 for b in Buses: print("buses with ", b[busSize], " seats cost ", b[busCost]) mdl = CpoModel(name='buses') #decision variables mdl.nbBus = { b: mdl.integer_var(0, 1000, name="nbBus" + str(b[busSize])) for b in Buses } # Constraint mdl.add(sum(mdl.nbBus[b] * b[busSize] for b in Buses) >= nbKids) # Objective mdl.minimize(sum(mdl.nbBus[b] * b[busCost] for b in Buses)) msol = mdl.solve() # Dislay solution for b in Buses: print(msol[mdl.nbBus[b]], " buses with ", b[busSize], " seats")
# Indicate to constrain each square diagonal with all different symbols CONSTRAIN_DIAGONALS = True #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Create grid of variables GRNG = range(CUBE_SIZE) grid = [[[ mdl.integer_var(min=0, max=CUBE_SIZE - 1, name="C_{}_{}_{}".format(x, y, z)) for x in GRNG ] for y in GRNG] for z in GRNG] # Add constraints for each slice on direction x for x in GRNG: # Add alldiff constraints for lines for l in GRNG: mdl.add(mdl.all_diff([grid[x][l][c] for c in GRNG])) # Add alldiff constraints for columns for c in GRNG: mdl.add(mdl.all_diff([grid[x][l][c] for l in GRNG])) # Add alldiff constraints for diagonals if CONSTRAIN_DIAGONALS:
def get_neighbors(l, c): """ Build the list of neighbors of a given cell """ res = [] if c > 0: res.append((l, c - 1)) if c < SIZE - 1: res.append((l, c + 1)) if l > 0: res.append((l - 1, c)) if l < SIZE - 1: res.append((l + 1, c)) return res # Create model mdl = CpoModel() # Create one binary variable for each colored cell color = [[ mdl.integer_var(min=0, max=1, name="C" + str(l) + "_" + str(c)) for c in range(SIZE) ] for l in range(SIZE)] # Forbid adjacent colored cells for l in range(SIZE): for c in range(SIZE - 1): mdl.add((color[l][c] + color[l][c + 1]) < 2) for c in range(SIZE): for l in range(SIZE - 1): mdl.add((color[l][c] + color[l + 1][c]) < 2) # Color cells for digits occurring more than once for l in range(SIZE): lvals = [] # List of values already processed for c in range(SIZE):
def elastic_optimal_solver(tasks: List[ElasticTask], servers: List[Server], time_limit: Optional[int]): """ Elastic Optimal algorithm solver using cplex :param tasks: List of tasks :param servers: List of servers :param time_limit: Time limit for cplex :return: the results of the algorithm """ assert time_limit is None or 0 < time_limit, f'Time limit: {time_limit}' model = CpoModel('Elastic Optimal') # The resource speed variables and the allocation variables loading_speeds, compute_speeds, sending_speeds, task_allocation = {}, {}, {}, {} # Loop over each task to allocate the variables and add the deadline constraints max_bandwidth = max(server.bandwidth_capacity for server in servers) max_computation = max(server.computation_capacity for server in servers) runnable_tasks = [ task for task in tasks if any( server.can_run_empty(task) for server in servers) ] for task in runnable_tasks: # Check if the task can be run on any server even if empty loading_speeds[task] = model.integer_var( min=1, max=max_bandwidth - 1, name=f'{task.name} loading speed') compute_speeds[task] = model.integer_var( min=1, max=max_computation, name=f'{task.name} compute speed') sending_speeds[task] = model.integer_var( min=1, max=max_bandwidth - 1, name=f'{task.name} sending speed') model.add((task.required_storage / loading_speeds[task]) + (task.required_computation / compute_speeds[task]) + (task.required_results_data / sending_speeds[task]) <= task.deadline) # The task allocation variables and add the allocation constraint for server in servers: task_allocation[(task, server)] = model.binary_var( name=f'{task.name} Task - {server.name} Server') model.add( sum(task_allocation[(task, server)] for server in servers) <= 1) # For each server, add the resource constraint for server in servers: model.add( sum(task.required_storage * task_allocation[(task, server)] for task in runnable_tasks) <= server.available_storage) model.add( sum(compute_speeds[task] * task_allocation[(task, server)] for task in runnable_tasks) <= server.available_computation) model.add( sum((loading_speeds[task] + sending_speeds[task]) * task_allocation[(task, server)] for task in runnable_tasks) <= server.available_bandwidth) # The optimisation statement model.maximize( sum(task.value * task_allocation[(task, server)] for task in runnable_tasks for server in servers)) # Solve the cplex model with time limit try: model_solution: CpoSolveResult = model.solve(log_output=None, TimeLimit=time_limit) except CpoSolverException as e: print(f'Solver Exception: ', e) return None # Check that it is solved if model_solution.get_solve_status() != SOLVE_STATUS_FEASIBLE and \ model_solution.get_solve_status() != SOLVE_STATUS_OPTIMAL: print(f'Optimal solver failed', file=sys.stderr) print_model_solution(model_solution) print_model(tasks, servers) return None # Generate the allocation of the tasks and servers try: for task in runnable_tasks: for server in servers: if model_solution.get_value(task_allocation[(task, server)]): server_task_allocation( server, task, model_solution.get_value(loading_speeds[task]), model_solution.get_value(compute_speeds[task]), model_solution.get_value(sending_speeds[task])) break if abs(model_solution.get_objective_values()[0] - sum(t.value for t in tasks if t.running_server)) > 0.1: print( 'Elastic optimal different objective values - ' f'cplex: {model_solution.get_objective_values()[0]} and ' f'running task values: {sum(task.value for task in tasks if task.running_server)}', file=sys.stderr) return model_solution except (AssertionError, KeyError) as e: print('Error: ', e, file=sys.stderr) print_model_solution(model_solution)
from docplex.cp.model import CpoModel mdl = CpoModel(name='buses') nbbus40 = mdl.integer_var(0, 6, name='nbBus40') nbbus30 = mdl.integer_var(0, 6, name='nbBus30') cost = mdl.integer_var(0, 1000000, name='cost') mdl.add(cost == nbbus40 * 500 + nbbus30 * 400) mdl.add(cost <= 4000) mdl.add(nbbus40 * 40 + nbbus30 * 30 >= 300) siter = mdl.start_search(SearchType='DepthFirst', Workers=1, TimeLimit=100) # Parameters needed to avoid duplicate solutions from pandas import * dfsol = pandas.DataFrame() for msol in siter: print(msol[nbbus40], " buses 40 seats") print(msol[nbbus30], " buses 30 seats") print("cost = ", msol[cost]) dfsol = concat( [dfsol, DataFrame([msol[nbbus40], msol[nbbus30], msol[cost]])], axis=1) print("\n") dfsol.columns = ["sol1", "sol2", "sol3"] print(dfsol) """ which gives
while l < HEIGHT and PUZZLE[l][c] == ' ': l += 1 res += 1 return res #----------------------------------------------------------------------------- # Build the model #----------------------------------------------------------------------------- # Create CPO model mdl = CpoModel() # Create one binary variable for presence of bulbs in cells bulbs = [[ mdl.integer_var(min=0, max=1, name="C{}_{}".format(l, c)) for c in range(WIDTH) ] for l in range(HEIGHT)] # Force number of bulbs in black cells to zero for l in range(HEIGHT): for c in range(WIDTH): if PUZZLE[l][c] != ' ': mdl.add(bulbs[l][c] == 0) # Force number of bulbs around numbered cells for l in range(HEIGHT): for c in range(WIDTH): v = PUZZLE[l][c] if v.isdigit(): mdl.add(