Multitask Solving
MEALPY provides a dedicated Multitask class designed to streamline large-scale experimental setups. Instead of writing boilerplate loops, you can use this class to effortlessly execute combinations of:
One algorithm solving one problem across multiple trials.
One algorithm solving multiple problems across multiple trials.
Multiple algorithms solving one problem across multiple trials.
Multiple algorithms solving multiple problems across multiple trials.
Hint
Explore the Examples Folder
For a deep dive into complex experiment configurations, please check out our official Multitask-Examples repository.
Simple Multitask Example
In this example, we benchmark two algorithms (BBO and DE) with different variants against three standard CEC2017 benchmark functions.
import numpy as np
from opfunu.cec_based.cec2017 import F52017, F102017, F292017
from mealpy import FloatVar, BBO, DE, Multitask
## 1. Define your problems using Opfunu
f1, f2, f3 = F52017(30, f_bias=0), F102017(30, f_bias=0), F292017(30, f_bias=0)
p1 = {"bounds": FloatVar(lb=f1.lb, ub=f1.ub), "obj_func": f1.evaluate, "minmax": "min", "name": "F5"}
p2 = {"bounds": FloatVar(lb=f2.lb, ub=f2.ub), "obj_func": f2.evaluate, "minmax": "min", "name": "F10"}
p3 = {"bounds": FloatVar(lb=f3.lb, ub=f3.ub), "obj_func": f3.evaluate, "minmax": "min", "name": "F29"}
## 2. Define the optimizer models
model1 = BBO.DevBBO(epoch=10000, pop_size=50)
model2 = BBO.OriginalBBO(epoch=10000, pop_size=50)
model3 = DE.OriginalDE(epoch=10000, pop_size=50)
model4 = DE.SAP_DE(epoch=10000, pop_size=50)
## 3. Define termination criteria
term = {"max_fe": 3000}
## 4. Initialize and execute Multitask
if __name__ == "__main__":
multitask = Multitask(
algorithms=(model1, model2, model3, model4),
problems=(p1, p2, p3),
terminations=(term, ),
modes=("single", ) # Default is "single"
)
# Execute 5 independent trials for all algorithm-problem combinations
multitask.execute(
n_trials=5,
n_jobs=None,
save_path="history",
save_as="csv",
save_convergence=True,
verbose=False
)
Advanced Configuration: Terminations & Modes
When defining a Multitask object, you can pass a highly specific grid of terminations and modes (e.g., “thread”, “process”, “swarm”, “single”) for each optimizer solving each problem.
Assuming you have 3 optimizers and 2 problems, MEALPY intelligently broadcasts your inputs. Here is how you can configure the mapping:
# 1. Exact Mapping (List of Lists/Tuples)
# Define a specific termination for every single algorithm-problem pair
terminations = [ (term_11, term_12), (term_21, term_22), (term_31, term_32) ]
# 2. Algorithm-Specific Mapping (Matches number of algorithms)
# The same termination applies to all problems, mapped by optimizer
terminations = [ term_1, term_2, term_3 ]
# Internally converts to: [ (term_1, term_1), (term_2, term_2), (term_3, term_3) ]
# 3. Problem-Specific Mapping (Matches number of problems)
# The same termination applies to all optimizers, mapped by problem
terminations = [ term_1, term_2 ]
# Internally converts to: [ (term_1, term_2), (term_1, term_2), (term_1, term_2) ]
# 4. Universal Mapping (Single element)
# Applies exactly one termination rule to ALL algorithms and ALL problems
terminations = [term]
# Internally converts to: [ (term, term), (term, term), (term, term) ]
Execution & Parallel Trials
Once the Multitask object is created, call execute() to start the experiment. Two critical parameters dictate the workload:
n_trials: The number of independent runs for each (optimizer, problem) pair to ensure statistical significance.n_jobs: The number of CPU processes used to run these trials in parallel.n_jobs <= 1orNone: Runs trials sequentially.n_jobs >= 2: Spawns processes to run trials concurrently (e.g.,n_jobs=4runs 4 trials simultaneously).
Important
Do Not Nest Parallelism (n_jobs vs modes)
Be extremely careful when mixing multiprocessing levels.
n_jobsparallelizes at the Trial Level.modes="process"parallelizes at the Agent Fitness Level (inside the algorithm).
If you set both n_jobs=4 and modes=("process",) with n_workers=4, your machine will attempt to spawn 4 × 4 = 16 intensive processes simultaneously. This can lead to severe CPU bottlenecking or memory crashes. Rule of thumb: Choose only one level of parallelization.