import scipy.io
import pkgutil
import io
from ddmtolab.Problems.BasicFunctions.basic_functions import *
from ddmtolab.Methods.mtop import MTOP
import numpy as np
[docs]
class CEC19MaTSO:
"""
Implementation of the CEC 2019 Competition on Massive Multi-Task Optimization (MaTSO)
benchmark problems P1 to P6.
These problems are designed to challenge algorithms with a large number of
optimization tasks (typically 100 or more) derived from the same
underlying function, but with different rotations and shifts, thereby testing
transfer learning across many similar, but distinct tasks.
Attributes
----------
dim : int
The dimensionality of the search space for all tasks (fixed at 50).
data_dir : str
The directory path for problem data files.
"""
problem_information = {
'n_cases': 6,
'n_tasks': 'K',
'n_dims': '50',
'n_objs': '1',
'n_cons': '0',
'type': 'synthetic',
}
def __init__(self):
self.dim = 50
self.data_dir = 'data_cec19matso'
[docs]
def P1(self, K=10) -> MTOP:
"""
Generates Problem 1 (MaTSO): **Rosenbrock** tasks.
Each task is a 50D **Rosenbrock** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Rosenbrock
- Dimensions: 50D
- Bounds: [-50, 50]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask1.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask1.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task1 = go_data['GoTask1']
rotation_task1 = rotation_data['RotationTask1']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task1[0, i]
go_vector = go_task1[i, :]
def create_task_function(rot, go):
return lambda x: Rosenbrock(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -50),
upper_bound=np.full(self.dim, 50))
return problem
[docs]
def P2(self, K=10) -> MTOP:
"""
Generates Problem 2 (MaTSO): **Ackley** tasks.
Each task is a 50D **Ackley** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Ackley
- Dimensions: 50D
- Bounds: [-50, 50]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask2.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask2.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task2 = go_data['GoTask2']
rotation_task2 = rotation_data['RotationTask2']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task2[0, i]
go_vector = go_task2[i, :]
def create_task_function(rot, go):
return lambda x: Ackley(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -50),
upper_bound=np.full(self.dim, 50))
return problem
[docs]
def P3(self, K=10) -> MTOP:
"""
Generates Problem 3 (MaTSO): **Rastrigin** tasks.
Each task is a 50D **Rastrigin** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Rastrigin
- Dimensions: 50D
- Bounds: [-50, 50]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask3.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask3.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task3 = go_data['GoTask3']
rotation_task3 = rotation_data['RotationTask3']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task3[0, i]
go_vector = go_task3[i, :]
def create_task_function(rot, go):
return lambda x: Rastrigin(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -50),
upper_bound=np.full(self.dim, 50))
return problem
[docs]
def P4(self, K=10) -> MTOP:
"""
Generates Problem 4 (MaTSO): **Griewank** tasks.
Each task is a 50D **Griewank** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Griewank
- Dimensions: 50D
- Bounds: [-100, 100]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask4.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask4.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task4 = go_data['GoTask4']
rotation_task4 = rotation_data['RotationTask4']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task4[0, i]
go_vector = go_task4[i, :]
def create_task_function(rot, go):
return lambda x: Griewank(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -100),
upper_bound=np.full(self.dim, 100))
return problem
[docs]
def P5(self, K=10) -> MTOP:
"""
Generates Problem 5 (MaTSO): **Weierstrass** tasks.
Each task is a 50D **Weierstrass** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Weierstrass
- Dimensions: 50D
- Bounds: [-0.5, 0.5]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask5.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask5.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task5 = go_data['GoTask5']
rotation_task5 = rotation_data['RotationTask5']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task5[0, i]
go_vector = go_task5[i, :]
def create_task_function(rot, go):
return lambda x: Weierstrass(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -0.5),
upper_bound=np.full(self.dim, 0.5))
return problem
[docs]
def P6(self, K=10) -> MTOP:
"""
Generates Problem 6 (MaTSO): **Schwefel** tasks.
Each task is a 50D **Schwefel** function, rotated and shifted.
Parameters
----------
K : int, optional
Number of tasks to create (default: 10).
Notes
-----
Fixed parameters by benchmark definition: D=50
- Function: Schwefel
- Dimensions: 50D
- Bounds: [-500, 500]
Returns
-------
MTOP
A Multi-Task Optimization Problem instance containing ``task_num`` tasks.
"""
go_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/GoTask6.mat')
go_file = io.BytesIO(go_bytes)
go_data = scipy.io.loadmat(go_file)
rotation_bytes = pkgutil.get_data('ddmtolab.Problems.MTSO', f'{self.data_dir}/RotationTask6.mat')
rotation_file = io.BytesIO(rotation_bytes)
rotation_data = scipy.io.loadmat(rotation_file)
go_task6 = go_data['GoTask6']
rotation_task6 = rotation_data['RotationTask6']
problem = MTOP()
for i in range(K):
rotation_matrix = rotation_task6[0, i]
go_vector = go_task6[i, :]
def create_task_function(rot, go):
return lambda x: Schwefel(x, rot, go, 0)
task_function = create_task_function(rotation_matrix, go_vector)
problem.add_task(task_function, dim=self.dim,
lower_bound=np.full(self.dim, -500),
upper_bound=np.full(self.dim, 500))
return problem