Exemplo n.º 1
0
    def get_solutions(
        self,
        num_solutions: int = 1,
        get_all_solutions: bool = False,
        selected_features: typing.Optional[typing.Tuple[str, int]] = None,
    ) -> typing.Optional[typing.Dict[str, int]]:
        instance = minizinc.Instance(self.solver, self.model)

        if selected_features:
            for feature_name, feature_value in selected_features:
                instance[feature_name] = feature_value

        if get_all_solutions:
            solutions = instance.solve(all_solutions=True).solution
        else:
            solutions = instance.solve(nr_solutions=num_solutions)

        if solutions:
            return [
                {
                    key: value
                    for key, value in solution.__dict__.items()
                    if key.startswith("feature")
                }
                for solution in solutions
            ]

        return None
Exemplo n.º 2
0
def check_solution(
    model: minizinc.Model,
    result: minizinc.Result,
    solver: minizinc.Solver,
    solution_nrs: Optional[Sequence[int]] = None,
) -> bool:
    """Checks a solution to for a model using a given solver.

    Check the correctness of the solving process using a (different) solver
    configuration. An instance is branched and will be assigned all
    available values from a solution. The solver configuration is now used
    to confirm is assignment of the variables is correct. By default only
    the last solution will be checked. A sequence of solution numbers can
    be provided to check multiple solutions.

    Args:
        model (Model): To model for which the solution was provided
        result (Result): The solution to be checked
        solver (Solver): The solver configuration used to check the
            solutions.
        solution_nrs: The index set of solutions to be checked. (default:
            ``-1``)

    Returns:
        bool: True if the given solution are correctly verified.

    """
    if solution_nrs is None:
        solution_nrs = [-1]

    instance = minizinc.Instance(solver, model)
    solutions = (
        result.solution if isinstance(result.solution, list) else [result.solution]
    )

    for i in solution_nrs:
        sol = solutions[i]
        with instance.branch() as child:
            for k, v in asdict(sol).items():
                if k not in ("objective", "__output_item"):
                    child[k] = v
            try:
                check = child.solve(timeout=timedelta(seconds=1))
                if result.status != check.status:
                    if check.status in [
                        minizinc.Status.SATISFIED,
                        minizinc.Status.OPTIMAL_SOLUTION,
                    ] and result.status in [
                        minizinc.Status.SATISFIED,
                        minizinc.Status.OPTIMAL_SOLUTION,
                        minizinc.Status.ALL_SOLUTIONS,
                    ]:
                        continue
                    else:
                        return False
            except minizinc.MiniZincError:
                if result.status != minizinc.Status.ERROR:
                    return False

    return True
Exemplo n.º 3
0
    def __init__(self, quantite_objectif, liste_gallons):

        # Create a MiniZinc model
        self.model = mnz.Model()
        self.model.add_file("ProjSceau.mzn")

        # Transform Model into a instance
        gecode = mnz.Solver.lookup("gecode")
        self.inst = mnz.Instance(gecode, self.model)

        self.gallons = liste_gallons
        self.quantite_objectif = quantite_objectif

        self.inst["nbr_sceau"] = len(liste_gallons)
        self.inst["remplissage_final"] = quantite_objectif

        list_taille_sceau = []
        list_remplissage_init = []
        for g in self.gallons:
            list_taille_sceau.append(g.taille)
            list_remplissage_init.append(g.remplissage)

        self.inst["taille_sceau"] = list_taille_sceau
        self.inst["remplissage_initial"] = list_remplissage_init

        print("CONFIGURATION d'ORIGINE:")
        print("\tnombre sceaux : ", self.inst["nbr_sceau"])
        print("\tremplissage_final : ", self.inst["remplissage_final"])
        print("\ttaille_sceau : ", self.inst["taille_sceau"])
        print("\tremplissage_initial : ", self.inst["remplissage_initial"])
Exemplo n.º 4
0
async def run_instance(problem, model, data, config, timeout, stat_base,
                       sol_file, stats_file):
    statistics = stat_base.copy()
    try:
        driver = minizinc.default_driver
        if config.minizinc is not None:
            driver = minizinc.CLI.CLIDriver(config.minizinc)
        instance = minizinc.Instance(config.solver, minizinc.Model(model),
                                     driver)
        if data is not None:
            instance.add_file(data, parse_data=False)
        is_satisfaction = instance.method == minizinc.Method.SATISFY

        for key, value in config.extra_data.items():
            instance[key] = value

        start = time.perf_counter()
        with sol_file.open(mode="w") as file:
            async for result in instance.solutions(
                    timeout=timeout,
                    processes=config.processes,
                    random_seed=config.random_seed,
                    intermediate_solutions=True,
                    free_search=config.free_search,
                    optimisation_level=config.optimisation_level,
                    **config.other_flags,
            ):
                solution = stat_base.copy()
                solution["status"] = str(result.status)
                if "time" in result.statistics:
                    solution["time"] = result.statistics.pop(
                        "time").total_seconds()
                if result.solution is not None:
                    solution["solution"] = asdict(result.solution)
                    solution["solution"].pop("_output_item", None)
                    solution["solution"].pop("_checker", None)
                file.write(ruamel.yaml.dump([solution]))

                statistics.update(result.statistics)
                statistics["status"] = str(result.status)
                if result.solution is not None and not is_satisfaction:
                    statistics["objective"] = result.solution.objective

        total_time = time.perf_counter() - start
        statistics["time"] = total_time
    except minizinc.MiniZincError as err:
        statistics["status"] = str(minizinc.result.Status.ERROR)
        statistics["error"] = str(err)

    for key, val in statistics.items():
        if isinstance(val, timedelta):
            statistics[key] = val.total_seconds()
    ruamel.yaml.dump(
        statistics,
        stats_file.open(mode="w"),
        default_flow_style=False,
    )
Exemplo n.º 5
0
 def minizinc_model():
     src = "float: a;\n" \
           "var float: x;\n" \
           "constraint x == a + 1;\n" \
           "solve satisfy"
     model = minizinc.Model()
     model.add_string(src)
     solver = minizinc.Solver.lookup("cbc")
     inst = minizinc.Instance(solver, model)
     inst["a"] = 2
     result = inst.solve()
     return result
Exemplo n.º 6
0
    def _solveOptimize(self, objstr:str, solver="gecode"):
        if not self.frozen:
            self.model.add_string(objstr)
            self.frozen = True

        gecode = mz.Solver.lookup(solver)
        instance = mz.Instance(gecode, self.model)
        for param, value in self.params.items():
            instance[param] = value
        result = instance.solve()
        if result.solution is None:
            return None
        return self.postprocessSolution(result.solution)
Exemplo n.º 7
0
def check_solution(
    model: minizinc.Model,
    solution: Union[DataClass, Dict[str, Any]],
    status: minizinc.Status,
    solver: minizinc.Solver,
) -> bool:
    """Checks a solution for a model using the given solver.

    Check the correctness of the solving process using a (different) solver
    configuration. A new  model instance is created and will be assigned all
    available values from the given solution. The Instance.solve() method is
    then used to ensure that the same solution with the same expected status is
    reached. Note that this method will not check the optimality of a solution.

    Args:
        model (Model): To model for which the solution was provided
        solution (Union[DataClass, Dict[str, Any]]): The solution to be checked
        status (Status): The expected (compatible) MiniZinc status
        solver (Solver): The solver configuration used to check the
            solution.

    Returns:
        bool: True if the given solution are correctly verified.

    """
    instance = minizinc.Instance(solver, model)
    if is_dataclass(solution):
        solution = asdict(solution)

    for k, v in solution.items():
        if k not in ("objective", "__output_item"):
            instance[k] = v
    try:
        check = instance.solve(timeout=timedelta(seconds=5))
        if status == check.status:
            return True
        elif check.status in [
                minizinc.Status.SATISFIED,
                minizinc.Status.OPTIMAL_SOLUTION,
        ] and status in [
                minizinc.Status.SATISFIED,
                minizinc.Status.OPTIMAL_SOLUTION,
                minizinc.Status.ALL_SOLUTIONS,
        ]:
            return True
        else:
            return False
    except minizinc.MiniZincError:
        if status == minizinc.Status.ERROR:
            return True
        return False
Exemplo n.º 8
0
 def minizinc_model():
     src = "int: a;\n" \
           "int: b;\n" \
           "var -100..100: x;\n" \
           "constraint a < x;\n" \
           "constraint x < b;\n" \
           "solve satisfy"
     model = minizinc.Model()
     model.add_string(src)
     gecode = minizinc.Solver.lookup("gecode")
     inst = minizinc.Instance(gecode, model)
     inst["a"] = 1
     inst["b"] = 4
     result = inst.solve(all_solutions=True)
     return result
Exemplo n.º 9
0
    def __init__(self, nombre_moutons):

        # Create a MiniZinc model
        self.model = mnz.Model()
        self.model.add_file("ProjSauteMouton.mzn")

        # Transform Model into a instance
        gecode = mnz.Solver.lookup("gecode")
        self.inst = mnz.Instance(gecode, self.model)

        self.nb_moutons = nombre_moutons
        self.inst["nbr_m"] = nombre_moutons

        self.moutons = []
        '''
Exemplo n.º 10
0
 def solver_exists(self, solver):
     solver_exists = pytest.solver_cache.get(solver, None)
     if solver_exists is None:
         try:
             s = mzn.Solver.lookup(solver)
             empty_model = mzn.Model()
             empty_model.add_string("solve satisfy;")
             instance = mzn.Instance(s, empty_model)
             instance.solve()
             solver_exists = True
         except (mzn.MiniZincError, LookupError) as error:
             solver_exists = False
         finally:
             pytest.solver_cache[solver] = solver_exists
     return solver_exists
Exemplo n.º 11
0
    def run(self, mzn_file, solver, default_options={}):
        """
        Runs this test case given an mzn file path, a solver name and some default options.

        Any options specified in this test case directly will override those provided in
        default options.

        Returns a tuple containing:
        - the model produced
        - the result of running the solver
        - a list of expected results
        - the actual obtained result

        Pass the actual obtained result to passed() to determine if the test case passed.
        """
        options = {k: v for k, v in default_options.items()}
        options.update(self.options)
        file = pathlib.Path(mzn_file)
        extra_files = [
            file.parent.joinpath(other) for other in self.extra_files
        ]

        try:
            model = mzn.Model([file] + extra_files)
            solver = mzn.Solver.lookup(solver)
            instance = mzn.Instance(solver, model)
            if self.type == "solve":
                instance.output_type = Solution
                result = instance.solve(**options)
                obtained = Result.from_mzn(result)
            elif self.type == "compile":
                with instance.flat(**options) as (fzn, ozn, stats):
                    obtained = FlatZinc.from_mzn(fzn, file.parent)
                    result = obtained
            elif self.type == "output-model":
                with instance.flat(**options) as (fzn, ozn, stats):
                    obtained = OutputModel.from_mzn(ozn, file.parent)
                    result = obtained
            else:
                raise NotImplementedError("Unknown test case type")
        except mzn.MiniZincError as error:
            result = error
            obtained = Error.from_mzn(result)

        required = self.expected if isinstance(self.expected,
                                               list) else [self.expected]

        return model, result, required, obtained
Exemplo n.º 12
0
 def minizinc_model():
     src = "int: a;\n" \
           "int: b;\n" \
           "int: c;\n" \
           "var -100..100: x;\n" \
           "constraint ((((a * pow(x, 2)) + (b * x)) + c) = 0);\n" \
           "solve satisfy"
     model = minizinc.Model()
     model.add_string(src)
     gecode = minizinc.Solver.lookup("gecode")
     inst = minizinc.Instance(gecode, model)
     inst["a"] = 1
     inst["b"] = 4
     inst["c"] = 0
     result = inst.solve(all_solutions=True)
     return result
Exemplo n.º 13
0
 def _solve(self, *how_to_solve, all_solutions, result_as, verbose, solver):
     solver = minizinc.Solver.lookup(solver)
     model = minizinc.Model()
     src = self.compile(how_to_solve)
     if verbose:
         print(src)
     model.add_string(src)
     inst = minizinc.Instance(solver, model)
     for name, param in self._ir.pars.items():
         inst[name] = param.value
     for e in self._ir.enums:
         inst[e.__name__] = e
     result: minizinc.Result = inst.solve(all_solutions=all_solutions)
     if result_as is None:
         return Result(result)
     else:
         return result_as(result)
Exemplo n.º 14
0
    def _model(self, model, solvername=None):
        import minizinc
        if solvername is None:
            # default solver
            solvername = "gecode"

        # from superclass
        mzn_txt = self.convert(model)

        # minizinc-python API
        # Create a MiniZinc model
        mznmodel = minizinc.Model()
        mznmodel.add_string(mzn_txt)

        # Transform Model into a instance
        slv = minizinc.Solver.lookup(solvername)
        return minizinc.Instance(slv, mznmodel)
Exemplo n.º 15
0
def schedule_evs(num_days,
                 num_periods_day,
                 peak_periods,
                 off_peak_periods,
                 num_evs,
                 max_charge,
                 total_energy,
                 prices_2d,
                 loads_2d,
                 network_tariff_peak,
                 network_tariff_off_peak,
                 model_file="scripts/ev-scheduling.mzn"):

    off_peak_periods2 = {i + 1 for i in off_peak_periods}.copy()
    if network_tariff_peak == network_tariff_off_peak:
        peak_periods2 = {i + 1 for i in range(num_periods_day)}.copy()
        network_tariff_off_peak = 0
    else:
        # minizinc index starts from 1
        peak_periods2 = {i + 1 for i in peak_periods}.copy()

    # build a MiniZinc model
    model = mzn.Model(model_file)
    solver = mzn.Solver.lookup("mip")
    ins = mzn.Instance(solver, model)
    ins["num_days"] = num_days
    ins["num_periods_day"] = num_periods_day
    ins["PEAK_PERIODS"] = peak_periods2
    ins["OFF_PEAK_PERIODS"] = off_peak_periods2
    ins["num_evs"] = num_evs
    ins["max_charge"] = max_charge
    ins["total_energy"] = total_energy
    ins["wholesale_prices"] = prices_2d
    ins["network_tariff_peak"] = network_tariff_peak
    ins["network_tariff_off_peak"] = network_tariff_off_peak
    ins["existing_loads"] = loads_2d
    result = ins.solve()

    # organise results
    charge_ev_day_period = result.solution.charge_strategy
    minizinc_outputs = ast.literal_eval(result.solution._output_item)
    minizinc_outputs["time (ms)"] = [
        result.statistics['solveTime'].microseconds * 0.001
    ]
    return charge_ev_day_period, minizinc_outputs
Exemplo n.º 16
0
def schedule_evs(num_days, prices_2d, loads_2d, network_tariff_peak,
                 network_tariff_off_peak):

    # build a MiniZinc model
    model = mzn.Model(model_file)
    solver = mzn.Solver.lookup("coin-bc")
    ins = mzn.Instance(solver, model)
    ins["num_days"] = num_days
    ins["num_periods_day"] = num_periods_day
    ins["num_evs"] = num_evs
    ins["max_charge"] = max_charge
    ins["total_energy"] = total_energy
    ins["wholesale_prices"] = prices_2d
    ins["network_tariff_peak"] = network_tariff_peak
    ins["network_tariff_off_peak"] = network_tariff_off_peak
    ins["existing_loads"] = loads_2d
    result = ins.solve()

    return result
Exemplo n.º 17
0
    def calcular(self, siCondicionesA):
        self.crearVarRegiones()
        self.kitsPorUnidad()
        self.Unidades()
        self.costosAdecuacion()
        
        if(siCondicionesA):
            self.condicionesAdicionales() 
        
        self.poblacion()
        self.noNegatividad()
        self.funcionObjetivo()
        
        # desde aca se resilve el codigo en minizinc, en alguna parte desde aca iria la funcion de parar en X minutos        
        
        # Create a MiniZinc model
        model = mz.Model()
        model.add_string(self.stringFinal)

        # Transform Model into a instance
        gecode = mz.Solver.lookup("gecode")
        inst = mz.Instance(gecode, model)

        # Solve the instance
        result = inst.solve()
        
        print("*************************   RESULTADOS MINIZINC   *************************")
        
        for regionX in self.listaDeRegiones:
            nombreRegionX = str(regionX.get_nombreCorto()) + " = "
            resultadoX = result[str(regionX.get_nombreCorto())]
            print(resultadoX)
            
            print(nombreRegionX, end = "")
            print(resultadoX)
            
            self.stringResultado = self.stringResultado + nombreRegionX + str(resultadoX) + "\n"

        self.stringResultado = self.stringResultado + "Beneficio = " + str(result["Beneficio"]) + "\n"
        
        print("Beneficio", end = " = ")
        print(result["Beneficio"])
        print("\n*************************   FIN DE PROGRAMA   *************************")
Exemplo n.º 18
0
    def solveSatisfy(self, timeout=None, numSolutions:int=0, solver="gecode"
                     ) -> list[solution_t]:
        if not self.frozen:
            self.model.add_string(f'solve satisfy;')
            self.frozen = True

        gecode = mz.Solver.lookup(solver)
        instance = mz.Instance(gecode, self.model)
        for param, value in self.params.items():
            instance[param] = value
        if numSolutions == 0 or numSolutions == "all":
            numSolutions = None
            allSolutions = True
        else:
            allSolutions = False
        result = instance.solve(nr_solutions=numSolutions, timeout=timeout, all_solutions=allSolutions)
        if result.solution is None:
            return []
        elif isinstance(result.solution, list):
            return [self.postprocessSolution(sol) for sol in result.solution]
        else:
            return [self.postprocessSolution(result.solution)]
Exemplo n.º 19
0
async def flatten(ctx, options: commands.Greedy[Option], *, arg: str):
    response = await ctx.send(random.choice(running_messages))
    await ctx.message.add_reaction("⌛")

    arg = arg.strip("` \t")

    arguments = {
        "solver": no_solver,
        "timeout": timedelta(seconds=30),
    }
    try:
        arguments = Option.process(options, arguments)
        instance = minizinc.Instance(arguments["solver"])
        instance.add_string(arg)
        with instance.flat(arguments["timeout"]) as (fzn, ozn, statistics):
            flatzinc = Path(fzn.name).read_text()
            output = f"```{flatzinc}```"
    except (OptionError, minizinc.MiniZincError) as err:
        output = "```" + str(err) + "```"

    await response.edit(content=output)
    await ctx.message.remove_reaction("⌛", bot.user)
    await ctx.message.add_reaction("✅")
Exemplo n.º 20
0
async def mzn(ctx, options: commands.Greedy[Option], *, arg: str):
    response = await ctx.send(random.choice(running_messages))
    await ctx.message.add_reaction("⌛")

    arg = arg.strip("` \t")

    arguments = {
        "solver": chuffed,
        "timeout": timedelta(seconds=30),
    }

    try:
        arguments = Option.process(options, arguments)
        instance = minizinc.Instance(arguments["solver"])
        instance.add_string(arg)
        result = await instance.solve_async(timeout=arguments["timeout"])
        output = f"`{result.status}` in {result.statistics['time'].total_seconds()}s: {'```' + str(result.solution) + '```' if result.solution is not None else 'No Solution'}"
    except (OptionError, minizinc.MiniZincError) as err:
        output = "```" + str(err) + "```"

    await response.edit(content=output)
    await ctx.message.remove_reaction("⌛", bot.user)
    await ctx.message.add_reaction("✅")
Exemplo n.º 21
0
 def __init__(self, model):
     self.mzn_instance = minizinc.Instance(solver, model)
     self.nogoods = []
     self.stayaway = []
     self.staynear = []
import minizinc

from minizinc import Model
print("Hi there, excited to run MZN")
# Create a MiniZinc model

basic_voting_model = Model("base_model.mzn")
gecode_solver = minizinc.Solver.lookup("gecode")

instance = minizinc.Instance(gecode_solver, basic_voting_model)
# set some parameters like this
# instance["a"] = 1

# now solve
result = instance.solve(all_solutions=True)
for i in range(len(result)):
    print("x = {}, y = {}".format(result[i, "x"], result[i, "y"]))
    print(result[i])
Exemplo n.º 23
0
def csp(blocks, sheets, matches):
    print('numblocks', len(blocks))
    blocks = blocks[:]
    model = minizinc.Model()
    model.add_string("""
    include "globals.mzn";

    int: num_blocks;
    int: num_rows;
    int: num_cols;
    set of int: b=1..num_blocks;
    set of int: rows=1..num_rows;
    set of int: cols=1..num_cols;
    array[b] of cols: x1;
    array[b] of cols: x2;
    array[b] of rows: y1;
    array[b] of rows: y2;
    array[b] of int: w;
    array[b] of int: h;
    array[rows] of var int: rowsa;
    array[cols] of var int: colsa;
    int: num_left;
    int: num_above;
    set of int: l=1..num_left;
    set of int: t=1..num_above;
    array[l] of cols: left1;
    array[l] of cols: left2;
    array[t] of rows: above1;
    array[t] of rows: above2;
    
    int: num_left_equal;
    int: num_above_equal;
    set of int: le=1..num_left_equal;
    set of int: te=1..num_above_equal;
    array[le] of cols: left_equal1;
    array[le] of cols: left_equal2;
    array[te] of rows: above_equal1;
    array[te] of rows: above_equal2;
    
    int: max_col = sum(w) + 1;
    int: max_row = sum(h) + 1;
        
    array[b] of var bool: use_block;
    array[b] of var int: wf;
    array[b] of var int: hf;
    constraint forall(bl in b) ((use_block[bl] -> wf[bl] = w[bl]) /\ 
                                (not use_block[bl] -> wf[bl] = 0));
    constraint forall(bl in b) ((use_block[bl] -> hf[bl] = h[bl]) /\ 
                                (not use_block[bl] -> hf[bl] = 0));
                                
    array[l] of var bool: use_left;
    array[t] of var bool: use_above;   
    array[le] of var bool: use_left_equal;                         
    array[te] of var bool: use_above_equal;                         

    constraint forall(c in cols) (colsa[c] > 0 /\ colsa[c] <= max_col);
    constraint forall(r in rows) (rowsa[r] > 0 /\ rowsa[r] <= max_row);

    constraint diffn([colsa[x1[bl]] | bl in b], 
                     [rowsa[y1[bl]] | bl in b],  
                     [wf[bl] | bl in b],
                     [hf[bl] | bl in b]);
    constraint forall(i in b) (colsa[x1[i]] + w[i] -1= colsa[x2[i]]);
    constraint forall(i in b) (rowsa[y1[i]] + h[i] -1= rowsa[y2[i]]);
    constraint forall(i in l) (use_left[i] <-> (colsa[left1[i]] < colsa[left2[i]]));
    constraint forall(i in t) (use_above[i] <-> (rowsa[above1[i]] < rowsa[above2[i]]));
    constraint forall(i in le) (use_left_equal[i] <-> (colsa[left_equal1[i]] = colsa[left_equal2[i]]));
    constraint forall(i in te) (use_above_equal[i] <-> (rowsa[above_equal1[i]] = rowsa[above_equal2[i]]));

    %solve satisfy;
    %solve minimize sum(rowsa) + sum(colsa);
    solve maximize sum(use_left) + sum(use_above) + sum(use_block) + sum(use_left_equal) + sum(use_above_equal);    
    """)

    cols = sorted(
        list(
            set(block.x1
                for block in blocks).union(set(block.x2 for block in blocks))))
    rows = sorted(
        list(
            set(block.y1
                for block in blocks).union(set(block.y2 for block in blocks))))
    relative_left, relative_left_equals = _parse_indices(cols, matches)
    relative_above, relative_above_equals = _parse_indices(rows, matches)
    colsi = {col: i + 1 for i, col in enumerate(cols)}
    rowsi = {row: i + 1 for i, row in enumerate(rows)}
    left, above = _location_constraints(cols, rows, sheets, matches)
    left = [(l1, l2)
            for l1, l2 in left if l1 in cols and l2 in cols] + relative_left
    above = [(a1, a2)
             for a1, a2 in above if a1 in rows and a2 in rows] + relative_above
    print('blocks', blocks)

    ProjectedBlock = collections.namedtuple('ProjectedBlock',
                                            'x1 y1 x2 y2 width height')
    pblocks = list(
        set(
            ProjectedBlock(block.x1, block.y1, block.x2, block.y2, block.width,
                           block.height) for block in blocks))
    for b in blocks:
        print(' ', b)
    print(len(blocks), len(pblocks))
    for b in pblocks:
        print('  ', b)
    print('pblocks', len(pblocks), pblocks)
    print('colsi', colsi)
    print('rowsi', rowsi)

    gecode = minizinc.Solver.lookup("chuffed")
    minst = minizinc.Instance(gecode, model)
    inst = {}
    inst['num_blocks'] = len(pblocks)
    inst['num_rows'] = len(rows)
    inst['num_cols'] = len(cols)
    inst['x1'] = [colsi[block.x1] for block in pblocks]
    inst['x2'] = [colsi[block.x2] for block in pblocks]
    inst['y1'] = [rowsi[block.y1] for block in pblocks]
    inst['y2'] = [rowsi[block.y2] for block in pblocks]
    inst['w'] = [block.width for block in pblocks]
    inst['h'] = [block.height for block in pblocks]
    inst['num_left'] = len(left)
    inst['num_above'] = len(above)
    inst['left1'] = [colsi[l1] for l1, _ in left]
    inst['left2'] = [colsi[l2] for _, l2 in left]
    inst['above1'] = [rowsi[a1] for a1, _ in above]
    inst['above2'] = [rowsi[a2] for _, a2 in above]
    inst['num_left_equal'] = len(relative_left_equals)
    inst['num_above_equal'] = len(relative_above_equals)
    inst['left_equal1'] = [colsi[l1] for l1, _ in relative_left_equals]
    inst['left_equal2'] = [colsi[l2] for _, l2 in relative_left_equals]
    inst['above_equal1'] = [rowsi[a1] for a1, _ in relative_above_equals]
    inst['above_equal2'] = [rowsi[a2] for _, a2 in relative_above_equals]

    print(inst)
    for k, v in inst.items():
        minst[k] = v
    # Solve the instance
    print('CSP')
    result = minst.solve(all_solutions=False)
    print('res', result)
    print(result['rowsa'])
    print(result['colsa'])
    assignment = {col: r for col, r in zip(cols, result['colsa'])}
    assignment.update(**{row: r for row, r in zip(rows, result['rowsa'])})
    used_blocks = {}
    for block, used in zip(pblocks, result['use_block']):
        used_blocks[block] = used
        print(used)
        if not used:
            print('Warning not used:', block)
            for oblock in blocks:
                if oblock.x1 == block.x1 and oblock.y1 == block.y1 and oblock.x2 == block.x2 and oblock.y2 == block.y2:
                    print('Original block:', oblock)

    print('assignment', assignment)
    return assignment
Exemplo n.º 24
0
def run_minizinc_model(params):
    mdl_name, instance_name, timeout = params

    instance_path = os.path.join(INSTANCE_FOLDER, instance_name)

    if not os.path.isfile(mdl_name):
        raise Exception("ERROR: mdl_name not found: ", mdl_name)

    if not os.path.isfile(instance_path):
        raise Exception("ERROR: instance_name not found: ", instance_name)

    print("*** Processing model {} with instance {}".format(mdl_name, instance_name))


    model = minizinc.Model([mdl_name])

    instance = minizinc.Instance(SOLVER, model)


    with open(instance_path, 'r') as f:
        input_data = json.load(f)
        scenesLength, actorsToScenes, actorsCosts = input_data['scenesLength'],input_data['actorsToScenes'], input_data['actorsCosts']


    num_scenes = len(scenesLength)
    num_actors = len(actorsCosts)
    if "1" in mdl_name:

        actorsToScenes_new = np.zeros((len(actorsCosts), len(scenesLength)))
        for actor, scenes in enumerate(actorsToScenes):
            actorsToScenes_new[actor, scenes] = 1


        data = {
            "num_scenes": len(scenesLength),
            "num_actors": len(actorsCosts),
            "max_cost": max(actorsCosts),
            "duration": scenesLength,
            "actor_cost": actorsCosts,
            "actorsToScenes": actorsToScenes_new.astype(int).tolist()
            }
    else:
        actorsToScenes_new = [set([i + 1 for i in scenes]) for scenes in actorsToScenes]
        data = {
            "num_scenes": len(scenesLength),
            "num_actors": len(actorsCosts),
            "max_cost": max(actorsCosts),
            "max_SceneDuration": max(scenesLength),
            "max_ActorCost":max(actorsCosts),
            "duration": scenesLength,
            "cost": actorsCosts,
            "actorsToScenes": actorsToScenes_new
            }


    for key, val in data.items():
        instance[key] = val

    msol = instance.solve(verbose=True, timeout=datetime.timedelta(seconds=timeout))


    # output= {
    #
    # }
    if msol:
        results = [
            msol.status.name,
            msol.solution.objective,
            msol.statistics['initTime'].total_seconds(),
            msol.statistics['solveTime'].total_seconds(),
            msol.statistics['variables']]
        if "1" in mdl_name:
            scene_order = msol['scene_order']
        else:
            scene_order = msol['order']
        success = True


    else:
        results = [msol.status.name if msol else "NOTFOUND"]
        success = False
        scene_order = None

    return success, mdl_name, instance_name, timeout, num_actors, num_scenes, scene_order, results
Exemplo n.º 25
0
def partial_schedule(volunteers, vehicle_request):
    # create an array of preferredHours
    preferred_hours = []
    for volunteer in volunteers:
        preferred_hours.append(volunteer["prefHours"])

    # generates a list of shift lengths corresponding to each vehicle request
    shift_lengths = generate_shift_lengths(vehicle_request)

    # generates a 2d array of booleans for the model
    # each entry denotes the compatability of 1 volunteer to 1 request
    compatible = generate_compatibility(volunteers, vehicle_request)

    # generates a 2d array of booleans for the model
    # each entry denotes whether there is a clash (true) between the corresponding vehicle requests
    clashing = generate_clashes(vehicle_request)

    # the following codeblock generates 3 lists of booleans
    # if is_heavy(index) = true then vehicle_request(index) is a heavy tanker
    # if is_medium(index) = true then vehicle_request(index) is a medium tanker
    # if is_light(index) = true then vehicle_request(index) is a light unit
    is_heavy = []
    is_medium = []
    is_light = []
    for request in vehicle_request:
        if request["assetClass"] == "heavyTanker":
            is_heavy.append(True)
            is_medium.append(False)
            is_light.append(False)
        if request["assetClass"] == "mediumTanker":
            is_heavy.append(False)
            is_medium.append(True)
            is_light.append(False)
        if request["assetClass"] == "lightUnit":
            is_heavy.append(False)
            is_medium.append(False)
            is_light.append(True)

    # the following codeblock generates 4 lists of booleans
    # if is_driver(index) = true then volunteer(index) is a driver
    # if is_crew_leader(index) = true then volunteer(index) is a crewleader
    # if is_advanced(index) = true then volunteer(index) is advanced
    # if is_basic(index) = true then volunteer(index) is basic
    is_driver = []
    is_crew_leader = []
    is_advanced = []
    is_basic = []
    for volunteer in volunteers:
        basic = False
        advanced = False
        crewLeader = False
        driver = False
        for qualification in volunteer["possibleRoles"]:
            if qualification == "basic":
                basic = True
            if qualification == "advanced":
                advanced = True
            if qualification == "crewLeader":
                crewLeader = True
            if qualification == "driver":
                driver = True
        is_basic.append(basic)
        is_advanced.append(advanced)
        is_crew_leader.append(crewLeader)
        is_driver.append(driver)

    # we are using the gecode optimiser
    gecode = minizinc.Solver.lookup("gecode")
    # create the model
    model = minizinc.Model()
    # the following string generates the minizinc model for a full solve
    model.add_string("""
        int: V;
        int: S;
        set of int: volunteers = 1..V;
        set of int: Shifts = 1..S;

        array[Shifts,volunteers] of bool: compatible;
        array[Shifts,Shifts] of bool: clashing;
        array[Shifts,volunteers] of var bool: assignments;
        array[volunteers] of int: preferredHours;
        array[Shifts] of int: shiftLength;

        array[Shifts] of bool: is_heavy;
        array[Shifts] of bool: is_medium;
        array[Shifts] of bool: is_light;

        array[volunteers] of bool: is_basic;
        array[volunteers] of bool: is_advanced;
        array[volunteers] of bool: is_crew_leader;
        array[volunteers] of bool: is_driver;

        array[Shifts] of var 0..V: seat1;
        array[Shifts] of var 0..V: seat2;
        array[Shifts] of var 0..V: seat3;
        array[Shifts] of var 0..V: seat4;
        array[Shifts] of var 0..V: seat5;

        array[volunteers,Shifts] of var int: hoursOnAssignment;
        array[volunteers] of var int: totalHours;

        %volunteer availability check
        constraint forall(s in Shifts)(forall(v in volunteers)(if compatible[s,v] == false then assignments[s,v] == false endif));

        %volunteers cannot be assigned to 2 shifts at once
        constraint forall(s1 in Shifts)(forall(s2 in Shifts)(forall(v in volunteers)(if clashing[s1,s2] /\ assignments[s1,v] then assignments[s2,v] == false endif)));

        %all vehicles are (at most) filled. This allows for partial fills
        constraint forall(s in Shifts)(if is_heavy[s] then sum(v in volunteers)(assignments[s,v]) <= 5 endif);
        constraint forall(s in Shifts)(if is_medium[s] then sum(v in volunteers)(assignments[s,v]) <= 3 endif);
        constraint forall(s in Shifts)(if is_light[s] then sum(v in volunteers)(assignments[s,v]) <= 2 endif);

        %Seat1 Requirements
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat1[s] == v then assignments[s,v] = true endif));
        constraint forall(s in Shifts)(forall(v in volunteers)(if seat1[s] == v then is_driver[v] = true endif));
        constraint forall(s in Shifts)(if is_light[s] then forall(v in volunteers)(if seat1[s] == v then is_crew_leader[v] = true endif) endif);

        %seat2 Requirements
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat2[s] == v then assignments[s,v] = true endif));
        constraint forall(s in Shifts)(if is_light[s] then forall(v in volunteers)(if seat2[s] == v then is_advanced[v] = true endif) endif);
        constraint forall(s in Shifts)(if is_medium[s] then forall(v in volunteers)(if seat2[s] == v then is_crew_leader[v] = true endif) endif);
        constraint forall(s in Shifts)(if is_heavy[s] then forall(v in volunteers)(if seat2[s] == v then is_crew_leader[v] = true endif) endif);

        %seat3 Requirements
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat3[s] == v then assignments[s,v] = true endif));
        constraint forall(s in Shifts)(if is_light[s] then seat3[s] == seat2[s] endif);
        constraint forall(s in Shifts)(if is_medium[s] then forall(v in volunteers)(if seat3[s] == v then is_basic[v] = true endif) endif);
        constraint forall(s in Shifts)(if is_heavy[s] then forall(v in volunteers)(if seat3[s] == v then is_advanced[v] = true endif) endif);

        %seat4 Requirements
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat4[s] == v then assignments[s,v] = true endif));
        constraint forall(s in Shifts)(if is_light[s] then seat4[s] == seat2[s] endif);
        constraint forall(s in Shifts)(if is_medium[s] then seat4[s] == seat3[s] endif);
        constraint forall(s in Shifts)(if is_heavy[s] then forall(v in volunteers)(if seat4[s] == v then is_advanced[v] = true endif) endif);

        %seat5 Requirements
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat5[s] == v then assignments[s,v] = true endif));
        constraint forall(s in Shifts)(if is_light[s] then seat5[s] == seat2[s] endif);
        constraint forall(s in Shifts)(if is_medium[s] then seat5[s] == seat3[s] endif);
        constraint forall(s in Shifts)(if is_heavy[s] then forall(v in volunteers)(if seat5[s] == v then is_basic[v] = true endif) endif);

        %if a volunteer is not on any seats of a shift, they are not on the shift
        constraint forall(s in Shifts)(forall(v in volunteers) (if seat5[s] != v /\ seat4[s] != v /\ seat3[s] != v /\ seat2[s] != v /\ seat1[s] != v then assignments[s,v] = false endif));


        %maps shifts to hours worked
        constraint forall(v in volunteers)(forall(s in Shifts)(if assignments[s,v] then hoursOnAssignment[v,s] = shiftLength[s] else hoursOnAssignment[v,s] = 0 endif));

        %defines total hours for each volunteer
        constraint forall(v in volunteers)(totalHours[v] == sum(s in Shifts)(hoursOnAssignment[v,s]));

        %ensures no one is overworked
        constraint forall(v in volunteers)(totalHours[v] <= preferredHours[v]);

        %maximise for number of volunteers assigned
        solve maximize sum(s in Shifts)(sum(v in volunteers)(assignments[s,v]))
        """)
    # initialise all the variables in the minizinc model from the variables we previously created
    instance = minizinc.Instance(gecode, model)
    instance["V"] = len(volunteers)
    instance["S"] = len(vehicle_request)
    instance["preferredHours"] = preferred_hours
    instance["shiftLength"] = shift_lengths
    instance["compatible"] = compatible
    instance["clashing"] = clashing
    instance["is_heavy"] = is_heavy
    instance["is_medium"] = is_medium
    instance["is_light"] = is_light
    instance["is_basic"] = is_basic
    instance["is_advanced"] = is_advanced
    instance["is_crew_leader"] = is_crew_leader
    instance["is_driver"] = is_driver
    # solve the model
    result = instance.solve()
    # if there is a valid solution, format it and output
    if result.solution:
        output = []
        for i in range(len(vehicle_request)):
            vehicle_dict = {}
            vehicle_dict["shiftID"] = vehicle_request[i]["shiftID"]
            vehicle_dict["assetClass"] = vehicle_request[i]["assetClass"]
            vehicle_dict["timeframe"] = vehicle_request[i]["timeframe"]
            seats = []
            seats.append(result["seat1"])
            seats.append(result["seat2"])
            seats.append(result["seat3"])
            seats.append(result["seat4"])
            seats.append(result["seat5"])
            if vehicle_dict["assetClass"] == "lightUnit":
                volunteers = add_light_unit_to_output(seats, i, volunteers)
            if vehicle_dict["assetClass"] == "mediumTanker":
                volunteers = add_medium_tanker_to_output(seats, i, volunteers)
            if vehicle_dict["assetClass"] == "heavyTanker":
                volunteers = add_heavy_tanker_to_output(seats, i, volunteers)
            vehicle_dict["volunteers"] = volunteers
            output.append(vehicle_dict)
    # if there is no valid model, output an empty list
    else:
        print("No partial fill possible")
        output = []
    return output
Exemplo n.º 26
0
model_file = "rect_packing.mzn"

import minizinc
from minizinc import Model, Status

square_packing_model = Model(model_file)
solver = minizinc.Solver.lookup("chuffed")

# number of squares we want to pack

widths = [5, 6, 4, 3, 2, 4, 3, 1, 2, 1, 7, 3]
heights = [1, 2, 3, 2, 1, 2, 4, 6, 5, 1, 1, 2]
n = len(widths)

inst = minizinc.Instance(solver, square_packing_model)
inst["n"] = n
inst["widths"] = widths
inst["heights"] = heights
inst.add_string("constraint sq_width > sq_height;")
inst.add_string("constraint sq_width >= 10;")
inst.add_string("constraint sq_height >= 10;")
result = inst.solve()

# coordinates
pos_x = []
curr_x = 0
for i in range(1, n + 1):
    pos_x.append(curr_x)
    curr_x += widths[i - 1]
Exemplo n.º 27
0
            [1, 0, 1, 0, 0], [1, 1, 0, 0, 0]]

lastT = 14
nTasks = 3
dur = [[5, 2, 3], [4, 5, 1], [3, 4, 2]]
nMachines = 3
taskToMach = [[1, 2, 3], [2, 1, 3], [2, 3, 1]]
# prettier output for slots
datetime_object = datetime.datetime.strptime('14:00', '%H:%M')
date_list = [
    datetime_object + datetime.timedelta(minutes=15 * x)
    for x in range(0, nSlots)
]
print_dates = [d.strftime('%H:%M') for d in date_list]

inst = minizinc.Instance(solver, model)

inst["nOptions"] = nOptions
inst["nCarConfigs"] = nCarConfigs
inst["nTasks"] = nTasks
inst["at_most"] = at_most
inst["per_slots"] = per_slots
inst["demand"] = demand
inst["requires"] = requires

# for example, first slot should be a config 1
#inst.add_string("constraint line[1] = 3;")
result = inst.solve()

if result.status == Status.SATISFIED or result.status == Status.OPTIMAL_SOLUTION:
    print("sounds good")