Git Product home page Git Product logo

iraikov / dmosopt Goto Github PK

View Code? Open in Web Editor NEW
4.0 4.0 3.0 1.04 MB

Distributed surrogate-assisted evolutionary methods for multi-objective optimization of high-dimensional dynamical systems

License: GNU General Public License v3.0

Python 99.97% Makefile 0.03%
distributed distributed-computing evolutionary-algorithms cmaes nsga2 optimization python smpso evolution-strategies gaussian-processes gpflow gpytorch mpi mpi-applications mpi4py trust-region

dmosopt's Introduction

dmosopt

Distributed surrogate based multi-objective optimization.

Documentation

Quick start example

import sys, logging
import numpy as np
from dmosopt import dmosopt
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def zdt1(x):
    ''' This is the Zitzler-Deb-Thiele Function - type A
        Bound: XUB = [1,1,...]; XLB = [0,0,...]
        dim = 30
    '''
    num_variables = len(x)
    f = np.zeros(2)
    f[0] = x[0]
    g = 1. + 9./float(num_variables-1)*np.sum(x[1:])
    h = 1. - np.sqrt(f[0]/g)
    f[1] = g*h
    return f


def obj_fun(pp):
    """ Objective function to be minimized. """
    param_values = np.asarray([pp[k] for k in sorted(pp)])
    res = zdt1(param_values)
    logger.info(f"Iter: \t pp:{pp}, result:{res}")
    return res


def zdt1_pareto(n_points=100):
    f = np.zeros([n_points,2])
    f[:,0] = np.linspace(0,1,n_points)
    f[:,1] = 1.0 - np.sqrt(f[:,0])
    return f

if __name__ == '__main__':
    space = {}
    for i in range(30):
        space['x%d' % (i+1)] = [0.0, 1.0]
    problem_parameters = {}
    objective_names = ['y1', 'y2']
    
    # Create an optimizer
    dmosopt_params = {'opt_id': 'dmosopt_zdt1',
                      'obj_fun_name': 'example_dmosopt_zdt1.obj_fun',
                      'problem_parameters': problem_parameters,
                      'space': space,
                      'objective_names': objective_names,
                      'population_size': 200,
                      'num_generations': 200,
                      'initial_maxiter': 10,
                      'optimizer': 'nsga2',
                      'termination_conditions': True,
                      'n_initial': 3,
                      'n_epochs': 2}
    
    best = dmosopt.run(dmosopt_params, verbose=True)
    if best is not None:
        import matplotlib.pyplot as plt
        bestx, besty = best
        x, y = dmosopt.sopt_dict['dmosopt_zdt1'].optimizer_dict[0].get_evals()
        besty_dict = dict(besty)
        
        # plot results
        plt.plot(y[:,0],y[:,1],'b.',label='evaluated points')
        plt.plot(besty_dict['y1'],besty_dict['y2'],'r.',label='best points')
    
        y_true = zdt1_pareto()
        plt.plot(y_true[:,0],y_true[:,1],'k-',label='True Pareto')
        plt.legend()
        
        plt.savefig("example_dmosopt_zdt1.svg")

Acknowledgements

dmosopt is based on MO-ASMO as described in the following paper:

Gong, W., Q. Duan, J. Li, C. Wang, Z. Di, A. Ye, C. Miao, and Y. Dai (2016), Multiobjective adaptive surrogate modeling-based optimization for parameter estimation of large, complex geophysical models, Water Resour. Res., 52(3), 1984-2008. doi:10.1002/2015WR018230.

dmosopt's People

Contributors

frthjf avatar iraikov avatar pmoolchand avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

dmosopt's Issues

Record EO algorithm parameters for each epoch

The ability to perform per-epoch sensitivity analysis and dispersion index computation means that the EO algorithm parameters will differ from to epoch. We need some general way to record the parameters of the EO algorithm used for each epoch.

Probabilities do not sum to 1 in tournament selection

The tournament selection routine creates a vector of probabilities for each candidate solution, and then uses random.choice to select candidates for the MOEA pool selection. However, it does not ensure the probabilities sum to 1, which occasionally leads to errors.

Trust-region optimizer

This feature will add a simple multi-objective trust region optimizer, which can be used as a local optimizer after an epoch with a global optimizer.

Broken constraint handling

After the recent refactorings, constraint handling is not applied after initial sampling epoch, but is applied when loading saved evaluations.

Non-surrogate optimization fails with KeyError

Example debug.py script to reproduce:

import logging
import numpy as np
from dmosopt import dmosopt

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def zdt1(x):
    num_variables = len(x)
    f = np.zeros(2)
    f[0] = x[0]
    g = 1.0 + 9.0 / float(num_variables - 1) * np.sum(x[1:])
    h = 1.0 - np.sqrt(f[0] / g)
    f[1] = g * h
    return f


def obj_fun(pp):
    param_values = np.asarray([pp[k] for k in sorted(pp)])
    res = zdt1(param_values)
    logger.info(f"Iter: \t pp:{pp}, result:{res}")
    return res


def zdt1_pareto(n_points=100):
    f = np.zeros([n_points, 2])
    f[:, 0] = np.linspace(0, 1, n_points)
    f[:, 1] = 1.0 - np.sqrt(f[:, 0])
    return f


if __name__ == "__main__":
    space = {}
    for i in range(30):
        space["x%d" % (i + 1)] = [0.0, 1.0]
    problem_parameters = {}
    objective_names = ["y1", "y2"]
    dmosopt_params = {
        "opt_id": "dmosopt_zdt1",
        "obj_fun_name": "debug.obj_fun",
        "problem_parameters": problem_parameters,
        "space": space,
        "objective_names": objective_names,
        "population_size": 50,
        "num_generations": 25,
        "initial_maxiter": 10,
        "optimizer_name": "age",
        "termination_conditions": True,
        "n_initial": 3,
        "n_epochs": 4,
        "surrogate_method_name": None,
        "save": True,
        "file_path": "zdt1.h5",
    }

    dmosopt.run(dmosopt_params, verbose=True)
Traceback (most recent call last):
  File "./MultiObjectiveSurrogateOptimization/debug.py", line 64, in <module>
    dmosopt.run(dmosopt_params, verbose=True)
  File "./dmosopt/dmosopt/dmosopt.py", line 1975, in run
    distwq.run(
  File "/scratch1/08818/fg14/venvs/multiobjectivesurrogateoptimization-py3.9-scratch/lib/python3.9/site-packages/distwq.py", line 2071, in run
    fun(controller, *args)
  File "./dmosopt/dmosopt/dmosopt.py", line 1944, in dopt_ctrl
    dopt.run_epoch()
  File "./dmosopt/dmosopt/dmosopt.py", line 1137, in run_epoch
    strategy_state, strategy_value, completed_evals = self.optimizer_dict[
  File "./dmosopt/dmosopt/dmosopt.py", line 357, in update_epoch
    x_resample = result_dict["x_resample"]
KeyError: 'x_resample'

More precise time estimates

A more accurate implementation of the time limit functionality should include 1) GP model train time measurements and estimates 2) elapsed time and time limit in MOEA optimizer..

Support for using several optimization method in a sequence

This feature will add support for using different optimization methods in successive epochs, i.e. NSGA in epoch 1, followed by a local optimization method in epoch 2, then followed by NSGA again and so on. It will require modifying the various optimizer_method arguments to take an iterable of optimizer method names.

Alllow GP interface to return prediction variance

Currently, the predict methods in the Gaussian Process interface module only return the mean at the requested points. However, the variance is also necessary to estimate the uncertainty at those points.

Use pythonic configuration for optimizers to allow for user extensions

Currently, the user can specify the objective and initialization methods by simply providing a Python module and object name. However, the optimizer and sampling strategies are hardcoded.

I wonder if it would make sense to change the semantics of the optimizer and sampling_method setting to refer to a Python object instead. For example, "optimizer": "nsga2" would become "optimizer": "dmosopt.NSGA2:NSGA2" etc. In this example, I've used the entry point notation, but for consistency, it might make more to add a optimizer_module option instead.

This would allow users to extend and develop custom strategies by simply pointing to the module. To maintain backward compatibility we could simply keep the current behavior but fall back on importing if the user provides an 'unknown' option.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.