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 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)
Example #3
0
def BRAttackerP(gameModel):
    source = gameModel.source_list[0]
    edges = list(gameModel.G.edges())
    nodes = list(gameModel.G.nodes())

    defender_coverage = gameModel.defender_strategy_set
    defender_prob = gameModel.defender_prob
    assert(len(defender_coverage) == len(defender_prob))

    resource_list = gameModel.resource_list
    edge2index = gameModel.edge2index

    solution_list = []
    # =================== attacker CP ==================
    for j in range(len(gameModel.terminal_list)):
        # ---------------- tarminal j ------------------
        target = gameModel.terminal_list[j]
        cpo = CpoModel()
        # cpo.add_parameters(LogVerbosity="Quiet")

        edge_variables = cpo.binary_var_list(gameModel.m, "gamma")
        cpo.add(sum([edge_variables[edge2index[source_out]] for source_out in gameModel.G.out_edges(source)]) - sum([edge_variables[edge2index[source_in]] for source_in in gameModel.G.in_edges(source)]) == 1)
        cpo.add(sum([edge_variables[edge2index[target_out]] for target_out in gameModel.G.out_edges(target)]) - sum([edge_variables[edge2index[target_in]] for target_in in gameModel.G.in_edges(target)]) == -1)
        for node in nodes:
            if node == source or node == target:
                continue
            else:
                cpo.add(sum([edge_variables[edge2index[in_edge]] for in_edge in gameModel.G.in_edges(node)]) == sum([edge_variables[edge2index[out_edge]] for out_edge in gameModel.G.out_edges(node)])) # incoming flow == outgoing flow

        # -------------- computing the objective value -------------
        objective_value = 0
        for i in range(len(defender_coverage)):
            success_prob = 1
            for r in range(gameModel.R):
                covering_prob = gameModel.resource_list[r].prob # covering prob
                # print defender_coverage[i].resource_usage
                for e_i in range(len(defender_coverage[i].resource_usage[r])):
                    e = defender_coverage[i].resource_usage[r][e_i]
                    success_prob *= (1 - edge_variables[edge2index[e]] * covering_prob)
            objective_value += success_prob * defender_prob[i] * gameModel.terminal_payoff[j]

        cpo.add(cpo.maximize(objective_value))
        cpo_solution = cpo.solve()
        if cpo_solution:
            edge_usage = [edges[i] for i in range(gameModel.m) if cpo_solution[edge_variables[i]] == 1]
            obj = cpo_solution.get_objective_values()

            solution_list.append((obj, edge_usage, target, cpo))
        else:
            print("no solution")

    best_solution = max(solution_list, key=lambda x: x[0])
    best_target = best_solution[2]
    best_cpo = best_solution[3]
    best_cpo.export_model("attacker.cpo")
    new_obj = best_solution[0]
    new_G = nx.DiGraph(best_solution[1])
    print("edges:", new_G.edges)
    new_path = nx.shortest_path(new_G, source, best_target)
    return new_obj, new_path
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
Example #5
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
Example #6
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
Example #7
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
Example #8
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
    def solve(self, factors, observed, config, all_bits):
        rvs = list(sorted(factors.keys()))

        # https://cdn.rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/cp/creating_model.html
        model = CpoModel()
        # model.context.cplex_parameters.threads = cpu_count()
        rv2var = {rv: model.binary_var(str(rv)) for rv in rvs}
        for rv, val in observed.items():
            model.add(rv2var[rv] == bool(val))
        for rv, factor in factors.items():
            ftype = factor.factor_type
            if ftype == 'INV':
                inp = factor.input_rvs[0]
                model.add(rv2var[inp] == 1 - rv2var[rv])
            elif ftype == 'SAME':
                inp = factor.input_rvs[0]
                model.add(rv2var[inp] == rv2var[rv])
            elif ftype == 'AND':
                inp1, inp2 = factor.input_rvs[:2]
                # Linearization of out = inp1 * inp2 for binary variables
                model.add(rv2var[rv] <= rv2var[inp1])
                model.add(rv2var[rv] <= rv2var[inp2])
                model.add(rv2var[rv] >= rv2var[inp1] + rv2var[inp2] - 1)

        # https://cdn.rawgit.com/IBMDecisionOptimization/docplex-doc/master/docs/cp/docplex.cp.parameters.py.html#docplex.cp.parameters.CpoParameters
        params = CpoParameters(Workers=cpu_count())

        model.print_information()
        sol = model.solve(
            agent='local',
            params=params,
            execfile=
            '/Applications/CPLEX_Studio1210/cpoptimizer/bin/x86-64_osx/cpoptimizer'
        )
        solution = {rv: sol.get_value(rv2var[rv]) for rv in rvs}
        return solution
Example #10
0
def solveSchedulingSubproblem(numJobs, totalTime, availResources, jobLength):
    ''' Input data
    numJobs: Number of jobs (int)
    totalTime: Total time blocks (int)
    availResources: Total amount of resource available for this machine.  Assume each job uses one resource. (int)
    jobLength: The length (in time blocks) of each job (list, by job number)
    '''

    # Create a CPO model
    model = CpoModel()

    # Create variables
    TIME = model.integer_var_list(numJobs, 0, totalTime - 1,
                                  "TIME")  # For each job, indicate start time
    RESOURCE = model.integer_var_list(
        numJobs, 0, availResources - 1,
        "RESOURCE")  # For each job, indicate resource used

    # Add general constraints
    for i in range(numJobs):
        # Jobs must end before the end of the totalTime available
        model.add(TIME[i] + jobLength[i] <= totalTime)
        # Jobs can't be scheduled on a machine at the same time
        for j in range(numJobs):
            if i != j:
                model.add((RESOURCE[i] != RESOURCE[j])
                          | (TIME[i] + jobLength[i] <= TIME[j])
                          | (TIME[j] + jobLength[j] <= TIME[i]))

    # If there's only one job, then above constraints will never reference RESOURCE variable.
    # In that case, RESOURCE won't show up in the problem, and won't get a value.
    # To prevent this, we add dummy constraints on RESOURCE as follows:
    if numJobs == 1: model.add(RESOURCE[0] >= 0)

    # Solve model
    print("Solving model....")
    msol = model.solve(TimeLimit=10)

    if msol:  # If the model ran successfully, it returns True
        print("Solution:")
        for j in range(numJobs):
            print("Job " + str(j) + " starts at time " + str(msol[TIME[j]]) +
                  " and uses resource " + str(msol[RESOURCE[j]]))
        print("Last job time ends at " +
              str(max(msol[TIME[j]] + jobLength[j] for j in range(numJobs))))
        return True
    else:  # Problem is infeasible; print the infeasibility
        # theConflictsResult = model.refine_conflict()
        # print(theConflictsResult)
        return False
Example #11
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')
Example #12
0
def recherche_exact(instance, temps):
    '''
    :param temps: int, temps de recherche
    :param instance: nom de l'instance str
    :return: None
    '''
    problem_data, optimum = loader(instance)
    nb_machine = problem_data["nb_machine"]
    nb_jobs = problem_data["nb_jobs"]
    problem = problem_data["problem"]

    machine, durations = separate(problem)

    model = CpoModel(name='Scheduling')

    # Variable
    job_operations = [[model.interval_var(size=durations[j][m],
                                          name="O{}-{}".format(j, m)) for m in range(nb_machine)] for j in
                      range(nb_jobs)]

    # chaque opération doit commencer aprés la fin de la précedente
    for j in range(nb_jobs):
        for s in range(1, nb_machine):
            model.add(model.end_before_start(job_operations[j][s - 1], job_operations[j][s]))

    # Pas d'overlap pour les operations executées sur une même machine
    machine_operations = [[] for m in range(nb_machine)]
    for j in range(nb_jobs):
        for s in range(0, nb_machine):
            machine_operations[machine[j][s]].append(job_operations[j][s])
    for lops in machine_operations:
        model.add(model.no_overlap(lops))

    # Minimiser la date de fin
    model.add(model.minimize(model.max([model.end_of(job_operations[i][nb_machine - 1]) for i in range(nb_jobs)])))

    # Solve model
    print("Solving model....")
    msol = model.solve(TimeLimit=temps)
Example #13
0
# Create model
mdl = CpoModel()

masonry = mdl.interval_var(name='masonry', size=35)
carpentry = mdl.interval_var(name='carpentry', size=15)
plumbing = mdl.interval_var(name='plumbing', size=40)
ceiling = mdl.interval_var(name='ceiling', size=15)
roofing = mdl.interval_var(name='roofing', size=5)
painting = mdl.interval_var(name='painting', size=10)
windows = mdl.interval_var(name='windows', size=5)
facade = mdl.interval_var(name='facade', size=10)
garden = mdl.interval_var(name='garden', size=5)
moving = mdl.interval_var(name='moving', size=5)

# Add precedence constraints
mdl.add(mdl.end_before_start(masonry, carpentry))
mdl.add(mdl.end_before_start(masonry, plumbing))
mdl.add(mdl.end_before_start(masonry, ceiling))
mdl.add(mdl.end_before_start(carpentry, roofing))
mdl.add(mdl.end_before_start(ceiling, painting))
mdl.add(mdl.end_before_start(roofing, windows))
mdl.add(mdl.end_before_start(roofing, facade))
mdl.add(mdl.end_before_start(plumbing, facade))
mdl.add(mdl.end_before_start(roofing, garden))
mdl.add(mdl.end_before_start(plumbing, garden))
mdl.add(mdl.end_before_start(windows, moving))
mdl.add(mdl.end_before_start(facade, moving))
mdl.add(mdl.end_before_start(garden, moving))
mdl.add(mdl.end_before_start(painting, moving))

#-----------------------------------------------------------------------------
Example #14
0
    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):
        v = PUZZLE[l][c]
        if v not in lvals:
            lvals.append(v)
            lvars = [color[l][c]]
            for c2 in range(c + 1, SIZE):
                if PUZZLE[l][c2] == v:
                    lvars.append(color[l][c2])
Example #15
0
# 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))

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

# Estimate an upper bound to the ruler length
MAX_LENGTH = (ORDER - 1)**2

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create array of variables corresponding to position rule marks
marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, "M")

# Create marks distances that should be all different
dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)]
mdl.add(mdl.all_diff(dist))

# Avoid symmetric solutions by ordering marks
mdl.add(marks[0] == 0)
for i in range(1, ORDER):
    mdl.add(marks[i] > marks[i - 1])

# Avoid mirror solution
mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2]))

# Minimize ruler size (position of the last mark)
mdl.add(mdl.minimize(marks[ORDER - 1]))

#-----------------------------------------------------------------------------
# Solve the model and display the result
#-----------------------------------------------------------------------------
Example #17
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")
for i in range(len(ALL_TASKS)):
    ALL_TASKS[i].id = i

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create interval variable for each building task
tasks = [mdl.interval_var(size=t.duration, name=t.name) for t in ALL_TASKS]

# Add precedence constraints
for p, s in PRECEDENCES:
    mdl.add(mdl.end_before_start(tasks[p.id], tasks[s.id]))

# Cost function
cost = []  # List of individual costs
fearliness = dict()  # Task earliness cost function (for display)
ftardiness = dict()  # Task tardiness cost function (for display)

for t in ALL_TASKS:
    task = tasks[t.id]
    if t.release_date is not None:
        f = CpoSegmentedFunction((-t.earliness_cost, 0),
                                 [(t.release_date, 0, 0)])
        cost.append(mdl.start_eval(task, f))
        fearliness[t] = f
    if t.due_date is not None:
        f = CpoSegmentedFunction((0, 0), [(t.due_date, 0, t.tardiness_cost)])
Example #19
0
    global cash

    # Allocate tasks to workers
    for t in ALL_TASKS:
        desc[tasks[t.id]] = t
        house[tasks[t.id]] = loc
        workers_usage += mdl.pulse(tasks[t.id], 1)
        cash -= mdl.step_at_start(tasks[t.id], 200 * t.duration)


# Make houses
for i, sd in enumerate(HOUSES):
    make_house(i, sd)

# Number of workers should not be greater than the limit
mdl.add(workers_usage <= NB_WORKERS)

# Cash should not be negative
mdl.add(cash >= 0)

# Minimize overall completion date
mdl.add(mdl.minimize(mdl.max([mdl.end_of(task) for task in all_tasks])))

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


def compact(name):
    # Example: H3-garden -> G3
    #           ^ ^
Example #20
0
    def initialize(self):
        model = CpoModel()
        self.model = model
        instance = self.instance
        T = len(instance.intervals)
        first_on = instance.earliest_on_interval_idx
        last_on = instance.latest_on_interval_idx
        init_start_times = self.get_init_start_times(sort_starts=True)
        ub = min(instance.get_ub(), self.get_upper_bound(init_start_times))
        total_proc = sum(j.processing_time for j in instance.jobs)

        # -------------------------------------- Construct the model.
        job_vars = dict()  # Dict[Job, CpoIntervalVar]
        self.job_vars = job_vars
        gap_vars = dict()  # Dict[Tuple[int, int], CpoIntervalVar]
        obj = 0  # objective value
        seq_vars = []  # variables for no-overlap constraint
        stp = model.create_empty_solution(
        )  # starting point of the solving procedure
        step_fns = CpGeneral.get_step_functions(
            instance, first_on,
            last_on)  # Generate seqment function for each processing time.

        first_job_var = model.interval_var(length=0,
                                           optional=False,
                                           name="first_job_var",
                                           start=1)
        seq_vars.append(
            first_job_var)  # dummy job with 0 length, first in the sequence
        last_job_var = model.interval_var(length=0,
                                          optional=False,
                                          name="last_job_var",
                                          end=T - 1)
        seq_vars.append(
            last_job_var)  # dummy job with 0 length, last in the sequence

        # variables for jobs -------------------------------------------------------------------------------------------
        for job in instance.jobs:
            var = model.interval_var(length=job.processing_time,
                                     optional=False,
                                     name="j[{:d}]".format(job.id))
            model.add(cpmod.start_of(var) >=
                      first_on)  # earliest possible start time is first_on
            model.add(cpmod.end_of(var) <=
                      last_on + 1)  # latest possible end time is last_on
            job_vars[job] = var
            seq_vars.append(var)

            if self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 0:  # Optional :
                alternatives = []
                for t in range(first_on, T):
                    if t <= last_on - (
                            job.processing_time - 1
                    ):  # (-1) because unit job can be processed in last_on
                        var = model.interval_var(start=t,
                                                 length=job.processing_time,
                                                 optional=True,
                                                 name="j[{:d},{:d}]".format(
                                                     t, job.id))
                        alternatives.append(var)
                        obj += cpmod.presence_of(
                            var) * instance.cumulative_energy_cost[t][
                                t + job.processing_time -
                                1] * instance.on_power_consumption

                # add a present variable for the job
                model.add(cpmod.alternative(job_vars[job], alternatives))
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 1:  # Logical :
                for t in range(T):
                    if first_on <= t <= last_on - (job.processing_time - 1):
                        obj += (cpmod.start_of(var, absentValue=-1)
                                == t) * instance.cumulative_energy_cost[t][
                                    t + job.processing_time -
                                    1] * instance.on_power_consumption
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 2:  # Element :
                energy = [
                    instance.cumulative_energy_cost[t][t +
                                                       job.processing_time -
                                                       1] *
                    instance.on_power_consumption if
                    (first_on <= t <= last_on -
                     (job.processing_time - 1)) else 0 for t in range(T)
                ]
                obj += cpmod.element(energy, cpmod.start_of(var))
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 3:  # Overlap :
                for t in range(T):  # add overlaps to objective
                    if first_on <= t <= last_on:
                        obj += cpmod.overlap_length(
                            var, (t, t + 1)) * instance.intervals[
                                t].energy_cost * instance.on_power_consumption
            elif self.specialized_solver_config[
                    "JobInObjectiveModelling"] == 4:  # Step function :
                obj += cpmod.start_eval(var, step_fns[job.processing_time])
            else:
                raise Exception(
                    "Given JobInObjectiveModelling method {0} is not supported."
                    .format(
                        self.
                        specialized_solver_config["JobInObjectiveModelling"]))

        # add variables for gaps ---------------------------------------------------------------------------------------
        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 0:  # Fixed :
            for t_s in range(1, T):
                for t_e in range(t_s + 1, T):
                    if instance.has_switching_cost(t_s, t_e):
                        if instance.get_gap_lower_bound(
                                t_s,
                                t_e) > ub:  # skip gaps that are too costly
                            continue

                        sw_cost = instance.optimal_switching_costs[t_s][t_e]

                        var = model.interval_var(start=t_s,
                                                 end=t_e,
                                                 optional=True,
                                                 name="gap[{:d},{:d}]".format(
                                                     t_s, t_e))
                        gap_vars[t_s, t_e] = var

                        seq_vars.append(var)
                        obj += cpmod.presence_of(
                            var
                        ) * sw_cost  # if the gap is present, add cost to objective
        elif self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 1:  # Free :
            gaps_by_lengths = {i: [] for i in range(1, T - 1)}
            for gap_len in range(1, T - total_proc - 1):
                costs = [
                    instance.optimal_switching_costs[t][t + gap_len]
                    if instance.optimal_switching_costs[t][t + gap_len]
                    is not None else
                    len(instance.intervals) * instance.on_power_consumption +
                    1  # TODO : max value
                    for t in range(T) if t + gap_len < T
                ]
                costs[0] = 0  # TODO: for absent value

                for i in range(int(T / gap_len)):
                    var = model.interval_var(optional=True,
                                             length=gap_len,
                                             name="gap[{:d},{:d}]".format(
                                                 gap_len, i))
                    model.add(cpmod.start_of(var, absentValue=1) >= 1)
                    model.add(cpmod.end_of(var) <= T - 1)
                    obj += cpmod.element(costs, cpmod.start_of(var))
                    gaps_by_lengths[gap_len].append(var)

                    seq_vars.append(var)

                # force order on the gaps
                for cur, nxt in zip(gaps_by_lengths[gap_len],
                                    gaps_by_lengths[gap_len][1:]):
                    model.add(cpmod.presence_of(cur) >= cpmod.presence_of(nxt))
                    model.add(cpmod.end_before_start(cur, nxt))
        elif self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 2:  # No :
            # Gaps will be added to the objective after introducing the sequence variable
            pass
        else:
            raise Exception(
                "Given GapsInObjectiveModelling method {0} is not supported.".
                format(self.
                       specialized_solver_config["GapsInObjectiveModelling"]))

        # add no overlap constraint ------------------------------------------------------------------------------------
        seq = model.sequence_var(seq_vars, name="seq")
        model.add(cpmod.no_overlap(seq))

        model.add(cpmod.first(seq, first_job_var))
        model.add(cpmod.last(seq, last_job_var))

        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] == 2:  # No :
            gap_costs = (
                [0 for _ in range(T)] +  # gap_len == 0
                [
                    instance.optimal_switching_costs[gap_s][gap_s + gap_len]
                    if gap_s + gap_len <= T - 1 and
                    instance.optimal_switching_costs[gap_s][gap_s + gap_len]
                    is not None else INT_MAX for gap_len in range(1, T)
                    for gap_s in range(T)
                ])

            for job in instance.jobs:
                job_var = self.job_vars[job]
                obj += cpmod.element(
                    gap_costs,
                    (cpmod.start_of_next(seq, job_var, T - 1) -
                     cpmod.end_of(job_var)) * T + cpmod.end_of(job_var))
            obj += cpmod.element(gap_costs,
                                 cpmod.start_of_next(seq, first_job_var) * T)

        # constrain lengths to fill the whole horizon ------------------------------------------------------------------
        if self.specialized_solver_config[
                "GapsInObjectiveModelling"] != 2:  # gaps are modelled
            if self.specialized_solver_config[
                    "FillAllModelling"] == 0:  # SumLengths :
                model.add(
                    sum([cpmod.length_of(var) for var in seq_vars]) == T - 2)
            elif self.specialized_solver_config[
                    "FillAllModelling"] == 1:  # Pulse :
                cumul_func = 0
                for var in seq_vars:
                    if var is not first_job_var and var is not last_job_var:
                        cumul_func += cpmod.pulse(var, 1)
                model.add(cpmod.always_in(cumul_func, (1, T - 1), 1, 1))
            elif self.specialized_solver_config[
                    "FillAllModelling"] == 2:  # StartOfNext :
                for var in seq_vars:
                    if var is not last_job_var:
                        model.add(
                            cpmod.start_of_next(
                                seq, var, lastValue=T, absentValue=0) ==
                            cpmod.end_of(var, absentValue=0))
            else:
                raise Exception(
                    "Given FillAllModelling method {0} is not supported.".
                    format(self.specialized_solver_config["FillAllModelling"]))

        # set objective
        model.minimize(obj)

        # - init start times.
        # if init_start_times is not None:
        #     for job in instance.jobs:
        #         stp.add_interval_var_solution(job_vars[job], presence=True, start=init_start_times[job])
        #
        #     # gaps in the schedule
        #     gaps = self.get_gaps_in_schedule(init_start_times)
        #
        #     for g_s, g_e in gaps:
        #         stp.add_interval_var_solution(gap_vars[g_s, g_e], presence=True, start=g_s)
        #
        #     # set starting point
        #     model.set_starting_point(stp)

        # force ordering of the jobs
        jobs_by_lengths = self.get_job_by_lengths()
        for lst in jobs_by_lengths.values():
            for j_cur, j_nxt in zip(lst, lst[1:]):
                model.add(
                    cpmod.end_before_start(job_vars[j_cur], job_vars[j_nxt]))
Example #21
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
Example #22
0
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per job operation
job_operations = [[
    mdl.interval_var(size=JOB_DURATIONS[j][m], name="J{}-M{}".format(j, m))
    for m in range(NB_MACHINES)
] for j in range(NB_JOBS)]

# Force each operation to start after the end of the previous
for j in range(NB_JOBS):
    for m in range(1, NB_MACHINES):
        mdl.add(
            mdl.end_before_start(job_operations[j][m - 1],
                                 job_operations[j][m]))

# Force no overlap for operations executed on a same machine
for m in range(NB_MACHINES):
    mdl.add(mdl.no_overlap([job_operations[j][m] for j in range(NB_JOBS)]))

# Minimize termination date
mdl.add(
    mdl.minimize(
        mdl.max([
            mdl.end_of(job_operations[i][NB_MACHINES - 1])
            for i in range(NB_JOBS)
        ])))

#-----------------------------------------------------------------------------
Example #23
0
    for task in TASKS:
        v = (0, MAX_SCHEDULE)
        tasks[(house, task)] = mdl.interval_var(v,
                                                v,
                                                size=task.duration,
                                                name="house {} task {}".format(
                                                    house, task))
    for task in SKILLS:
        wtasks[(house, task)] = mdl.interval_var(
            optional=True, name="house {} skill {}".format(house, task))

# Maximization objective of the model
obj2 = mdl.sum([
    s.level * mdl.presence_of(wtasks[(h, s)]) for s in SKILLS for h in HOUSES
])
mdl.add(mdl.maximize(obj2))

# Constraints of the model
for h in HOUSES:
    # Temporal constraints
    for p in TASK_PRECEDENCES:
        mdl.add(
            mdl.end_before_start(tasks[(h, find_tasks(p.beforeTask))],
                                 tasks[(h, find_tasks(p.afterTask))]))
    # Alternative workers
    for t in TASKS:
        mdl.add(
            mdl.alternative(
                tasks[(h, t)],
                [wtasks[(h, s)] for s in SKILLS if (s.task == t.name)], 1))
    # Continuity constraints
all_pins_list = []
for macro in macros:
	for term in macro.terms:
		all_pins_list.append(term)

for i in list(range(0, len(all_pins_list))):
	for j in list(range(i + 1, len(all_pins_list))):
		cpo_pinPitch = cplex_helpers.t2tDistance(mdl, all_pins_list[i], all_pins_list[j])
		mdl.add(cpo_pinPitch >= minPinPitch)
'''
new_index_list = []
for key, value in new_index_map.items():
    new_index_list.append(value)
for i in range(0, len(new_index_list)):
    for j in range(i + 1, len(new_index_list)):
        mdl.add(new_index_list[i] != new_index_list[j])
        #mdl.add(new_index_list[i] - new_index_list[j] > minPinPitch/pinMovement)

# maxPinPitch Constraints - save cpo_perturbation_list for objectives modeling
cpo_perturbation_list = []
for macro in macros:
    for term in macro.terms:
        cpo_perturbation = cplex_helpers.termPerturbation(mdl, term)
        cpo_perturbation_list.append(cpo_perturbation)
        if maxPerturbation != -1:
            mdl.add(cpo_perturbation < maxPerturbation)

# ----------------
# Add Objective
# ----------------
# Update terms info in all nets - because no initialization
Example #25
0

#-----------------------------------------------------------------------------
# Build the model
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()

# Create one interval variable per task
tasks = {t['id']: mdl.interval_var(name="T{}".format(t['id'])) for t in TASKS}

# Add precedence constraints
for t in TASKS:
    for s in t['successors']:
        mdl.add(mdl.end_before_start(tasks[t['id']], tasks[s]))

# Create one optional interval variable per task mode and add alternatives for tasks
modes = {}  # Map of all modes
for t in TASKS:
    tmds = [mdl.interval_var(name=m['id'], optional=True, size=m['duration']) for m in t['modes']]
    mdl.add(mdl.alternative(tasks[t['id']], tmds))
    for m in tmds:
        modes[m.name] = m

# Initialize pulse functions for renewable and non renewable resources
renewables = [mdl.pulse((0, 0), 0) for j in range(NB_RENEWABLE)]
non_renewables = [0 for j in range(NB_NON_RENEWABLE)]
for m in MODES:
    dren = m['demandRenewable']
    dnren = m['demandNonRenewable']
Example #26
0
def main():
    filename = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "data_in/test_1.txt")
    inst = instance.Instance(filename)

    # input from master problem, now random
    id_profile = 0
    random.seed(42)
    rewards = [random.randint(0, 30000) for i in range(inst.J)]
    #rewards = [random.uniform(0.0, 30000.0) for i in range(inst.J)]
    equivalences = [[0, 1], [2, 3]]
    mutexes = [[2, 1], [4, 3]]
    # input from master problem, now random

    types = inst.profiles[id_profile]
    types.insert(0, inst.INIT)
    types.append(inst.TERM)
    trans_cost = [[0 for i in range(inst.V)] for j in range(inst.V)]
    trans_time = [[0 for i in range(inst.V)] for j in range(inst.V)]
    for i in range(len(inst.edges)):
        for j in range(len(inst.edges[i])):
            trans_cost[i][inst.edges[i][j][
                'to']] = inst.edges[i][j]['C'] * inst.edges[i][j]['t']
            trans_time[i][inst.edges[i][j]['to']] = inst.edges[i][j]['t']
    changeover_cost = 0
    for i in range(1, len(types)):
        changeover_cost += trans_cost[types[i - 1]][types[i]]

    cp = CpoModel()
    primitives = [[] for i in range(inst.J)]
    all_primitives = []
    init = cp.interval_var(start=0)
    init.set_end_max(inst.L)
    total_cost = changeover_cost + inst.vertices[
        inst.INIT]['C'] * cp.length_of(init, 0)
    modes_of_mach = [init
                     ]  # serves only for retrieving starts and ends of modes
    last_shift = init
    for i in range(1, len(types) - 1):
        v = types[i]
        shift = cp.interval_var()
        shift.set_size_min(inst.vertices[v]['t_min'])
        shift.set_size_max(inst.vertices[v]['t_max'])
        shift.set_end_max(inst.L)
        total_cost += inst.vertices[v]['C'] * cp.length_of(shift, 0)
        cp.add(
            cp.start_at_end(shift, last_shift,
                            -trans_time[types[i - 1]][types[i]]))
        last_shift = shift
        modes_of_mach.append(shift)
        for t in range(inst.J):
            if inst.tasks[t]['p'][v] <= inst.L:
                prim = cp.interval_var(size=inst.tasks[t]['p'][v])
                total_cost -= rewards[t] * cp.presence_of(prim)
                prim.set_optional()
                prim.set_start_min(inst.tasks[t]['r'])
                prim.set_end_max(inst.tasks[t]['d'])
                primitives[t].append(prim)
                all_primitives.append(prim)
                cp.add(cp.start_before_start(shift, prim))
                cp.add(cp.end_before_end(prim, shift))
    term = cp.interval_var(end=inst.L)
    total_cost += inst.vertices[inst.TERM]['C'] * cp.length_of(term, 0)
    cp.add(
        cp.start_at_end(term, last_shift,
                        -trans_time[types[len(types) - 2]][inst.TERM]))
    modes_of_mach.append(term)
    cp.add(cp.no_overlap(cp.sequence_var(all_primitives)))
    for t in range(inst.J):
        cp.add(sum([cp.presence_of(p) for p in primitives[t]]) <= 1)
    for eq in equivalences:
        cp.add(
            sum([cp.presence_of(p) for p in primitives[eq[0]]]) == sum(
                [cp.presence_of(p) for p in primitives[eq[1]]]))
    for mut in mutexes:
        cp.add(
            sum([cp.presence_of(p) for p in primitives[mut[0]]]) +
            sum([cp.presence_of(p) for p in primitives[mut[1]]]) <= 1)
    cp.add(cp.minimize(total_cost))

    # set TimeLimit in seconds or delete it for no limit
    # parameters DefaultInferenceLevel and Workers may be beneficial to add
    sol = cp.solve(
        TimeLimit=30,
        LogVerbosity="Quiet")  #, DefaultInferenceLevel='Extended', Workers=1)
    if sol:
        tasks = []
        for t in range(inst.J):
            for pr in primitives[t]:
                p = sol.get_var_solution(pr)
                if p.is_present():
                    tasks.append({
                        "task": t,
                        "start": p.get_start(),
                        "end": p.get_end()
                    })
                    break
        modes = []
        sched_cost = 0
        for t in range(len(modes_of_mach)):
            m = sol.get_var_solution(modes_of_mach[t])
            modes.append({
                "mode": types[t],
                "start": m.get_start(),
                "end": m.get_end()
            })
            sched_cost += inst.vertices[types[t]]['C'] * m.get_length()
        print("Solution status: " + sol.get_solve_status())
        print("Solve time: " + str(sol.get_solve_time()))
        print("Objective: " + str(sol.get_objective_values()[0]))
        print("Schedule cost: " + str(sched_cost))
        print(tasks)
        print(modes)
    else:
        print("No solution found.")
Example #27
0
def fixed_resource_allocation_model(env: OnlineFlexibleResourceAllocationEnv,
                                    state: EnvState):
    """
    Generate the fixed resource allocation model and then solve it

    Args:
        env: Online Flexible Resource Allocation Env
        state: Environment state

    Returns: Cplex model
    """
    tasks = env._unallocated_tasks
    if state.auction_task:
        tasks.append(state.auction_task)
    fixed_tasks = convert_fixed_task(tasks)
    servers = list(state.server_tasks.keys())

    model = CpoModel('FixedEnv')

    server_task_allocation = {
        (server, task):
        model.binary_var(name=f'{server.name} server - {task.name} task')
        for server in servers for task in fixed_tasks
    }

    for task in fixed_tasks:
        model.add(
            sum(server_task_allocation[(server, task)]
                for server in servers) <= 1)

    for server in servers:
        for time in range(env._total_time_steps):
            time_tasks = [
                task for task in fixed_tasks
                if task.auction_time <= time <= task.deadline
            ]

            model.add(
                sum(
                    min(
                        task.required_storage,
                        task.fixed_loading_speed *
                        (time + 1 - task.auction_time)) *
                    server_task_allocation[(server, task)]
                    for task in time_tasks) <= server.storage_cap)
            model.add(
                sum(task.fixed_compute_speed *
                    server_task_allocation[(server, task)]
                    for task in time_tasks) <= server.computational_cap)
            model.add(
                sum((task.fixed_loading_speed + task.fixed_sending_speed) *
                    server_task_allocation[(server, task)]
                    for task in time_tasks) <= server.bandwidth_cap)

    model.maximize(
        sum(server_task_allocation[(server, task)] for server in servers
            for task in fixed_tasks))

    model_solution = model.solve(log_output=None, TimeLimit=150)
    total_tasks_completed = sum(
        model_solution.get_value(server_task_allocation[(server, task)])
        for server in servers for task in fixed_tasks)

    return total_tasks_completed
Example #28
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
Example #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
for b in Buses:
    print("buses with ", b[busSize], " seats cost ", b[busCost])

print()

for b in Buses:
    print("buses with ", b[busSize], " seats cost ", b[busCost])

mdl = CpoModel(name='buses')

#decision variables
mdl.nbBus = mdl.integer_var_dict(Buses, 0, maxquantity, name="nbBus")

# 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")

#Add a constraint
# Number of different quantity should be less than 1

mdl.add(
    mdl.sum(((mdl.count(mdl.nbBus.values(), q) >= 1)