Skip to main content

Deploy to GitHub Pages

Introduction

pycomocma is a Python implementation of COMO-CMA-ES which is a Multiobjective Evolution Strategy, based upon the Covariance Matrix Adaptation Evolution Strategy (CMA-ES) single optimizer.

For the time being, only the bi-objective case is tested and functional.

Installation

From PyPI via

python -m pip install comocma

or from GitHub, for example, via

python -m pip install git+https://github.com/CMA-ES/pycomocma.git@master

Links

Testing of the comocma module

The call

python -m comocma

runs the doc-tests from comocma.como and comocma.test (by calling comocma.test.main()).

Example code

import cma, comocma

### Settings
dimension = 10  # dimension of the search space
num_kernels = 5 # number of single-objective solvers
sigma0 = 0.2    # initial step-sizes

### Initialize
list_of_solvers = comocma.get_cmas(
        num_kernels * [dimension * [0]], sigma0) # return num_kernels cma instances
moes = comocma.Sofomore(list_of_solvers, [11,11]) # create a como-cma-es instance

fitness = comocma.FitFun(cma.ff.sphere, lambda x: cma.ff.sphere(x-1)) # a callable bi-objective function

### Do the job
moes.optimize(fitness)
print(moes.stop())
moes.logger.plot()

Output:

    Iterat #Fevals   Hypervolume   axis ratios   sigmas   min&max stds
                                      (median)  (median)    (median)
        1     10 1.210000000000000e+00 1.0e+00 2.00e-01  2e-01  2e-01
        2     20 1.210000000000000e+00 1.0e+00 2.00e-01  2e-01  2e-01
        3     30 1.210000000000000e+00 1.0e+00 1.85e-01  2e-01  2e-01
      100   1000 1.207601015381810e+00 1.6e+00 3.40e-02  3e-02  3e-02
      200   2000 1.209903687756354e+00 1.7e+00 7.74e-03  5e-03  6e-03
      300   3000 1.209997694077156e+00 1.8e+00 2.03e-03  1e-03  1e-03
      400   4000 1.209999800600613e+00 1.8e+00 4.90e-04  2e-04  3e-04
      480   4800 1.209999979594839e+00 1.9e+00 2.02e-04  7e-05  9e-05
    {0: {'tolx': 0.0001}, 1: {'tolx': 0.0001}, 2: {'tolx': 0.0001}, 3: {'tolx': 0.0001}, 4: {'tolx': 0.0001}}

[plots omitted]

Now,

moes.kernels[0].plot()

plots the optimization from "the first" kernel (the order of kernels is arbitrary) and

moes.kernels[0].result

contains the result of the first kernel.

Explanations step-by-step

Importing necessary packages:

import cma, comocma

Setting parameters:

dimension = 10  # dimension of the search space
num_kernels = 5 # number of single-objective solvers (number of points on the front)
sigma0 = 0.2    # initial step-sizes

Instantiate a multiobjective solver

list_of_solvers = comocma.get_cmas(num_kernels * [dimension * [0]], sigma0) # produce `num_kernels cma instances`
moes = comocma.Sofomore(list_of_solvers, reference_point=[11, 11]) # create a bi-objective como-cma-es instance
moes3 = comocma.Sofomore(list_of_solvers, reference_point=[11, 11, 11]) # create a multiobjective como-cma-es instance

Setting a callable multiobjective function

fitness = comocma.FitFun(cma.ff.sphere, lambda x: cma.ff.sphere(x-1)) # a callable bi-objective function
fitness3 = comocma.FitFun(cma.ff.sphere, lambda x: cma.ff.sphere(x-1), lambda x: cma.ff.sphere(x+1)) # a callable multiobjective function

More specific use cases

Example of single-objective options for CMA-ES

list_of_solvers = comocma.get_cmas(num_kernels * [dimension * [0]], 0.2, inopts={'bounds': [0.2, 0.9], 'tolx': 10**-7,'popsize': 32}) 
# produce `num_kernels cma instances`
moes = comocma.Sofomore(list_of_solvers, [1.1, 1.1]) # create a como-cma-es instance

Example of Multiobjective options

list_of_solvers = comocma.get_cmas(num_kernels * [dimension * [0]], 0.2)
moes = comocma.Sofomore(list_of_solvers, [1.1, 1.1], opts={'archive': True, 'restart': None, 'update_order': None}) # create a como-cma-es instance

The Optimize interface

Initialization

import cma, comocma

dimension = 10  # dimension of the search space
num_kernels = 5 # number of single-objective solvers (number of points on the front)
sigma0 = 0.2    # initial step-sizes

list_of_solvers = comocma.get_cmas(num_kernels * [dimension * [0]], sigma0) # produce `num_kernels cma instances`
moes = comocma.Sofomore(list_of_solvers, [11,11]) # create a como-cma-es instance

fitness = comocma.FitFun(cma.ff.sphere, lambda x: cma.ff.sphere(x-1)) # a callable bi-objective function

Optimizing fitness with a limited number of iterations

moes.optimize(fitness, iterations=300)
    Iterat #Fevals   Hypervolume   axis ratios   sigmas   min&max stds
                                    (median)  (median)    (median)
      1     10 1.100000000000000e+01 1.0e+00 2.00e-01  2e-01  2e-01
      2     20 2.158412269365152e+01 1.0e+00 2.00e-01  2e-01  2e-01
      3     30 2.896035267829712e+01 1.0e+00 1.98e-01  2e-01  2e-01
    100   1000 9.512982413314423e+01 1.7e+00 1.01e-01  8e-02  9e-02
    200   2000 9.703624875547615e+01 1.9e+00 4.27e-02  3e-02  4e-02
    300   3000 9.722958234416403e+01 1.9e+00 1.63e-02  9e-03  1e-02

Optimizing fitness with a maximum number of evaluations

moes.optimize(fitness, maxfun=3000)
    Iterat #Fevals   Hypervolume   axis ratios   sigmas   min&max stds
                                    (median)  (median)    (median)
      1     10 1.100000000000000e+01 1.0e+00 2.00e-01  2e-01  2e-01
      2     20 2.158412269365152e+01 1.0e+00 2.00e-01  2e-01  2e-01
      3     30 2.896035267829712e+01 1.0e+00 1.98e-01  2e-01  2e-01
    100   1000 9.512982413314423e+01 1.7e+00 1.01e-01  8e-02  9e-02
    200   2000 9.703624875547615e+01 1.9e+00 4.27e-02  3e-02  4e-02
    300   3000 9.722958234416403e+01 1.9e+00 1.63e-02  9e-03  1e-02

The ask-and-tell interface

while not moes.stop():
    solutions = moes.ask("all")
    objective_values = [fitness(x) for x in solutions]
    moes.tell(solutions, objective_values)
    moes.disp()          # display datas during the optimization
    moes.logger.add()    # logging data after each `ask` and `tell` call
    Iterat #Fevals   Hypervolume   axis ratios   sigmas   min&max stds
                                      (median)  (median)    (median)
        1    180 1.990425600000000e-01 1.0e+00 1.88e-01  2e-01  2e-01
        2    360 2.279075246432772e-01 1.1e+00 1.87e-01  2e-01  2e-01
        3    540 2.436105134581627e-01 1.2e+00 1.90e-01  2e-01  2e-01
      100  18000 3.607157703968831e-01 2.1e+00 1.80e-02  1e-02  2e-02
      200  35172 3.635275131024869e-01 2.1e+00 5.95e-03  4e-03  5e-03
      300  49788 3.637412031970786e-01 2.2e+00 1.29e-03  8e-04  1e-03
      320  50784 3.637421277015990e-01 2.2e+00 1.26e-03  7e-04  9e-04

Argument of moes.ask

solutions = moes.ask() # we generate offspring for only one kernel (sequential)
solutions = moes.ask("all") # we generate offspring simultaneously for all kernels (parallel)
solutions = moes.ask(number_asks) # we generate offspring for `number_asks` kernels

Picklable object: saving and resuming a MO optimization with the ask-and-tell interface

Initialization

import cma, como, pickle

dimension = 10  # dimension of the search space
num_kernels = 5 # number of single-objective solvers (number of points on the front)
sigma0 = 0.2    # initial step-sizes

list_of_solvers = como.get_cmas(num_kernels * [dimension * [0]], sigma0) # produce `num_kernels cma instances`
moes = como.Sofomore(list_of_solvers, reference_point = [11,11]) # create a como-cma-es instance

fitness = como.FitFun(cma.ff.sphere, lambda x: cma.ff.sphere(x-1)) # a callable bi-objective function

Saving an optimization

for i in range(100):
    solutions = moes.ask()
    objective_values = [fitness(x) for x in solutions]
    moes.tell(solutions, objective_values)
    moes.disp()

pickle.dump(moes, open('saved-mocma-object.pkl', 'wb')) # we save the instance
print('saved')
del moes  # deleting completely the Sofomore instance

Output

    Iterat #Fevals   Hypervolume   axis ratios   sigmas   min&max stds
                                      (median)  (median)    (median)
        1     10 1.100000000000000e+01 1.0e+00 2.00e-01  2e-01  2e-01
        2     20 2.845200549045931e+01 1.0e+00 2.00e-01  2e-01  2e-01
        3     30 3.440089785096067e+01 1.0e+00 2.00e-01  2e-01  2e-01
      100   1000 9.562953505152342e+01 1.9e+00 1.13e-01  9e-02  1e-01
    saved

Resuming an optimization

moes = pickle.load(open('saved-mocma-object.pkl', 'rb')) # we load the saved file here

moes.optimize(fitness, iterations=400)

Output

    200   2000 9.716644477685412e+01 1.9e+00 3.33e-02  2e-02  3e-02
    300   3000 9.723550009906029e+01 2.0e+00 1.13e-02  6e-03  8e-03
    400   4000 9.724067117112808e+01 1.9e+00 2.95e-03  1e-03  2e-03
    500   5000 9.724107479961819e+01 2.0e+00 9.38e-04  4e-04  5e-04

Example of plots

COMO-CMA-ES data plottings

moes.logger.plot_front()

image info

moes.logger.plot_divers()

image info

CMA-ES plots of written data

cma.plot("cma_kernels/0")

image info

Metadata

Release files for comocma 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for comocma 0.6.0
File Size Uploaded
comocma-0.6.0.tar.gz 44.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for comocma 0.6.0
File Interpreter ABI Platform
comocma-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 88.1 kB

Release files / comocma-0.6.0.tar.gz

Download URL comocma-0.6.0.tar.gz
Size 44.4 kB
Tags Source
SHA-256 checksum
How to use checksums
665d98d3ee8b5f3b49ad0e60dcddc087743babcfea3620e39c3b53c8b0143456
BLAKE2b-256 checksum
How to use checksums
893d3bf452e7e300e3b7b6f5315961b273a62ab73e8f97d5a12c1ad32f3ea9af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.18

Release files / comocma-0.6.0-py3-none-any.whl

Download URL comocma-0.6.0-py3-none-any.whl
Size 43.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0772d8d55f47e43247212de179c8f296e495fa6e5d2f661f15223f71b6504ad9
BLAKE2b-256 checksum
How to use checksums
9da36e1ce55702aa7bb47243a75110909b21a8a6824fcbf1bf115d67237ac554
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.18

Release history Release notifications | RSS feed

This release

0.6.0 This release

2 release files

0.5.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page