Пример #1
0
    def __init__(self, model, **kwargs):
        """ Constructor

        All necessary solving parameters are taken from the solving context that is constructed from the following list
        of sources, each one overwriting the previous:

           - the parameters that are set in the model itself,
           - the default solving context that is defined in the module :mod:`~docplex.cp.config`
           - the user-specific customizations of the context that may be defined (see :mod:`~docplex.cp.config` for details),
           - the optional arguments of this method.

        Args:
            context (Optional): Complete solving context.
                                If not given, solving context is the default one that is defined in the module
                                :mod:`~docplex.cp.config`.
            params (Optional):  Solving parameters (object of class :class:`~docplex.cp.parameters.CpoParameters`)
                                that overwrite those in the solving context.
            url (Optional):     URL of the DOcplexcloud service that overwrites the one defined in the solving context.
            key (Optional):     Authentication key of the DOcplexcloud service that overwrites the one defined in
                                the solving context.
            (param) (Optional): Any individual solving parameter as defined in class :class:`~docplex.cp.parameters.CpoParameters`
                               (for example *TimeLimit*, *Workers*, *SearchType*, etc).
            (others) (Optional): Any leaf attribute with the same name in the solving context
                                (for example *agent*, *trace_log*, *trace_cpo*, etc).
            (listeners) (Optional): List of solution listeners
        """
        super(CpoSolver, self).__init__()
        self.agent = None
        self.last_result = None
        self.status = STATUS_IDLE
        self.status_lock = threading.Lock()
        self.listeners = []

        # Build effective context from args
        context = config._get_effective_context(**kwargs)

        # If defined, limit the number of threads
        mxt = context.solver.max_threads
        if isinstance(mxt, int):
            # Maximize number of workers
            nbw = context.params.Workers
            if (nbw is None) or (nbw > mxt):
                context.params.Workers = mxt
                print("WARNING: Number of workers has been reduced to " + str(mxt) + " to comply with platform limitations.")

        # Save attributes
        self.model = model
        self.context = context

        # Determine appropriate solver agent
        self.agent = self._get_solver_agent()

        # Add solver listener for environment
        env = runenv.get_environment()
        if env is not None:
            self.add_listener(runenv.EnvSolverListener())
Пример #2
0
    def __init__(self, model, **kwargs):
        """ Create a new compiler

        Args:
            model:  Source model
        Optional args:
            context:             Global solving context. If not given, context is the default context that is set in config.py.
            params:              Solving parameters (CpoParameters) that overwrites those in solving context
            add_source_location: Add source location into generated text
            length_for_alias:    Minimum name length to use shorter alias instead
            (others):            All other context parameters that can be changed
        """
        super(CpoCompiler, self).__init__()

        # Build effective context
        if model:
            mparams = model.get_parameters()
            if mparams:
                pparams = kwargs.get('params')
                if pparams:
                    mparams = mparams.clone()
                    mparams.add(pparams)
                kwargs['params'] = mparams
        context = config._get_effective_context(**kwargs)

        # Initialize processing
        self.model = model
        self.parameters = context.params

        self.min_name_length_for_alias = None
        self.min_name_length_for_rename = None
        self.identifier_strings = {}
        self.rename_map = None

        # Set model parameters
        mctx = context.model
        if mctx is not None:
            ma = mctx.length_for_alias
            mr = mctx.length_for_rename
            if (mr is not None) and (ma is not None) and (ma >= mr):
                ma = None
            self.min_name_length_for_alias = ma
            self.min_name_length_for_rename = mr

        # Initialize source location
        if (self.parameters is not None) and (self.parameters.UseFileLocations
                                              is not None):
            self.add_source_location = (self.parameters.UseFileLocations
                                        in ('On', True))
        elif (mctx is not None) and (mctx.add_source_location is not None):
            self.add_source_location = mctx.add_source_location
        else:
            self.add_source_location = True
        self.last_location = None
Пример #3
0
    def __init__(self, model, **kwargs):
        """ Create a new compiler

        Args:
            model:  Source model
        Optional args:
            context:             Global solving context. If not given, context is the default context that is set in config.py.
            params:              Solving parameters (CpoParameters) that overwrites those in solving context
            add_source_location: Add source location into generated text
            length_for_alias:    Minimum name length to use shorter alias instead
            (others):            All other context parameters that can be changed
        """
        super(CpoCompiler, self).__init__()

        # Build effective context
        if model:
            mparams = model.get_parameters()
            if mparams:
                pparams = kwargs.get('params')
                if pparams:
                    mparams = mparams.clone()
                    mparams.add(pparams)
                kwargs['params'] = mparams
        context = config._get_effective_context(**kwargs)

        # Initialize processing
        self.model = model
        self.parameters = context.params

        self.min_length_for_alias = None
        self.id_printable_strings = {}
        self.name_all_constraints = False
        self.verbose_output = False
        self.factorize = True
        self.sort_names = 'none'

        # Set model parameters
        mctx = context.model
        if mctx is not None:
            self.min_length_for_alias = mctx.length_for_alias
            self.name_all_constraints = mctx.name_all_constraints
            self.verbose_output = not mctx.short_output
            self.factorize = mctx.factorize_expressions
            self.sort_names = str(mctx.sort_names).lower()

        # Determine CPO format version
        self.format_version = None if model is None else model.get_format_version(
        )
        if self.format_version is None:
            self.format_version = mctx.version

        # Determine output variant triggers
        if self.format_version is None:
            # Assume most recent solver
            self.is_format_less_than_12_8 = False
            self.is_format_at_least_12_8 = True
            self.is_format_at_least_12_9 = True
        else:
            self.is_format_less_than_12_8 = self.format_version and compare_natural(
                self.format_version, '12.8') < 0
            self.is_format_at_least_12_8 = self.format_version and compare_natural(
                self.format_version, '12.8') >= 0
            self.is_format_at_least_12_9 = self.format_version and compare_natural(
                self.format_version, '12.9') >= 0

        # Initialize source location
        if self.verbose_output:
            if (self.parameters
                    is not None) and (self.parameters.UseFileLocations
                                      is not None):
                self.add_source_location = (self.parameters.UseFileLocations
                                            in ('On', True))
            elif (mctx is not None) and (mctx.add_source_location is not None):
                self.add_source_location = mctx.add_source_location
            else:
                self.add_source_location = True
        else:
            self.add_source_location = False
        self.last_location = None

        # Initialize expression dictionaries
        self.expr_by_names = {}
        self.expr_infos = {}
        self.list_consts = []
        self.list_vars = []
        self.list_exprs = []
        self.list_phases = []
        self.alias_name_map = {}

        # Precompile model
        self._pre_compile_model()
def print_environment_report(out=None):
    """ Print a report on the docplex.cp execution environment

    Args:
        out:  (optional) Output stream, default is stdout
    """
    # Check output
    if out is None:
        out = sys.stdout
    out.write("Execution environment:\n")

    # Initialize warning list
    warnings = []
    msg = init.check_platform_system()
    if msg:
        warnings.append(msg)
    msg = init.check_python_version()
    if msg:
        warnings.append(msg)

    # Print context info
    out.write(" * System: {}, {}\n".format(platform.system(),
                                           platform.architecture()[0]))
    is_64bits = sys.maxsize > 2**32
    out.write(" * Python version: {}, {} ({})\n".format(
        platform.python_version(), "64 bits" if is_64bits else "32 bits",
        sys.executable))
    out.write(" * Docplex version: {}\n".format(
        version.docplex_version_string))

    # Print package info
    lpacks = ('numpy', 'panda', 'matplotlib')
    out.write(" * Optional packages: {}\n".format(", ".join(
        "{}: {}".format(p, utils.get_module_version(p)) for p in lpacks)))

    # Print solver info
    ctx = config._get_effective_context()
    agt = ctx.solver.agent
    out.write(" * Solver agent: {}".format(agt))
    if not agt:
        warnings.append("No solver agent is defined.")

    if agt == 'local':
        file = ctx.solver.local.execfile
        out.write(", executable file: '{}'".format(file))
        msg = _check_exec_file("Solver executable", file)
        if msg:
            warnings.append(msg)
    elif agt == 'lib':
        file = ctx.solver.lib.libfile
        out.write(", library file: {}".format(file))
        msg = _check_exec_file("Solver library", file)
        if msg:
            warnings.append(msg)
    out.write('\n')

    sver = solver.get_solver_version()
    out.write(" * Solver version: {}\n".format(sver))
    if sver is None and agt is not None:
        warnings.append(
            "Solver version is not accessible with agent '{}'.".format(agt))

    # Print warnings if any
    if warnings:
        out.write("Warnings:\n")
        for w in warnings:
            out.write(" * {}\n".format(w))
    else:
        out.write("No problem found.\n")
    def __init__(self, model, **kwargs):
        """ Constructor

        All necessary solving parameters are taken from the solving context that is constructed from the following list
        of sources, each one overwriting the previous:

           - the parameters that are set in the model itself,
           - the default solving context that is defined in the module :mod:`~docplex.cp.config`
           - the user-specific customizations of the context that may be defined (see :mod:`~docplex.cp.config` for details),
           - the optional arguments of this method.

        If an optional argument other than `context` or `params` is given to this method, it is searched in the
        context where its value is replaced by the new one.
        If not found, it is then considered as a solver parameter.
        In this case, only public parameters are allowed, except if the context attribute `solver.enable_undocumented_params`
        is set to True. This can be done directly when creating the solver, as for example:
        ::

            slvr = CpoSolver(mdl, enable_undocumented_params=True, MyPrivateParam=MyValue)

        Args:
            context (Optional): Complete solving context.
                                If not given, solving context is the default one that is defined in the module
                                :mod:`~docplex.cp.config`.
            params (Optional):  Solving parameters (object of class :class:`~docplex.cp.parameters.CpoParameters`)
                                that overwrite those in the solving context.
            (param) (Optional): Any individual solving parameter as defined in class :class:`~docplex.cp.parameters.CpoParameters`
                               (for example *TimeLimit*, *Workers*, *SearchType*, etc).
            (others) (Optional): Any leaf attribute with the same name in the solving context
                                (for example *agent*, *trace_log*, *trace_cpo*, etc).
            (listeners) (Optional): List of solution listeners
        """
        super(CpoSolver, self).__init__()
        self.agent = None
        self.last_result = None
        self.status = STATUS_IDLE
        self.status_lock = threading.Lock()
        self.listeners = []
        self.callbacks = []

        # Build effective context from args
        context = config._get_effective_context(**kwargs)

        # If defined, limit the number of threads
        mxt = context.solver.max_threads
        if isinstance(mxt, int):
            # Maximize number of workers
            nbw = context.params.Workers
            if (nbw is None) or (nbw > mxt):
                context.params.Workers = mxt
                print("WARNING: Number of workers has been reduced to " + str(mxt) + " to comply with platform limitations.")

        # Save attributes
        self.model = model
        self.context = context

        # Determine appropriate solver agent
        self.agent = self._get_solver_agent()

        # Add configured default listeners if any
        # Note: calling solver_created() is not required as it is done by add_listener().
        lstnrs = context.solver.listeners
        if lstnrs is not None:
            if is_array(lstnrs):
                for lstnr in lstnrs:
                    self._add_listener_from_class(lstnr)
            else:
                self._add_listener_from_class(lstnrs)