Skip to main content

pyVolutionary is a package collecting metaheuristic algorithms, available for free usage and able to solve a wide range of optimization problems.

Project description

pyVolutionary

GitHub release PyPI - Python Version PyPI - Status PyPI - Downloads GitHub Release Date GitTutorial License: MIT

Introduction

pyVolutionary

pyVolutionary stands as a versatile Python library dedicated to metaheuristic algorithms within the realm of evolutionary computation. Engineered for ease of use, flexibility, and speed, it exhibits robustness and efficiency, having undergone rigorous testing on large-scale problem instances. The primary objectives encompass the implementation of both classical and cutting-edge nature-inspired algorithms. The library is conceived as a user-friendly resource facilitating rapid access to optimization algorithms for researchers, fostering the dissemination of optimization knowledge to a broad audience without financial barriers.

Nature-inspired algorithms constitute a widely embraced tool for addressing optimization challenges. Over the course of their evolution, a plethora of variants have emerged (paper 1, paper 2), showcasing their adaptability and versatility across diverse domains and applications. Noteworthy advancements have been achieved through hybridization, modification, and adaptation of these algorithms. However, the implementation of nature-inspired algorithms can often pose a formidable challenge, characterized by complexity and tedium. pyVolutionary is specifically crafted to surmount this challenge, offering a streamlined and expedited approach to leveraging these algorithms without the need for arduous, time-consuming implementations from scratch.

The list of algorithms currently implemented in pyVolutionary can be consulted in the Algorithms section. The library is continuously updated with new algorithms and problems, and contributions are welcome.

Installation

pyVolutionary is available on PyPI, and can be installed via pip:

pip install pyvolutionary

Usage

Once installed, pyVolutionary can be imported into your Python scripts as follows:

import pyvolutionary

Now, you can access the algorithms and problems included in the library. For example, let us inspect how you can solve the sphere problem with the Particle Swarm Optimization algorithm.

from pyvolutionary import ContinuousVariable, ParticleSwarmOptimization, ParticleSwarmOptimizationConfig, Task

# Define the problem, you can replace the following class with your custom problem to optimize
class Sphere(Task):
    def objective_function(self, x: list[float]) -> float:
        x1, x2 = x
        f1 = x1 - 2 * x2 + 3
        f2 = 2 * x1 + x2 - 8
        return f1 ** 2 + f2 ** 2


# Define the task with the bounds and the configuration of the optimizer
population = 200
dimension = 2
position_min = -100.0
position_max = 100.0
generation = 400
fitness_error = 10e-4
task = Sphere(
    variables=[ContinuousVariable(
        name=f"x{i}", lower_bound=position_min, upper_bound=position_max
    ) for i in range(dimension)],
)

configuration = ParticleSwarmOptimizationConfig(
    population_size=population,
    fitness_error=fitness_error,
    max_cycles=generation,
    c1=0.1,
    c2=0.1,
    w=[0.35, 1],
)
optimization_result = ParticleSwarmOptimization(configuration).optimize(task)

You can pass the minmax parameter to the Task class to specify whether you want to minimize or maximize the function. Therefore, if you want to maximize the function, you can write:

task = Sphere(
    variables=[ContinuousVariable(
        name=f"x{i}", lower_bound=position_min, upper_bound=position_max
    ) for i in range(dimension)],
    minmax="max",
)

optimization_result = ParticleSwarmOptimization(configuration).optimize(task)

By default, the minmax parameter is set to min.

You can also specify the mode of the solver by using the mode argument of the optimize method. For instance, if you want to run the Particle Swarm Optimization algorithm in parallel with threads, you can write:

optimization_result = ParticleSwarmOptimization(configuration).optimize(task, mode="thread")

The possible values of the mode parameter are:

  • serial: the algorithm is run in serial mode;
  • process: the algorithm is run in parallel with processes;
  • thread: the algorithm is run in parallel with threads.

In case of process and thread modes, you can also specify the number of processes or threads to use by using the n_jobs argument of the optimize method:

optimization_result = ParticleSwarmOptimization(configuration).optimize(task, mode="thread", jobs=4)

Finally, you can also specify the seed of the random number generator by using the seed parameter of the definition of the Task:

task = Sphere(
    variables=[ContinuousVariable(
        name=f"x{i}", lower_bound=position_min, upper_bound=position_max
    ) for i in range(dimension)],
    minmax="max",
    seed=42,
)

optimization_result = ParticleSwarmOptimization(configuration).optimize(task)

The optimization result is a dictionary containing the following keys:

  • evolution: a list of the agents found at each generation
  • rates: a list of the fitness values of the agents found at each generation
  • best_solution: the best agent found by the algorithm

Explicitly, the evolution key contains a list of Population, i.e. a dictionary which agents key contains a list of Agent. The latter is a dictionary composed by the following basic keys:

  • position: the position of the agent
  • fitness: the fitness value of the agent
  • cost: the cost of the agent
from pydantic import BaseModel

class Agent(BaseModel):
    position: list[float]
    cost: float
    fitness: float

These are the basic information, but each algorithm can add more information to the agent, such as the velocity in the case of PSO.

Utilities

pyVolutionary also provides a set of utilities to facilitate the use of the library. For example, you can use the plot function to plot the evolution of the algorithm. Its usage is as follows:

plot(function: callable, pos_min: float, pos_max: float, evolution: list[Population])

where:

  • function: the function to plot, i.e., the function to optimize
  • pos_min: the minimum possible coordinates in the search space
  • pos_max: the maximum possible coordinates in the search space
  • evolution: the evolution of the algorithm, i.e., the list of the agents found at each generation

It is also possible to inspect an animation of the evolution of the algorithm by using the animate function:

animate(function: callable, optimization_result: OptimizationResult, pos_min: float, pos_max: float, filename: str)

where:

  • function: the same as above
  • optimization_result: the result of the optimization, i.e., the dictionary returned by the optimize method
  • pos_min: the same as above
  • pos_max: the same as above
  • filename: the name of the file where to save the animation

Furthermore, you can extract the trend of the best agent found by the algorithm by using the best_agent_trend function:

best_agent_trend(optimization_result: OptimizationResult, iters: list[int] | None = None) -> list[float]

where:

  • optimization_result: the same as above
  • iters: a list of the iterations to consider. If None, all the iterations are considered It returns a list of the cost values of the best agent found at each iteration.

If you prefer, you can extract the trend of a specific agent by using the agent_trend function:

agent_trend(optimization_result: OptimizationResult, idx: int, iters: list[int] | None = None) -> list[float]

where:

  • optimization_result: the same as above
  • idx: the index of the agent to consider
  • iters: the same as above It returns a list of the cost values of the agent at each iteration.

Practical example

With pyVolutionary, you can solve a wide range of problems. In the following, we provide some examples of how to optimize the hyperparameters of a Machine Learning model, specifically a Support Vector Classifier (SVC), by using the Particle Swarm Optimization (PSO).

You can replace the PSO with any other algorithm implemented in the library.

from typing import Any
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn import datasets, metrics

from pyvolutionary import (
    best_agent,
    ContinuousVariable,
    DiscreteVariable,
    ParticleSwarmOptimization,
    ParticleSwarmOptimizationConfig,
    Task,
)

# Load the data set; In this example, the breast cancer dataset is loaded.
X, y = datasets.load_breast_cancer(return_X_y=True)

# Create training and test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1, stratify=y)

sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)


class SvmOptimizedProblem(Task):
    def objective_function(self, x: list[Any]):
        x_transformed = self.transform_position(x)
        C, kernel = x_transformed["C"], x_transformed["kernel"]
        degree, gamma = x_transformed["degree"], x_transformed["gamma"]

        svc = SVC(C=C, kernel=kernel, degree=degree, gamma=gamma, probability=True, random_state=1)
        svc.fit(X_train_std, y_train)
        y_predict = svc.predict(X_test_std)
        return metrics.accuracy_score(y_test, y_predict)


task = SvmOptimizedProblem(
    variables=[
        ContinuousVariable(lower_bound=0.01, upper_bound=1000., name="C"),
        DiscreteVariable(choices=["linear", "poly", "rbf", "sigmoid"], name="kernel"),
        DiscreteVariable(choices=[*range(1, 6)], name="degree"),
        DiscreteVariable(choices=['scale', 'auto', 0.01, 0.05, 0.1, 0.5, 1.0], name="gamma"),
    ],
    minmax="max",
)

configuration = ParticleSwarmOptimizationConfig(
    population_size=200,
    fitness_error=10e-4,
    max_cycles=100,
    c1=0.1,
    c2=0.1,
    w=[0.35, 1],
)

result = ParticleSwarmOptimization(configuration).optimize(task)
best = best_agent(result.evolution[-1].agents, task.minmax)

print(f"Best parameters: {task.transform_position(best.position)}")
print(f"Best accuracy: {best.cost}")

Extending the library

pyVolutionary is designed to be easily extensible. You can add your own algorithms and problems to the library by following the instructions below.

Adding a new algorithm

To add a new algorithm, you need to create a new class that inherits from the OptimizationAbstract class. The new class must implement the optimization_step method, where you can implement your new metaheuristic algorithm.

The constructor of the new class must accept a config parameter, which is a Pydantic model extending the BaseOptimizationConfig class. This class contains the parameters of the algorithm, such as the population size, the number of generations, etc.

from pydantic import BaseModel

class BaseOptimizationConfig(BaseModel):
    population_size: int
    fitness_error: float | None = None
    max_cycles: int

Once you created your new classes, you can run the algorithm by calling the optimize method, which takes as input a Task object and returns a dictionary as above described.

Algorithms

The following algorithms are currently implemented in pyVolutionary:

Algorithm Class Paper Example
African Vulture Optimization AfricanVultureOptimization paper example
Ant Colony Optimization AntColonyOptimization paper example
Aquila Optimization AquilaOptimization paper example
Bacterial Foraging Optimization BacterialForagingOptimization paper example
Bat Optimization BatOptimization paper example
Bee Colony Optimization BeeColonyOptimization paper example
Camel Caravan Optimization CamelCaravanOptimization paper example
Coral Reef Optimization CoralReefOptimization paper example
Coyotes Optimization CoyotesOptimization paper example
Earthworms Optimization EarthwormsOptimization paper example
Electromagnetic Field Optimization ElectromagneticFieldOptimization paper example
Elephant Herd Optimization ElephantHerdOptimization paper example
Firefly Swarm Optimization FireflySwarmOptimization paper example
Fireworks Optimization FireworksOptimization paper example
Fish School Search Optimization FishSchoolSearchOptimization paper example
Flower Pollination Algorithm Optimization FlowerPollinationAlgorithmOptimization paper example
Forest Optimization Algorithm ForestOptimizationAlgorithm paper example
Fox Optimization FoxOptimization paper example
Genetic Algorithm Optimization GeneticAlgorithmOptimization paper example
Grasshopper Optimization Algorithm GrasshopperOptimization paper example
Grey Wolf Optimization GreyWolfOptimization paper example
Harmony Search Optimization HarmonySearchOptimization paper example
Imperialist Competitive Optimization ImperialistCompetitiveOptimization paper example
Invasive Weed Optimization InvasiveWeedOptimization paper example
Krill Herd Optimization KrillHerdOptimization paper example
Levy Flight Jaya Swarm Optimization LeviFlightJayaSwarmOptimization paper example
Monarch Butterfly Optimization MonarchButterflyOptimization paper example
Mountain Gazelle Optimization MountainGazelleOptimization paper example
Osprey Optimization OspreyOptimization paper example
Particle Swarm Optimization ParticleSwarmOptimization paper example
Pathfinder Algorithm Optimization PathfinderAlgorithmOptimization paper example
Pelican Optimization PelicanOptimization paper example
Seagull Optimization SeagullOptimization paper example
Siberian Tiger Optimization SiberianTigerOptimization paper example
Tasmanian Devil Optimization TasmanianDevilOptimization paper example
Virus Colony Search Optimization VirusColonySearchOptimization paper example
Walrus Optimization WalrusOptimization paper example
Whales Optimization WhalesOptimization paper example
Wildebeest Herd Optimization WildebeestHerdOptimization paper example
Zebra Optimization ZebraOptimization paper example

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyvolutionary-1.0.2.tar.gz (75.4 kB view details)

Uploaded Source

Built Distribution

pyvolutionary-1.0.2-py3-none-any.whl (132.7 kB view details)

Uploaded Python 3

File details

Details for the file pyvolutionary-1.0.2.tar.gz.

File metadata

  • Download URL: pyvolutionary-1.0.2.tar.gz
  • Upload date:
  • Size: 75.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.12 Linux/5.15.0-91-generic

File hashes

Hashes for pyvolutionary-1.0.2.tar.gz
Algorithm Hash digest
SHA256 9dbd1cc973927363a5c3269ea70a0125d1446786a638faef84ae9773322dcc92
MD5 ea634419efeef238d65216878dc6aab9
BLAKE2b-256 ae4d0e2a785153a81817df68e985e22c22cc171cdea337e08737f9a2ba5e97ce

See more details on using hashes here.

File details

Details for the file pyvolutionary-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: pyvolutionary-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 132.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.10.12 Linux/5.15.0-91-generic

File hashes

Hashes for pyvolutionary-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 875b31f7af1f8c00e487f026afaadcae647a99ffa3a42b70d551de13984dae6f
MD5 75dd0a68ce82c687843cb70a08781515
BLAKE2b-256 bb9d3b9ac219c1db6d93213d934c244fb7dfc91616aa22e5a4589f99a7b6efe1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page