(1) Overview
Introduction
In 1995, James Kennedy and Russel Eberhart, inspired by simulations of simplified social models, introduced an optimization algorithm for nonlinear continuous functions that they dubbed “particle swarm optimization” (PSO) [1]. Drawing parallels to concepts from artificial life (e.g., bird flocking, fish schooling) and evolutionary computation (e.g., genetic algorithms (GAs) [2]), PSO has gained significant attention primarily due to its ease of understanding/explaining and straightforward coding implementation, which has led to the development of numerous versions of it [3].
PSO is a heuristic search technique characterized by its stochastic nature, which incrementally enhances a collection of candidate solutions, referred to as “swarm of particles,” using a defined measure of fitness. The algorithm starts with an initial population of solutions, which are typically sampled at random, and seeks optimal solutions by iteratively adjusting the current positions of these particles. Unlike GAs where the solutions evolve, using a set of evolutionary operators, such as crossover and mutation, PSO solutions move through the search space by updating their positions in accordance with three distinct attractors: (1) the particle’s current position, (2) the particle’s personal historical best position, which serves as a cognitive convergence point, and (3) the best position identified by the entire swarm, functioning as a social convergence point.
The mechanics of the original PSO are remarkably simple and can be described by two straightforward equations. Equation (1) represents the core mechanism for updating the particle’s velocity. It defines how ith particle’s future velocity (at iteration t+1), is influenced by its current velocity , its own personal best known position pi, and the global best-known position gbest, together with some random influences represented by two uniform random vectors u1 and u2. This dynamic allows particles to explore the search space while being attracted to both their own and the global best positions. Subsequently, Eq. (2) computes the new position of the ith particle by adding its updated velocity to its current position .
where boldface letters vi, pi, gbest, xi∈ℜd and , represent d-dimensional vectors, while w, c1, c2∈ℜ, denote scalar values. Symbol “⋅” represents normal multiplication, in contrast to “∘” that represents an element-wise multiplication between two vectors of the same size.
Existing Python implementations of the basic/standard PSO can be found in some evolutionary algorithm toolboxes, such as DEAP [4], and other frameworks that offer single- and multi-objective optimization algorithms, such as pymoo [5]. Alternatively, a PSO-specific library that implements the classic PSO algorithm (global and local best) is provided by PySwarms [6].
StarPSO is an advanced research toolbox, specifically designed to implement a range of PSO algorithms. It addresses problems involving continuous, discrete, categorical, and mixed variable types within a single unified framework. This library effectively handles the complexities associated with optimizing diverse problem types by providing a cohesive platform. Furthermore, its clearly defined and well-structured object-oriented design facilitates the integration of new PSO algorithms, enhancing its adaptability and utility in research applications.
Implementation and Architecture
StarPSO is implemented in Python programming language which, according to the 2026 TIOBE (programming community) index [7] and the Stack Overflow Developer Survey [8], is the most dominant in several fields of computer science, such as artificial intelligence (AI) and machine learning (ML), due to its ease of learning, rapid development (fast prototyping), rich ecosystem, and cross-platform compatibility. The code is organized in four main packages:
[engines]: this package includes the computational models of all the available PSO implementations. Additional engines can be added in here, after inheriting from the GenericPSO class, which provides the basic functionality and acts as the required interface.
[population]: this package contains the main modules that are necessary to construct and represent the swarm of solutions to any optimization problem (i.e., the Particle and Swarm classes). Moreover, since the “JackOfAllTrades” algorithm requires specialized data structures to represent the mixed variable types, for this engine, the particle is modeled by the specific JatParticle class.
[utils]: includes two modules: (i) auxiliary and (ii) data_block. The former contains a list of supplementary data structures (e.g., BlockType), utility decorators (e.g., @time_it, @cost_function), along with a list of numba-jit optimized numerical functions that are used frequently by all the computational models (i.e., engines). While the later is used solely by the “JackOfAllTrades” version and contains the main class that encodes the data of a single optimization variable (i.e., a DataBlock), along with its core functionality that allows the update of particle’s position, according to its specific block type (i.e., float, int, binary, or categorical).
[benchmarks]: a particular strength of StarPSO is its built-in ability to be applied to multimodal problems (i.e., optimization problems where there exists more than one optimal value). This package contains a collection of 10 multimodal test functions [9], which vary in dimensionality from 1D (such as EqualMaxima, FiveUnevenPeakTrap) to 2D (e.g., Himmelblau, SixHumpCamelBack), and extends to dimensions greater than 2D (e.g., functions like Rastrigin and Shubert). More benchmark functions can be added by inheriting directly from the TestFunction class, which offers the essential functionality and serves as the necessary interface.
A graphical representation of the code structure is given in Figure 1.

Figure 1
An overview of the StarPSO code structure. The four main packages are represented by the light blue tabbed ovals, while the modules inside each package are represented by light red ovals, with different edge color.
Software Functionalities
The current version of StarPSO implements a variety of PSO algorithms that can be used on problems with different data types. We have to note that since the original PSO algorithm has undergone various transformations through the years, there exists a plethora of different variations. Therefore, we do not claim that there is a right or wrong version, but rather that we provide a set of implementations that they can be used as is, or tailored to match specific requirements.
Standard: this version is the most common in practice, and it is used for continuous space domains. It is based on the work of [10] with the introduction of the inertia weight parameter in the original particle swarm optimizer [1].
Binary: operates on discrete binary variables following [11], where the velocities of the particles are functioning as probability thresholds.
Integer: provides a similar workflow as the Standard, but it rounds the positional variables, of the particles, to the nearest integer (dubbed IPSO in [12]). For positions exactly halfway between rounded decimal values, the method rounds to the nearest even integer value.
Categorical: addresses problems, discrete in nature, with variables that indicate categories without a specific order (i.e. nominal variables). It provides a simpler alternative to the ICPSO algorithm [12], which incorporates ideas from estimation of distribution algorithms (EDAs) in that particles’ positions represent probability distributions rather than solution values.
Quantum: provides a version of the weighted QPSO (WQPSO) algorithm [13], which belongs to the family of quantum-behaved PSO algorithms. Quantum-behaved algorithms integrate principles of quantum mechanics with traditional PSO methods. These algorithms aim to improve the search for global optimal values in various optimization problems, with potentially faster convergence, compared to the Standard PSO.
BareBones: this algorithm is used for the optimization of continuous variables using the bare-bones PSO rules, where the velocity updates have been completely removed and the new position updates are sampled directly by a Gaussian distribution centered on the particle’s personal best and the swarm/ global best [14]. This simplified variant of the original PSO preserves the cooperative search behavior of the swarm, while reducing algorithmic complexity and hyperparameters, often yielding competitive performance on continuous optimization tasks.
JackOfAllTrades: introduces a new PSO implementation able to apply the original equations (as in the Standard), but for mixed variable problems. This is achieved by considering the particle as a collection (or container) of data blocks, where each data block represents a single optimization variable and can belong to one of the following types: (i) float, (ii) integer, (iii) binary, or (iv) categorical. Subsequently, the algorithm follows the same process and when it comes to the step of updating the positions of the particles, each data block calls internally its own function of updating its positional variables. In other words, the data block structure not only holds the correct type of the positional variables, but also encapsulates the correct update functionality.
Furthermore, all the above algorithms provide support for the following options (for a summary see Table 1):
Table 1
A summary of the available options for the different StarPSO implementations. The default value for the “Mode” is marked with square brackets.
| ALGORITHM | VARIABLE TYPE | OPTIONS | ||
|---|---|---|---|---|
| ADAPTIVE | MODE | PARALLEL | ||
| Standard | Continuous | ✓ | [Gbest], FI, Multimodal | ✓ |
| Binary | Discrete | ✓ | [Gbest], FI | ✓ |
| Integer | Discrete | ✓ | [Gbest], FI | ✓ |
| Categorical | Categorical | ✓ | [Gbest], FI | ✓ |
| Quantum | Continuous | – | [Gbest], FI, Multimodal | ✓ |
| BareBones | Continuous | – | [Gbest], FI, Multimodal | ✓ |
| JackOfAllTrades | Mixed | ✓ | [Gbest], FI | ✓ |
Adaptive: Contrary to GAs, which require a high number of parameters to be tuned for optimal performance [15] (e.g., choice of selection, crossover, mutation operators, probability values, number of elite population, etc.), PSO algorithms usually require only a handful of adjustable parameters, such as the inertia weight “w,” along with the cognitive “c1” and social “c2” parameters (see Eq. 1). Even though there are only three parameters, their role in balancing the trade-off between exploration and exploitation in the algorithm is crucial, therefore they can have a significant impact in the final result. StarPSO offers the option to allow these parameters to adapt, during runtime, based on the convergence of the population to a single solution. Each of the different implementations has a measure of the spread of the solutions in the search space, and if the spread is small (indicating the convergence to a single solution), the algorithm adjusts slightly the social and cognitive coefficients to allow the particles to explore a bit further for a better solution, or vice versa.
Mode: Unlike the previous adaptive parameter that is either enabled or disabled, the “mode” parameter is always set to one of its three options: (i) global best (Gbest), (ii) fully informed (FI), and (iii) multimodal. This parameter affects directly the gbest vector in the velocity equations (1), which deals with the social attractor of the particle. By default, its value is set to Gbest, which simply seeks the particle, from the whole swarm, with the optimal fitness value. The fully informed option is based in [16] and sets as a global attractor the weighted average of the particles’ best positions. Finally, the “multimodal” option is a new technique that enables the swarm to simultaneously concentrate on multiple optimal values instead of converging on just one solution. This is the preferred mode when we are dealing with multimodal problems, and we want to identify more than one optimal solutions, with a single run of the algorithm.
Parallel: Population based algorithms are inherently parallelizable. That means there is always a part of the algorithm that can be computed independently for each member of the population. As PSO algorithms fall in the same category, there are several parts of them, that can be executed in parallel. However, Python is known to have some limitations in multithreaded execution, mainly due to the global interpreter lock (GIL), which is a mutex that protects access to Python objects, preventing multiple native threads from executing Python bytecode simultaneously. Therefore, StarPSO offers the parallel option in a multiprocessing framework (using JobLib [17]), by allowing the fitness function of the swarm to be evaluated in several central processing units (CPUs).
As with every iterative optimization algorithm that is required to have at least one termination condition, to avoid running perpetually; StarPSO provides four termination conditions, as seen in Table 2.
Table 2
Types and default values of the termination conditions. The optional numeric conditions default to None.
| CONDITION | TYPE | DEFAULT VALUE | OPTIONAL |
|---|---|---|---|
| Maximum number of iterations | Integer | 1000 | No |
| Maximum fitness evaluations | Integer | None | Yes |
| Fitness (convergence) tolerance | Float | None | Yes |
| Found solution | Boolean | False | Yes |
The first condition sets a maximum number of iterations for the algorithm to update its particles positions. This acts as an upper bound and ensures that if no other condition is set (or met with) the algorithm will terminate. In environments where there are limitations on the resources, StarPSO also allows the user (optionally) to set a maximum number of fitness function evaluations. This feature is also useful when one compares two algorithms and wants to make sure that both algorithms use the same computational resources. Another optional termination condition is setting a tolerance threshold value for the improvement of the fitness function. This is usually set to a very small value (e.g. ftol = 10–8) and terminates the algorithm if the gains in the fitness are small. Moreover, in various optimization problems, it is possible to verify that a solution satisfies some termination criteria. In these cases, StarPSO can make direct use of that condition to signal the algorithm for termination. This feature requires the user to explicitly return a Boolean variable (flag), along with the computed fitness values.
Finally, all algorithms come with default values that would satisfy many optimization problems and allow the methods to run even without passing a single parameter. Nevertheless, the user is encouraged to set new parameter values depending on the problem at hand.
Illustrative Examples
To demonstrate a step-by-step example of the StarPSO library, we use the Himmelblau function [18]. This is a two-dimensional multimodal function that tests the performance of optimization algorithms. Here, we present a modified (inverted) version of the function defined as follows [9]:
where . It has four global optima with two of them closer to each other, as can be seen in Figure 2.

Figure 2
Contour plot of the Himmelblau 2D function at different iterations: (a) at initialization, (b) after 10 iterations, (c) after 50 iterations, and (d) at convergence after 200 iterations. All of the four modes have been successfully identified by the swarm particles. The symbol “×” marks the location of the particle with the optimal fitness value.
As shown in Listing 2, the basic steps that are required are as follows:
By definition, the PSO algorithms require a measure of fitness. This is specific to the optimization problem that is being solved and identifies which solutions are better than others. As a rule of thumb, this function will have to follow the template as seen in Listing 1.
Note that if the optimization problem refers to a minimization or a maximization, it has to be declared explicitly in the custom decorator @cost_function. Moreover, if a condition for termination is not possible to be verified, the user can simply omit the return of the second variable (solution_found).
The initialization of the swarm is usually done by sampling randomly within the limits of the search domain. Alternatively, StarPSO allows the user to initialize the population from a predefined swarm. This can be useful in cases where the optimization process has to stop (e.g., due to limited allocation of resources) and then re-start from the same point that it stopped.
Depending on the problem that one has to solve, the selection of an appropriate PSO implementation is crucial. For example, if one has to solve a problem in continuous domain, something that is addressed by the StandardPSO, selecting the BinaryPSO, or IntegerPSO could be the wrong choice.
Finally, once the initial swarm and the correct PSO have been created, the next step is to simply run the method. As mentioned earlier, the algorithms have default parameter values that would suffice for most cases, but using prior (problem-specific) knowledge to customize them is highly recommended. One thing to pay attention in multimodal cases is that the adaptation of the parameters should be disabled. The reason is that the current implementation uses the spread of the swarm as a measure of convergence. However, in problems with multiple optimal solutions, we want the swarm not to focus on a specific area, but rather explore all the domain to find all the possible solutions. This way, the spread of the whole swarm would work counter-intuitively.

Listing 1
Objective function template.

Listing 2
Simple multimodal example using the Himmelblau 2D function.
A comprehensive list of examples on how to use all the available implementations on various problems involving: (i) single/multiple objective(s), (ii) single/multiple mode(s), and (iii) using constraints (inequalities) can be found in the online documentation as well as the project’s GitHub page.
Quality Control
Ensuring the quality of the code is of high priority for this project, as it directly influences the overall performance, maintainability, and user satisfaction of our software. We use an object-oriented programming paradigm to structure our code, which promotes clean design and modularity. To achieve high standards of code quality, we adhere to the following best practices:
Thoroughly documented code: Comprehensive documentation serves as a vital resource for researchers, developers, and end-users, enabling them to grasp the code’s purpose, underlying logic, and structural organization. Additionally, our API documentation is readily available online, offering real-time access to essential information that aids in effective utilization of our algorithm’s features.
Consistent coding style: Maintaining a uniform coding style across the project significantly enhances code readability. A consistent approach not only makes the code easier to read and navigate but also facilitates smoother collaboration among team members.
Minimal code complexity: Our aim is to produce code that is straightforward and easy to comprehend. By minimizing complexity, we not only create less convoluted code but also enhance its efficiency. Simplified code can lead to faster execution, which ultimately improves the overall system performance.
Unit tests: Implementing adequate unit tests is crucial for early identification of bugs within the development lifecycle. By catching issues early, we can significantly reduce the time associated with fixes later in the process. Unit tests provide an assurance that individual components of the software perform as intended, contributing to the reliability of the overall system.
Moreover, to ensure adherence to coding standards and best practices, we use Pylint [19], a popular static code analysis tool, which scored StarPSO with: 9.50/10. This high score reflects our commitment to maintaining high code quality, readability, and alignment with Python conventions.
To ensure that we consistently meet these high standards, we will conduct regular reviews and checks. These evaluations will help us maintain our coding practices and adapt to any changes or improvements within the programming landscape, ensuring that our project remains robust and capable of adapting to future requirements. Through a continuous commitment to quality control, we aim to deliver a product that meets the highest expectations of performance and reliability.
(2) Availability
Operating system
StarPSO package is platform-independent and it can be run on any operating system (e.g., GNU/Linux, Mac OSX, Windows) that supports Python (version 3.10 or greater). Current operating systems that have been tested on include: macOS Catalina 10.15.7. and macOS Ventura 13.7.8.
Programming language
Python (version 3.10 or greater).
Additional system requirements
None
Dependencies
The current version has been developed and tested with the following packages.
Required:
numpy: 2.1.3
numba: 0.61.0
joblib: 1.4.2
scipy: 1.15.3 (for benchmark functions)
Optional (for running the example notebooks):
jupyter: 7.3.2
matplotlib: 3.10.0
sphinx_rtd_theme: (for building the doc files)
List of contributors
Michail D. Vrettas is the primary architect, developer and current maintainer of the StarPSO package. Stefano Silvestri advised and co-authored this article.
Software location
Archive
Name: Zenodo
Persistent identifier: https://doi.org/10.5281/zenodo.18429187
Licence: GNU General Public License v3.0 or later
Publisher: Michail D. Vrettas
Version published: v.0.1.2
Date published: 30/01/2026
Code repository
Name: GitHub
Persistent identifier: https://github.com/vrettasm/PyStarPSO
Licence: GNU General Public License v3.0 or later
Date published: 30/01/2026
Language
English
(3) Reuse potential
PSO algorithms have been used in various scientific research and industrial fields, with applications in electrical and electronic engineering, automation control systems, communication theory, operations research, mechanical engineering, fuel and energy, medicine, chemistry, and biology. A comprehensive survey is given in [20], and references therein.
StarPSO comes with support for the most frequently used PSO algorithms; however, this collection of algorithms can be extended by providing new “engines” that inherit directly the GenericPSO class. Moreover, the swarm update rules can be modified directly using the two relevant methods: (1) update_velocities and (2) update_positions. These two methods are part of the general interface and each PSO has to implement them accordingly. The GenericPSO class, which serves as the base for all subsequent algorithms, implements the original formulation of Eq. (1). Algorithms that use different update rules—such as QuantumPSO and BareBonesPSO—must provide their own implementations, overriding the default. Information on how to extend the software is available both through the API docs and example notebooks.
The software is maintained on GitHub under an open-source license (GPL-3.0). Users can report bugs, request features, or seek support by opening an issue on the repository. Alternatively, users may contact the primary author directly via email for inquiries related to the software. This method is in line with the principles of open science, highlighting transparency, accessibility, collaboration, and reproducibility, which fosters its broad acceptance among researchers.
