discrete_optimization.generic_tools.study package

Submodules

discrete_optimization.generic_tools.study.config module

class discrete_optimization.generic_tools.study.config.ConfigStore[source]

Bases: object

Store experiments config and mapping to their names

add(config: dict[str, DictConfig] | Hashable) None[source]

Add a config to the store.

Ensure bijection between names and configs. If name already given, use it. If not, construct it from solver parameters. If 2 names given in different occurences raise an error. If 2 different config share the same name, raise an error.

get_configs(name: str) list[dict[str, dict[str, DictConfig] | Hashable] | Hashable][source]
get_name(config: dict[str, DictConfig] | Hashable) str[source]
discrete_optimization.generic_tools.study.config.convert_config_dict2hashable(config: dict[str, DictConfig] | Hashable) tuple[str, HashableConfig] | Hashable[source]
discrete_optimization.generic_tools.study.config.convert_config_hashable2dict(config: tuple[str, HashableConfig] | Hashable) dict[str, DictConfig] | Hashable[source]
discrete_optimization.generic_tools.study.config.get_config_name(config: dict[str, DictConfig] | Hashable) str[source]
discrete_optimization.generic_tools.study.config.is_tupleddict(config: Any) bool[source]

discrete_optimization.generic_tools.study.database module

class discrete_optimization.generic_tools.study.database.Database[source]

Bases: ABC

Base class for database storing experiments.

By default, we assume a database is associated with a given study. But it could be implemented so that it can store several studies at once.

d-o experiments: - instance => string representing problem used - config:

  • name: can be empty, but useful to have a simple name for the config

  • solver: e.g. class name

  • params: hyperparameters used (nested dict whose leaves should be hashable, and preferably jsonable)

  • status: status of tge solver at then of the solve process

  • metrics: timeseries of objective, bound, …

close() None[source]

Close the database.

abstractmethod get_new_experiment_id() int[source]
abstractmethod load() list[Experiment][source]

Load all experiments of the study.

load_metadata() list[dict[str, dict[str, ConfigDict | Hashable] | Hashable]][source]

Load all experiments metadata with added field ‘metrics_length’.

load_results() list[DataFrame][source]

Load all experiments as time-indexes dataframes with metadata in attrs attribute.

abstractmethod store(xp: Experiment) None[source]

Store the experiment in the database.

Could store a complete experiment. Depending on implementations, could also support storing a partial experiment, and then overwriting with a complete experiment by re-calling store on an experiment with same id and more data.

class discrete_optimization.generic_tools.study.database.Hdf5Database(filepath: str)[source]

Bases: Database

Database based on hdf5 format.

close() None[source]

Close the database.

get_new_experiment_id() int[source]
load() list[Experiment][source]

Load all experiments of the study.

load_metadata() list[dict[str, dict[str, ConfigDict | Hashable] | Hashable]][source]

Load all experiments metadata with added field ‘metrics_length’.

store(xp: Experiment) None[source]

Store the experiment in the database.

Could store a complete experiment. Depending on implementations, could also support storing a partial experiment, and then overwriting with a complete experiment by re-calling store on an experiment with same id and more data.

store_metadata(xp: Experiment) None[source]
store_metrics(xp: Experiment) None[source]
discrete_optimization.generic_tools.study.database.is_empty_metrics(df: DataFrame) bool[source]

Return True is a dataframe has no data or only NaN’s.

discrete_optimization.generic_tools.study.experiment module

class discrete_optimization.generic_tools.study.experiment.DoJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: JSONEncoder

default(o)[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return super().default(o)
class discrete_optimization.generic_tools.study.experiment.Experiment(xp_id: int, instance: str, status: str, config: SolverJsonableConfig, metrics: DataFrame, reason: str = '')[source]

Bases: object

Experiment of a d-o study.

config: SolverJsonableConfig
classmethod from_solver_config(xp_id: int, instance: str, status: str | StatusSolver, solver_config: SolverConfig, metrics: DataFrame, config_name: str | None = None, reason: str = '')[source]
get_metadata_as_a_record() dict[str, Any][source]
get_metadata_as_nested_dict() dict[str, ConfigDict | Hashable][source]
instance: str
metrics: DataFrame
reason: str = ''
status: str
to_df()[source]

Convert to a dataframe (metrics) with metadata store in attrs attribute.

xp_id: int
class discrete_optimization.generic_tools.study.experiment.SolverConfig(cls: 'type[SolverDO]', kwargs: 'dict[str, Any]')[source]

Bases: object

cls: type[SolverDO]
kwargs: dict[str, Any]
class discrete_optimization.generic_tools.study.experiment.SolverJsonableConfig(solver: str, parameters: dict[str, ConfigDict | Hashable], name: str | None = None)[source]

Bases: object

Config representing solver used with its tuning.

as_nested_dict() dict[str, ConfigDict | Hashable][source]
classmethod from_record(record)[source]
classmethod from_solver_config(config: SolverConfig, name: str | None = None)[source]
classmethod from_xp_metadata_record(record)[source]
get_json_parameters() str[source]

Jsonify the config parameters attribute.

get_record() dict[str, str | None][source]
name: str | None = None
parameters: dict[str, ConfigDict | Hashable]
solver: str

discrete_optimization.generic_tools.study.study module

class discrete_optimization.generic_tools.study.study.Study(name: str, instances: list[str], solver_configs: dict[str, SolverConfig], problem_factory: Callable[[str], Problem], overwrite: bool = False, max_retry: int = 0, database_filepath: str | None = None, solver_factory: Callable[[Problem, SolverConfig], SolverDO] | None = None)[source]

Bases: Iterable[tuple[Problem, SolverDO, dict[str, Any]]]

Small wrapper to manage d-o studies

  • loop over instance x config

  • manage mapping instance_name <-> instance, config_name <-> config

  • allow warmstart from previous run, with skip of successful experiments

  • automatic retry of unsuccessful experiments

Manage database to store experiment. For now, use Hdf5Database with default path beigin <study_name>.h5

To loop over a study, do:

```python for problem, solver, solver_kwargs in study:

… # solve solver.solve(…, **solver_kwargs)

# retrieve metrics metrics = …

study.store_current_xp(metrics, …)

```

get_current_config_name() str[source]
get_current_instance() str[source]
load_metadatas()[source]

Load and normalize metadatas

store_current_xp(metrics: DataFrame, status: str | StatusSolver, reason: str = '', success: bool | None = None)[source]
Parameters:
  • metrics

  • status

  • reason

  • success

Returns:

discrete_optimization.generic_tools.study.study.normalize_config(config: Any, config_store: ConfigStore) str[source]
discrete_optimization.generic_tools.study.study.normalize_metadata(metadata: dict[str, Any], config_store: ConfigStore, n_runs_by_config_instance: dict[tuple[str, str], int]) None[source]
discrete_optimization.generic_tools.study.study.normalize_metadatas(metadatas: list[dict[str, Any]], config_store: ConfigStore) list[dict[str, Any]][source]

Module contents

class discrete_optimization.generic_tools.study.Experiment(xp_id: int, instance: str, status: str, config: SolverJsonableConfig, metrics: DataFrame, reason: str = '')[source]

Bases: object

Experiment of a d-o study.

config: SolverJsonableConfig
classmethod from_solver_config(xp_id: int, instance: str, status: str | StatusSolver, solver_config: SolverConfig, metrics: DataFrame, config_name: str | None = None, reason: str = '')[source]
get_metadata_as_a_record() dict[str, Any][source]
get_metadata_as_nested_dict() dict[str, ConfigDict | Hashable][source]
instance: str
metrics: DataFrame
reason: str = ''
status: str
to_df()[source]

Convert to a dataframe (metrics) with metadata store in attrs attribute.

xp_id: int
class discrete_optimization.generic_tools.study.Hdf5Database(filepath: str)[source]

Bases: Database

Database based on hdf5 format.

close() None[source]

Close the database.

get_new_experiment_id() int[source]
load() list[Experiment][source]

Load all experiments of the study.

load_metadata() list[dict[str, dict[str, ConfigDict | Hashable] | Hashable]][source]

Load all experiments metadata with added field ‘metrics_length’.

store(xp: Experiment) None[source]

Store the experiment in the database.

Could store a complete experiment. Depending on implementations, could also support storing a partial experiment, and then overwriting with a complete experiment by re-calling store on an experiment with same id and more data.

store_metadata(xp: Experiment) None[source]
store_metrics(xp: Experiment) None[source]
class discrete_optimization.generic_tools.study.SolverConfig(cls: 'type[SolverDO]', kwargs: 'dict[str, Any]')[source]

Bases: object

cls: type[SolverDO]
kwargs: dict[str, Any]
class discrete_optimization.generic_tools.study.Study(name: str, instances: list[str], solver_configs: dict[str, SolverConfig], problem_factory: Callable[[str], Problem], overwrite: bool = False, max_retry: int = 0, database_filepath: str | None = None, solver_factory: Callable[[Problem, SolverConfig], SolverDO] | None = None)[source]

Bases: Iterable[tuple[Problem, SolverDO, dict[str, Any]]]

Small wrapper to manage d-o studies

  • loop over instance x config

  • manage mapping instance_name <-> instance, config_name <-> config

  • allow warmstart from previous run, with skip of successful experiments

  • automatic retry of unsuccessful experiments

Manage database to store experiment. For now, use Hdf5Database with default path beigin <study_name>.h5

To loop over a study, do:

```python for problem, solver, solver_kwargs in study:

… # solve solver.solve(…, **solver_kwargs)

# retrieve metrics metrics = …

study.store_current_xp(metrics, …)

```

get_current_config_name() str[source]
get_current_instance() str[source]
load_metadatas()[source]

Load and normalize metadatas

store_current_xp(metrics: DataFrame, status: str | StatusSolver, reason: str = '', success: bool | None = None)[source]
Parameters:
  • metrics

  • status

  • reason

  • success

Returns: