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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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')
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
#-----------------------------------------------------------------------------

# 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:
Ejemplo n.º 11
0
#-----------------------------------------------------------------------------
# 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))
Ejemplo n.º 12
0
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
Ejemplo n.º 14
0
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)
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
    (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):
Ejemplo n.º 18
0
                    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
Ejemplo n.º 19
0
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 = []
Ejemplo n.º 20
0

#-----------------------------------------------------------------------------
# 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]:
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
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)
Ejemplo n.º 24
0
#-----------------------------------------------------------------------------
# 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):
Ejemplo n.º 25
0
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")
Ejemplo n.º 26
0
# 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:
Ejemplo n.º 27
0
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)
Ejemplo n.º 29
0
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
Ejemplo n.º 30
0
    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(