예제 #1
0
 def __init__(self, fp_listCplexParameters, fp_obInstance):
     '''
     @fp_listCplexParameters: [0:iCandidateFaciNum, 1:fAlpha]
     '''
     self.iCandidateFaciNum = fp_listCplexParameters[0]
     self.fAlpha = fp_listCplexParameters[1]
     self.obInstance = fp_obInstance
     self.model = Model()
     self.cpomodel = CpoModel()
    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)
예제 #3
0
def get_version_info():
    """ If the solver agent defined in the configuration enables this function,
    this method returns solver version information.

    This method creates a CP solver to retrieve this information, and end it immediately.
    It returns a dictionary with various information, as in the following example:
    ::
    {
       "AngelVersion" : 5,  # Or 'DllVersion' for Dll
       "SourceDate" : "Sep 12 2017",
       "SolverVersion" : "12.8.0.0",
       "IntMin" : -9007199254740991,
       "IntMax" : 9007199254740991,
       "IntervalMin" : -4503599627370494,
       "IntervalMax" : 4503599627370494,
    }

    Returns:
        Solver information dictionary, or None if not available.
    """
    from docplex.cp.model import CpoModel
    try:
        with CpoSolver(CpoModel()) as slvr:
            return slvr.agent.version_info
    except:
        pass
    return None
예제 #4
0
    def __init__(self, mdl=None):
        """ Create a new CPO format parser

        Args:
            mdl:  Model to fill, None (default) to create a new one.
        """
        super(CpoParser, self).__init__()
        self.model = mdl if mdl is not None else CpoModel()
        self.expr_dict = {}
        self.source_file = None
        self.tokenizer = None
        self.token = None
        self.pushtoken = None
        self.current_loc = None

        # Do not store location information (would store parser instead of real lines)
        self.model.source_loc = False

        # Initialize special function handlers
        self.fun_handlers = {
            'intVar': self._read_fun_intVar,
            '_intVar': self._read_fun_intVar,
            'boolVar': self._read_fun_boolVar,
            '_boolVar': self._read_fun_boolVar,
            'floatVar': self._read_fun_floatVar,
            '_floatVar': self._read_fun_floatVar,
            'intervalVar': self._read_fun_intervalVar,
            'sequenceVar': self._read_fun_sequenceVar,
            'stateFunction': self._read_fun_stateFunction,
            'stepFunction': self._read_fun_stepFunction,
            'segmentedFunction': self._read_fun_segmentedFunction,
            'transitionMatrix': self._read_fun_transitionMatrix,
        }
예제 #5
0
def get_solver_info():
    """ Get the information data of the local CP solver that is target by the solver configuration.

    This method creates a CP solver to retrieve this information, and end it immediately.
    It returns a dictionary with various information, as in the following example:
    ::
    {
       "AngelVersion" : 5,
       "SourceDate" : "Sep 12 2017",
       "SolverVersion" : "12.8.0.0",
       "IntMin" : -9007199254740991,
       "IntMax" : 9007199254740991,
       "IntervalMin" : -4503599627370494,
       "IntervalMax" : 4503599627370494,
       "AvailableCommands" : ["Exit", "SetCpoModel", "SolveModel", "StartSearch", "SearchNext", "EndSearch", "RefineConflict", "Propagate", "RunSeeds"]
    }

    Returns:
        Solver information dictionary, or None if not available.
    """
    try:
        with solver.CpoSolver(CpoModel()) as slvr:
            if isinstance(slvr.agent, CpoSolverLocal):
                return slvr.agent.version_info
    except:
        pass
    return None
예제 #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
예제 #7
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
예제 #8
0
    def __init__(self, mdl=None):
        """ Create a new CPO format parser

        Args:
            mdl:  Model to fill, None (default) to create a new one.
        """
        super(CpoParser, self).__init__()
        self.model = mdl if mdl is not None else CpoModel()
        self.source_file = None
        self.tokenizer = None
        self.token = None
        self.pushtoken = None

        # Do not store location information (would store parser instead of real lines)
        self.model.source_loc = False
예제 #9
0
# Build the model
#-----------------------------------------------------------------------------


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)
예제 #10
0
The masonry, roofing, painting, etc.  must be scheduled.
Some tasks must necessarily take place before others, and these requirements are
expressed through precedence constraints.

Please refer to documentation for appropriate setup of solving configuration.
"""

from docplex.cp.model import CpoModel
import docplex.cp.utils_visu as visu

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

# 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))
# Number of marks on the ruler
ORDER = 8

#-----------------------------------------------------------------------------
# Prepare the data for modeling
#-----------------------------------------------------------------------------

# 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]))
예제 #12
0
])

# Initialize demand of each customer
demand = list([data.popleft() for c in range(nbCustomer)])

# Initialize fixed cost of each location
fixedCost = list([data.popleft() for p in range(nbLocation)])

# Initialize capacity of each location
capacity = list([data.popleft() for p in range(nbLocation)])

#-----------------------------------------------------------------------------
# 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):
예제 #13
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
예제 #14
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
예제 #15
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]))
예제 #16
0
NB_TASKS = len(TASKS)

# Create a unique id for each mode (to retrieve results)
MODES = []
for t in TASKS:
   for i, m in enumerate(t['modes']):
       m['id'] = "T{}-M{}".format(t['id'], i + 1)
       MODES.append(m)


#-----------------------------------------------------------------------------
# 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:
# Create macro point lists
for macro in macros:
    #helpers.createMacroPositionList(macro, pinMovement, minPinPitch)
    helpers.createMacroPositionList(macro, minPinPitch, minPinPitch)
'''
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:
예제 #18
0
                      [1,1,0,1,1,1,0,1,0],
                      [1,1,0,0,0,0,1,1,0],
                      [1,0,0,0,1,1,0,0,1],
                      [0,0,1,0,1,1,1,1,0]]
compositions_players=[[1,1,1,1,0],
                      [1,1,1,0,0],
                      [0,0,0,0,1],
                      [1,1,0,0,0],
                      [0,1,0,1,1],
                      [1,1,0,1,1],
                      [1,0,1,0,1],
                      [0,1,1,0,1],
                      [1,0,0,1,0]]
waittimes=[2,4,1,3,3,2,5,7,6]

mdl = CpoModel()

numplayers=5
numcompositions=9
def sumcol(ind,mtrx,numcols):
    return sum([mtrx[i][ind] for i in range(numplayers)])
def checksymmetries(mtrx, numcols):
    sum_col = []
    checked_cur = []
    checked = []
    ind_col = []
    for i in range(numcols):
        pr = sumcol(i,mtrx,numcols)
        try:
            ind = sum_col.index(pr)
        except:
maxquantity = 10

# Indexes

busSize = 0
busCost = 1

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")
예제 #20
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
예제 #21
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.")
예제 #22
0
# The rest of the file consists of one line per job that contains the list of
# operations given as durations for each machines.

filename = os.path.dirname(
    os.path.abspath(__file__)) + "/data/flowshop_default.data"
with open(filename, "r") as file:
    NB_JOBS, NB_MACHINES = [int(v) for v in file.readline().split()]
    JOB_DURATIONS = [[int(v) for v in file.readline().split()]
                     for i in range(NB_JOBS)]

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

# 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
예제 #23
0
#-----------------------------------------------------------------------------
# Prepare the data for modeling
#-----------------------------------------------------------------------------

# Assign an index to tasks
ALL_TASKS = (MASONRY, CARPENTRY, PLUMBING, CEILING, ROOFING, PAINTING, WINDOWS,
             FACADE, GARDEN, MOVING)
for i in range(len(ALL_TASKS)):
    ALL_TASKS[i].id = i

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

# Create model
mdl = CpoModel()

# Initialize model variable sets
all_tasks = []  # Array of all tasks
desc = dict()  # Dictionary task interval var -> task descriptor
house = dict()  # Dictionary task interval var -> id of the corresponding house
workers_usage = mdl.step_at(0, 0)  # Total worker usage

# Initialize cash function
cash = mdl.step_at(0, 0)
for p in range(NB_PAYMENTS):
    cash += mdl.step_at(PAYMENT_INTERVAL * p, PAYMENT_AMOUNT)


# Utility function
def make_house(loc, rd):
예제 #24
0
"""

 In Constraint Programming decision variables have to be integer but sometimes we need more than this.

Let's see how we can handle through decision expressions.

Suppose in the bus example we want to book not only whole buses but also percentage of buses.

Then we can write

"""

from docplex.cp.model import CpoModel

mdl = CpoModel(name='buses')

#now suppose we can book a % of buses not only complete buses

scale = 100
scalenbbus40 = mdl.integer_var(0, 1000, name='scalenbBus40')
scalenbbus30 = mdl.integer_var(0, 1000, name='scalenbBus30')

nbbus40 = scalenbbus40 / scale
nbbus30 = scalenbbus30 / scale

mdl.add(nbbus40 * 40 + nbbus30 * 30 >= 310)
mdl.minimize(nbbus40 * 500 + nbbus30 * 400)

msol = mdl.solve()

print(msol[scalenbbus40] / scale, " buses 40 seats")
예제 #25
0
Moreover, there are earliness and tardiness costs associated with some tasks.
The objective is to minimize these costs.

Please refer to documentation for appropriate setup of solving configuration.
"""

from docplex.cp.model import CpoModel, CpoSegmentedFunction
import docplex.cp.utils_visu as visu

#-----------------------------------------------------------------------------
# Initialize the problem data
#-----------------------------------------------------------------------------

# Create model
mdl = CpoModel()


# House building task descriptor
class BuildingTask(object):
    def __init__(self,
                 name,
                 duration,
                 release_date=None,
                 due_date=None,
                 earliness_cost=None,
                 tardiness_cost=None):
        self.name = name
        self.duration = duration
        self.release_date = release_date
        self.due_date = due_date
#===============INITIALIZE DATA===============   
#items        
items = []
for i in range(0,len(items_data)):
    items.append(Item(i, items_data[i]))
#bins
bins = []
for i in range(len(bins_data)):
    bins.append(Bin(i, bins_data[i]))
    
#add a new bin at the end of the list, big enough to accommodate ALL items
#needed so that all items can be allocated, CPO won't return any solution if an item unallocated    
bins.append(Bin(nb_bins, sum(items_data)))

#===============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===============   
예제 #27
0
# Data

Buses = [(40, 500), (30, 400)]

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()
예제 #28
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
예제 #29
0
def find_skills(worker, task):
    return next(s for s in SKILLS if (s.worker == worker) and (s.task == task))


# Iterator on houses numbers
HOUSES = range(1, NB_HOUSES + 1)

# Build the list of all worker names
WORKERS = set(sk.worker for sk in SKILLS)

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

# Create model
mdl = CpoModel()

# Variables of the model
tasks = {}  # dict of interval variable for each house and task
wtasks = {}  # dict of interval variable for each house and skill
for house in HOUSES:
    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))