Skip to main content

FreeLunch - Meta-heuristic optimisation suite for python

PyPICode Tests Benchmark Coverage

Please note the minor changes to the optimiser call signature since 0.0.11, details below.


About

Freelunch is a convenient python implementation of a number of meta-heuristic optimisation (with an 's') algorithms.


Features

Optimisers

Your favourite not in the list? Feel free to add it.

  • Differential evolution freelunch.DE
  • Simulated Annealing freelunch.SA
  • Particle Swarm freelunch.PSO
  • Krill Herd freelunch.KrillHerd
  • Self-adapting Differential Evolution freelunch.SADE
  • Quantum Particle Swarm freelunch.QPSO

--Coming soon to 0.1.0--

  • Quantum Bees
  • Grenade Explosion Method
  • The Penguin one

Benchmarking functions

Tier list: TBA

  • N-dimensional Ackley function
  • N-dimensional Periodic function
  • N-dimensional Happy Cat function
  • N-dimensional Exponential function

Install

Install with pip (req. numpy).

pip install freelunch

Usage

Create instances of your favourite meta-heuristics!

import freelunch
opt = freelunch.DE(my_objective_function, bounds=my_bounds) # Differential evolution

Where,

  • obj: objective function that excepts a single argument, the trial vector x, and returns float or None. i.e. obj(x) -> float or None

  • bounds: Iterable bounds for elements of x i.e. bounds [[lower, upper]]*len(sol) where: (sol[i] <= lower) -> bool and (sol[i] >= upper) -> bool.

Running the optimisation

Run by calling the instance. There are several different calling signatures. Use any combination of the arguments below to suit your needs!

To return the best solution only:

quick_result = opt() # (D,)

To return optimum after n_runs:

best_of_nruns = opt(n_runs=n) # (D,)

To return optimum after n_runs in parallel (uses multiprocessing.Pool), see note below.:

best_of_nruns = opt(n_runs=n, n_workers=w, pool_args={}, chunks=1) # (D,)

Return best m solutions in np.ndarray:

best_m = opt(n_return=m) # (D, m)

Return json friendly dict with fun metadata!

full_output = opt(full_output=True)
    # {
    #     'optimiser':'DE',
    #     'hypers':...,
    #     'bounds':...,
    #     'nruns':nruns,
    #     'nfe':1234,
    #     'solutions':[sol1, sol2, ..., solm*n_runs], # All solutions from all runs sorted by fitness
    #     'scores':[fit1, fit2, ..., fitm*n_runs]
    # }

Customisation

Want to change things around?

  • Change the initialisation strategy

Custom initialisation strategies can be supplied by altering the optimiser.initialiser attribute of any optimiser instance. For example:

opt = fr.DE(obj, ...)

def my_initialiser(bounds, N, **hypers):
    'Custom population initialisation'
    # Remember to return and interable of length N
    population = ... # custum logic
    return population

Additionally, some examples of common initialisation strategies can be found in the freelunch.tech module.

  • Change the bounding strategy

The simplest way to do this is to overwrite the optimiser.bounder attribute. There are a number of ready made strategies in freelunch.tech or alternatively define a custom method with the following call signature.

opt = fr.DE(obj, ...)

def my_bounder(p, bounds, **hypers):
    '''custom bounding method'''
    p.dna = ... # custom bounding logic

opt.bounder = my_bounder # overwrite the bounder attribute

# and then call as before
x_optimised = opt()
  • Changing the hyperparameters

Check out the hyperparameters and set your own, (defaults set automatically):

print(opt.hyper_definitions)
    # {
    #     'N':'Population size (int)',
    #     'G':'Number of generations (int)',
    #     'F':'Mutation parameter (float in [0,1])',
    #     'Cr':'Crossover probability (float in [0,1])'
    # }

print(opt.hyper_defaults)
    # {
    #     'N':100,
    #     'G':100,
    #     'F':0.5,
    #     'Cr':0.2
    # }

opt.hypers.update({'N':300})
print(opt.hypers)
    # {
    #     'N':300,
    #     'G':100,
    #     'F':0.5,
    #     'Cr':0.2
    # }

Benchmarks

Access from freelunch.benchmarks for example:

bench = freelunch.benchmarks.ackley(n=2) # Instanciate a 2D ackley benchmark function

fit = bench(sol) # evaluate by calling
bench.bounds # [[-10, 10],[-10, 10]]
bench.optimum # [0, 0] 
bench.f0 # 0.0

A note on running optimisations in parallel.

Because multiprocessing.Pool relies on multiprocessing.forking.pickle to send code to parallel processes, it is imperative that anything passed to the freelunch optimisers can be pickled. For example, the following common python pattern for producing an objective function with a single argument,

method = ... # some methods / args that are requred by the objective function
args = 

def wrap_my_obj(method, args):
    def _obj(x):
        return method(args, x)
    return _obj

obj = wrap_my_obj(method, args)

cannot be pickled because _obj is not importable from the top level module scope and will raise freelunch.util.UnpicklableObjectiveFunction . Instead consider using functools.partial i.e.

from functools import partial

method = ... # some methods / args that are requred by the objective function
args = ...


def _obj(method, args, x):
    return method(args, x)

obj = partial(_obj, method, args)

Metadata

Release files for freelunch 0.0.15

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

Source distribution (sdist)

Source distribution for freelunch 0.0.15
File Size Uploaded
freelunch-0.0.15.tar.gz 20.0 kB Details

Built distribution (wheel)

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

Total release size: 40.1 kB

Release files / freelunch-0.0.15.tar.gz

Download URL freelunch-0.0.15.tar.gz
Size 20.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d8557e7c5bdd2844a423370685f0bed20067c5a40d99a1236725c1932cdf9f47
BLAKE2b-256 checksum
How to use checksums
f459b3081f9ec4b0de4ea17f8ced3f3720e04b10e121a8fb70c1bda47533d286
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release files / freelunch-0.0.15-py3-none-any.whl

Download URL freelunch-0.0.15-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f771f81a3119c0aeba6cb61eee987464cb628beb1d0c5fb972ab599ee5c519d9
BLAKE2b-256 checksum
How to use checksums
5dea9e8565de33475bcbcda662f3806673c3443d2cc335e4240334bf41b3728f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.16

Release history Release notifications | RSS feed

This release

0.0.15 This release

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.9

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.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