Skip to content

Commit

Permalink
Revert method, prop, attr names: .algorithms (#7)
Browse files Browse the repository at this point in the history
knakamura13 committed Sep 14, 2024
1 parent 0b692ff commit 6d92a16
Showing 41 changed files with 147 additions and 167 deletions.
15 changes: 2 additions & 13 deletions src/mlrose_ky/__init__.py
Original file line number Diff line number Diff line change
@@ -25,24 +25,13 @@
from .algorithms.decay import GeomDecay, ArithDecay, ExpDecay, CustomSchedule

# noinspection PyUnresolvedReferences
from .algorithms.crossovers import OnePointCrossover, UniformCrossover, TSPCrossover
from .algorithms.crossovers import OnePointCrossOver, UniformCrossOver, TSPCrossOver

# noinspection PyUnresolvedReferences
from .algorithms.mutators import ChangeOneMutator, DiscreteMutator, SwapMutator, ShiftOneMutator

# noinspection PyUnresolvedReferences
from .fitness import (
OneMax,
FlipFlop,
FourPeaks,
SixPeaks,
ContinuousPeaks,
Knapsack,
TravellingSales,
Queens,
MaxKColor,
CustomFitness,
)
from .fitness import OneMax, FlipFlop, FourPeaks, SixPeaks, ContinuousPeaks, Knapsack, TravellingSales, Queens, MaxKColor, CustomFitness

# noinspection PyUnresolvedReferences
from .neural import NeuralNetwork, LinearRegression, LogisticRegression, NNClassifier, _nn_core
9 changes: 6 additions & 3 deletions src/mlrose_ky/algorithms/__init__.py
Original file line number Diff line number Diff line change
@@ -3,12 +3,15 @@
# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause

from .crossovers import UniformCrossover, TSPCrossover, OnePointCrossover
from .decay import ArithDecay, CustomSchedule, ExpDecay, GeomDecay
from .ga import genetic_alg
from .gd import gradient_descent
from .hc import hill_climb
from .mimic import mimic
from .mutators import ChangeOneMutator, DiscreteMutator, ShiftOneMutator, SwapMutator
from .rhc import random_hill_climb
from .sa import simulated_annealing

from .crossovers import UniformCrossOver, TSPCrossOver, OnePointCrossOver

from .decay import ArithDecay, CustomSchedule, ExpDecay, GeomDecay

from .mutators import ChangeOneMutator, DiscreteMutator, ShiftOneMutator, SwapMutator
6 changes: 3 additions & 3 deletions src/mlrose_ky/algorithms/crossovers/__init__.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,6 @@
# Author: Genevieve Hayes
# License: BSD 3-clause

from .one_point_crossover import OnePointCrossover
from .tsp_crossover import TSPCrossover
from .uniform_crossover import UniformCrossover
from .one_point_crossover import OnePointCrossOver
from .tsp_crossover import TSPCrossOver
from .uniform_crossover import UniformCrossOver
26 changes: 14 additions & 12 deletions src/mlrose_ky/algorithms/crossovers/_crossover_base.py
Original file line number Diff line number Diff line change
@@ -8,10 +8,12 @@
# License: BSD 3-clause

from abc import ABC, abstractmethod
from typing import Any
from typing import Any, Sequence

import numpy as np

class _CrossoverBase(ABC):

class _CrossOverBase(ABC):
"""
Base class for crossover operations in a genetic algorithm.
@@ -20,7 +22,7 @@ class _CrossoverBase(ABC):
Parameters
----------
optimization_problem : Any
opt_prob : Any
An instance of the optimization problem related to the genetic algorithm.
This problem instance should provide necessary properties like 'length'
that might be needed for the crossover operation.
@@ -34,21 +36,21 @@ class _CrossoverBase(ABC):
'length' property.
"""

def __init__(self, optimization_problem: Any):
def __init__(self, opt_prob: Any):
"""
Initialize the CrossoverBase with the given optimization problem.
Initialize the _CrossOverBase with the given optimization problem.
Parameters
----------
optimization_problem : Any
opt_prob : Any
An instance of the optimization problem related to the GA.
"""
super().__init__()
self._opt_prob: Any = optimization_problem
self._length: int = optimization_problem.length
self._opt_prob: Any = opt_prob
self._length: int = opt_prob.length

@abstractmethod
def mate(self, parent1: Any, parent2: Any) -> Any:
def mate(self, p1: Sequence[int | float], p2: Sequence[int | float]) -> np.ndarray:
"""
Perform the crossover (mating) between two parents to produce offspring.
@@ -57,14 +59,14 @@ def mate(self, parent1: Any, parent2: Any) -> Any:
Parameters
----------
parent1 : Any
p1 : Sequence[int | float]
The first parent participating in the crossover.
parent2 : Any
p2 : Sequence[int | float]
The second parent participating in the crossover.
Returns
-------
Any
np.ndarray
The offspring resulting from the crossover. The type of this result
can vary depending on the specific GA implementation.
"""
22 changes: 11 additions & 11 deletions src/mlrose_ky/algorithms/crossovers/one_point_crossover.py
Original file line number Diff line number Diff line change
@@ -11,10 +11,10 @@

import numpy as np

from mlrose_ky.algorithms.crossovers._crossover_base import _CrossoverBase
from mlrose_ky.algorithms.crossovers._crossover_base import _CrossOverBase


class OnePointCrossover(_CrossoverBase):
class OnePointCrossOver(_CrossOverBase):
"""
One-point crossover for genetic algorithms.
@@ -23,21 +23,21 @@ class OnePointCrossover(_CrossoverBase):
is exchanged to create a new offspring.
Inherits from:
_CrossoverBase : Abstract base class for crossover operations.
_CrossOverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any):
def __init__(self, opt_prob: Any):
"""
Initialize the OnePointCrossover with the given optimization problem.
Initialize the OnePointCrossOver with the given optimization problem.
Parameters
----------
optimization_problem : Any
opt_prob : Any
An instance of the optimization problem related to the genetic algorithm.
"""
super().__init__(optimization_problem)
super().__init__(opt_prob)

def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray:
def mate(self, p1: Sequence[float], p2: Sequence[float]) -> np.ndarray:
"""
Perform the one-point crossover between two parent sequences to produce offspring.
@@ -46,9 +46,9 @@ def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray
Parameters
----------
parent1 : Sequence[float]
p1 : Sequence[float]
The first parent chromosome sequence.
parent2 : Sequence[float]
p2 : Sequence[float]
The second parent chromosome sequence.
Returns
@@ -57,4 +57,4 @@ def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray
The offspring chromosome resulting from the crossover.
"""
crossover_point = 1 + np.random.randint(self._length - 1)
return np.array([*parent1[:crossover_point], *parent2[crossover_point:]])
return np.array([*p1[:crossover_point], *p2[crossover_point:]])
50 changes: 25 additions & 25 deletions src/mlrose_ky/algorithms/crossovers/tsp_crossover.py
Original file line number Diff line number Diff line change
@@ -12,10 +12,10 @@

import numpy as np

from mlrose_ky.algorithms.crossovers._crossover_base import _CrossoverBase
from mlrose_ky.algorithms.crossovers._crossover_base import _CrossOverBase


class TSPCrossover(_CrossoverBase):
class TSPCrossOver(_CrossOverBase):
"""
Crossover operation tailored for the Travelling Salesperson Problem (TSP) in genetic algorithms.
@@ -24,21 +24,21 @@ class TSPCrossover(_CrossoverBase):
logic to combine parental genes.
Inherits from:
_CrossoverBase : Abstract base class for crossover operations.
_CrossOverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any):
def __init__(self, opt_prob: Any):
"""
Initialize the TSPCrossover with the given optimization problem.
Initialize the TSPCrossOver with the given optimization problem.
Parameters
----------
optimization_problem : Any
opt_prob : Any
An instance of the optimization problem related to the genetic algorithm.
"""
super().__init__(optimization_problem)
super().__init__(opt_prob)

def mate(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.ndarray:
def mate(self, p1: Sequence[int], p2: Sequence[int]) -> np.ndarray:
"""
Perform the crossover (mating) between two parent sequences to produce offspring.
@@ -47,28 +47,28 @@ def mate(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.ndarray:
Parameters
----------
parent1 : Sequence[int]
p1 : Sequence[int]
The first parent representing a TSP route.
parent2 : Sequence[int]
p2 : Sequence[int]
The second parent representing a TSP route.
Returns
-------
np.ndarray
The offspring representing a new TSP route.
"""
return self._mate_fill(parent1, parent2)
return self._mate_fill(p1, p2)

def _mate_fill(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.ndarray:
def _mate_fill(self, p1: Sequence[int], p2: Sequence[int]) -> np.ndarray:
"""
Perform a fill-based crossover using a segment of the first parent and filling
the rest with non-repeated cities from the second parent.
Parameters
----------
parent1 : Sequence[int]
p1 : Sequence[int]
The first parent representing a TSP route.
parent2 : Sequence[int]
p2 : Sequence[int]
The second parent representing a TSP route.
Returns
@@ -79,15 +79,15 @@ def _mate_fill(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.ndarr
if self._length > 1:
n = 1 + np.random.randint(self._length - 1)
child = np.array([0] * self._length)
child[:n] = parent1[:n]
unvisited = [city for city in parent2 if city not in parent1[:n]]
child[:n] = p1[:n]
unvisited = [city for city in p2 if city not in p1[:n]]
child[n:] = unvisited
else:
child = np.copy(parent1 if np.random.randint(2) == 0 else parent2)
child = np.copy(p1 if np.random.randint(2) == 0 else p2)

return child

def _mate_traverse(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.ndarray:
def _mate_traverse(self, parent_1: Sequence[int], parent_2: Sequence[int]) -> np.ndarray:
"""
Perform a traversal-based crossover using city adjacency considerations from
both parents to construct a viable TSP route.
@@ -98,9 +98,9 @@ def _mate_traverse(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.n
Parameters
----------
parent1 : Sequence[int]
parent_1 : Sequence[int]
The first parent representing a TSP route.
parent2 : Sequence[int]
parent_2 : Sequence[int]
The second parent representing a TSP route.
Returns
@@ -109,13 +109,13 @@ def _mate_traverse(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.n
The offspring TSP route.
"""
if self._length > 1:
next_city_parent1 = np.append(parent1[1:], parent1[0])
next_city_parent2 = np.append(parent2[1:], parent2[0])
next_city_parent1 = np.append(parent_1[1:], parent_1[0])
next_city_parent2 = np.append(parent_2[1:], parent_2[0])

visited_cities = [False] * self._length
offspring_route = np.array([0] * self._length)

starting_city = np.random.randint(len(parent1))
starting_city = np.random.randint(len(parent_1))
offspring_route[0] = starting_city
visited_cities[starting_city] = True

@@ -137,13 +137,13 @@ def _mate_traverse(self, parent1: Sequence[int], parent2: Sequence[int]) -> np.n
next_city = next_city2 if fitness1 > fitness2 else next_city1 # Choose the smaller distance
else:
while True:
next_city = np.random.randint(len(parent1))
next_city = np.random.randint(len(parent_1))
if not visited_cities[next_city]:
break

offspring_route[index] = next_city
visited_cities[next_city] = True
else:
offspring_route = np.copy(parent1 if np.random.randint(2) == 0 else parent2)
offspring_route = np.copy(parent_1 if np.random.randint(2) == 0 else parent_2)

return offspring_route
22 changes: 11 additions & 11 deletions src/mlrose_ky/algorithms/crossovers/uniform_crossover.py
Original file line number Diff line number Diff line change
@@ -12,10 +12,10 @@

import numpy as np

from mlrose_ky.algorithms.crossovers._crossover_base import _CrossoverBase
from mlrose_ky.algorithms.crossovers._crossover_base import _CrossOverBase


class UniformCrossover(_CrossoverBase):
class UniformCrossOver(_CrossOverBase):
"""
Uniform crossover for genetic algorithms.
@@ -24,21 +24,21 @@ class UniformCrossover(_CrossoverBase):
method is often used when no prior knowledge about the problem structure is known.
Inherits from:
_CrossoverBase : Abstract base class for crossover operations.
_CrossOverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any):
def __init__(self, opt_prob: Any):
"""
Initialize the UniformCrossover with the given optimization problem.
Initialize the UniformCrossOver with the given optimization problem.
Parameters
----------
optimization_problem : Any
opt_prob : Any
An instance of the optimization problem related to the genetic algorithm.
"""
super().__init__(optimization_problem)
super().__init__(opt_prob)

def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray:
def mate(self, p1: Sequence[float], p2: Sequence[float]) -> np.ndarray:
"""
Perform the uniform crossover between two parent sequences to produce offspring.
@@ -47,9 +47,9 @@ def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray
Parameters
----------
parent1 : Sequence[float]
p1 : Sequence[float]
The first parent chromosome sequence.
parent2 : Sequence[float]
p2 : Sequence[float]
The second parent chromosome sequence.
Returns
@@ -58,5 +58,5 @@ def mate(self, parent1: Sequence[float], parent2: Sequence[float]) -> np.ndarray
The offspring chromosome resulting from the crossover.
"""
gene_selector = np.random.randint(2, size=self._length)
stacked_parents = np.vstack((parent1, parent2))
stacked_parents = np.vstack((p1, p2))
return stacked_parents[gene_selector, np.arange(self._length)]
8 changes: 4 additions & 4 deletions src/mlrose_ky/algorithms/decay/__init__.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
# Author: Genevieve Hayes
# License: BSD 3-clause

from .arithmetic_decay import ArithDecay
from .custom_decay import CustomSchedule
from .exponential_decay import ExpDecay
from .geometric_decay import GeomDecay
from .arith_decay import ArithDecay
from .custom_schedule import CustomSchedule
from .expl_decay import ExpDecay
from .geom_decay import GeomDecay
Original file line number Diff line number Diff line change
@@ -64,29 +64,29 @@ def __eq__(self, other: object) -> bool:
return False
return self.init_temp == other.init_temp and self.decay == other.decay and self.min_temp == other.min_temp

def evaluate(self, time: int) -> float:
def evaluate(self, t: int) -> float:
"""
Calculate and return the temperature parameter at the given time.
Parameters
----------
time : int
t : int
The time at which to evaluate the temperature parameter.
Returns
-------
float
The temperature parameter at the given time, respecting the minimum temperature.
"""
return max(self.init_temp - (self.decay * time), self.min_temp)
return max(self.init_temp - (self.decay * t), self.min_temp)

def get_info(self, time: int = None, prefix: str = "") -> dict:
def get_info__(self, t: int = None, prefix: str = "") -> dict:
"""
Generate a dictionary containing the decay schedule's settings and optionally its current value.
Parameters
----------
time : int, optional
t : int, optional
The time at which to evaluate the current temperature value.
If provided, the current value is included in the returned dictionary.
prefix : str, optional
@@ -106,7 +106,7 @@ def get_info(self, time: int = None, prefix: str = "") -> dict:
f"{info_prefix}min_temp": self.min_temp,
}

if time is not None:
info[f"{info_prefix}current_value"] = self.evaluate(time)
if t is not None:
info[f"{info_prefix}current_value"] = self.evaluate(t)

return info
Original file line number Diff line number Diff line change
@@ -6,9 +6,6 @@
import numpy as np


# temp comment


class ExpDecay:
"""
Defines an exponential decay schedule for the temperature parameter T in simulated annealing,
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/ga.py
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ def genetic_alg(
max_iters: int | float = np.inf,
curve: bool = False,
random_state: int = None,
state_fitness_callback: Callable[..., Any] = None,
state_fitness_callback: Callable = None,
callback_user_info: Any = None,
hamming_factor: float = 0.0,
hamming_decay_factor: float = None,
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/hc.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,7 @@
@short_name("hc")
def hill_climb(
problem: Any,
max_iters: int = np.inf,
max_iters: int | float = np.inf,
restarts: int = 0,
init_state: np.ndarray = None,
curve: bool = False,
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/mimic.py
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ def mimic(
keep_pct: float = 0.2,
max_attempts: int = 10,
noise: float = 0.0,
max_iters: int = np.inf,
max_iters: int | float = np.inf,
curve: bool = False,
random_state: int = None,
state_fitness_callback: Callable = None,
6 changes: 3 additions & 3 deletions src/mlrose_ky/algorithms/mutators/__init__.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause

from .change_one_mutator import ChangeOneMutator
from .discrete_mutator import DiscreteMutator
from .gene_swap_mutator import SwapMutator
from .single_gene_mutator import ChangeOneMutator
from .single_shift_mutator import ShiftOneMutator
from .shift_one_mutator import ShiftOneMutator
from .swap_mutator import SwapMutator
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/mutators/_mutator_base.py
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ def __init__(self, opt_prob: Any):
self._length: int = opt_prob.length

@abstractmethod
def mutate(self, child: np.ndarray, mutation_probability: float) -> Any:
def mutate(self, child: np.ndarray, mutation_probability: float) -> np.ndarray:
"""
Apply mutation operation to a given child chromosome based on a mutation probability.
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/rhc.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
def random_hill_climb(
problem: Any,
max_attempts: int = 10,
max_iters: int = np.inf,
max_iters: int | float = np.inf,
restarts: int = 0,
init_state: np.ndarray = None,
curve: bool = False,
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/sa.py
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@ def simulated_annealing(
problem: Any,
schedule: Any = GeomDecay(),
max_attempts: int = 10,
max_iters: int = np.inf,
max_iters: int | float = np.inf,
init_state: np.ndarray = None,
curve: bool = False,
random_state: int = None,
4 changes: 2 additions & 2 deletions src/mlrose_ky/decorators/short_name_decorator.py
Original file line number Diff line number Diff line change
@@ -29,12 +29,12 @@ def short_name(expr: str) -> Callable:
A decorator that assigns the provided short name to a function and returns the function.
"""

def decorator(func: Callable) -> Callable:
def short_name_func_applicator(func: Callable) -> Callable:
"""Assign a short name to the given function."""
func.__short_name__ = expr
return func

return decorator
return short_name_func_applicator


def get_short_name(v: Any) -> str:
2 changes: 1 addition & 1 deletion src/mlrose_ky/gridsearch/grid_search_mixin.py
Original file line number Diff line number Diff line change
@@ -40,7 +40,7 @@ def __init__(self, scorer_method: Callable = None):
self._params: inspect.Signature = inspect.signature(self._scorer_method)
self._get_y_argmax: bool = False

def perform_grid_search(
def _perform_grid_search(
self, classifier: Any, x_train: np.ndarray, y_train: np.ndarray, cv: int, parameters: dict, n_jobs: int = 1, verbose: bool = False
) -> skms.GridSearchCV:
"""
12 changes: 6 additions & 6 deletions src/mlrose_ky/opt_probs/discrete_opt.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
from scipy.sparse.csgraph import minimum_spanning_tree, depth_first_tree
from sklearn.metrics import mutual_info_score

from mlrose_ky.algorithms.crossovers import UniformCrossover, TSPCrossover
from mlrose_ky.algorithms.crossovers import UniformCrossOver, TSPCrossOver
from mlrose_ky.algorithms.mutators import SwapMutator
from mlrose_ky.opt_probs.opt_prob import _OptProb

@@ -34,8 +34,8 @@ class DiscreteOpt(_OptProb):
Number of unique values that each element in the state vector can take.
Assumes values are integers in the range 0 to (max_val - 1), inclusive.
crossover : UniformCrossover | TSPCrossover, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossover`.
crossover : UniformCrossOver | TSPCrossOver, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossOver`.
mutator : SwapMutator, default=None
Mutation operation used for reproduction. If None, defaults to `SwapMutator`.
@@ -54,7 +54,7 @@ class DiscreteOpt(_OptProb):
Problem type; always 'discrete' for this class.
noise : float
Noise factor for probability density estimation.
_crossover : UniformCrossover
_crossover : UniformCrossOver
Crossover operation for reproduction.
_mutator : SwapMutator
Mutation operation for reproduction.
@@ -70,7 +70,7 @@ def __init__(
fitness_fn: Any,
maximize: bool = True,
max_val: int = 2,
crossover: UniformCrossover | TSPCrossover = None,
crossover: UniformCrossOver | TSPCrossOver = None,
mutator: "SwapMutator" = None,
):
self._get_mutual_info_impl = self._get_mutual_info_slow
@@ -100,7 +100,7 @@ def __init__(
self.prob_type: str = "discrete"
self.noise: float = 0

self._crossover: UniformCrossover | TSPCrossover = UniformCrossover(self) if crossover is None else crossover
self._crossover: UniformCrossOver | TSPCrossOver = UniformCrossOver(self) if crossover is None else crossover
self._mutator: SwapMutator = SwapMutator(self) if mutator is None else mutator

self._mut_mask: np.ndarray | None = None
10 changes: 5 additions & 5 deletions src/mlrose_ky/opt_probs/flip_flop_opt.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

import numpy as np

from mlrose_ky.algorithms.crossovers import OnePointCrossover
from mlrose_ky.algorithms.crossovers import OnePointCrossOver
from mlrose_ky.algorithms.mutators import ChangeOneMutator
from mlrose_ky.fitness import FlipFlop
from mlrose_ky.opt_probs.discrete_opt import DiscreteOpt
@@ -27,8 +27,8 @@ class FlipFlopOpt(DiscreteOpt):
maximize : bool, default=True
Whether to maximize the fitness function. Set :code:`False` for minimization problems.
crossover : OnePointCrossover, default=None
Crossover operation used for reproduction. If None, defaults to `OnePointCrossover`.
crossover : OnePointCrossOver, default=None
Crossover operation used for reproduction. If None, defaults to `OnePointCrossOver`.
mutator : ChangeOneMutator, default=None
Mutation operation used for reproduction. If None, defaults to `ChangeOneMutator`.
@@ -56,7 +56,7 @@ def __init__(
length: int = None,
fitness_fn: Any = None,
maximize: bool = True,
crossover: "OnePointCrossover" = None,
crossover: "OnePointCrossOver" = None,
mutator: "ChangeOneMutator" = None,
):
if (fitness_fn is None) and (length is None):
@@ -71,7 +71,7 @@ def __init__(
fitness_fn = FlipFlop()

self.max_val: int = 2
crossover = OnePointCrossover(self) if crossover is None else crossover
crossover = OnePointCrossOver(self) if crossover is None else crossover
mutator = ChangeOneMutator(self) if mutator is None else mutator

super().__init__(length, fitness_fn, maximize, crossover=crossover, mutator=mutator)
10 changes: 5 additions & 5 deletions src/mlrose_ky/opt_probs/knapsack_opt.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

from typing import Any

from mlrose_ky.algorithms.crossovers import UniformCrossover
from mlrose_ky.algorithms.crossovers import UniformCrossOver
from mlrose_ky.algorithms.mutators import ChangeOneMutator
from mlrose_ky.fitness.knapsack import Knapsack
from mlrose_ky.opt_probs.discrete_opt import DiscreteOpt
@@ -37,8 +37,8 @@ class KnapsackOpt(DiscreteOpt):
max_weight_pct : float, default=0.35
Maximum allowable weight as a percentage of the total weight.
crossover : UniformCrossover, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossover`.
crossover : UniformCrossOver, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossOver`.
mutator : ChangeOneMutator, default=None
Mutation operation used for reproduction. If None, defaults to `ChangeOneMutator`.
@@ -67,7 +67,7 @@ def __init__(
weights: list[float] = None,
values: list[float] = None,
max_weight_pct: float = 0.35,
crossover: "UniformCrossover" = None,
crossover: "UniformCrossOver" = None,
mutator: "ChangeOneMutator" = None,
multiply_by_max_item_count: bool = False,
):
@@ -94,7 +94,7 @@ def __init__(
multiply_by_max_item_count=multiply_by_max_item_count,
)

crossover = UniformCrossover(self) if crossover is None else crossover
crossover = UniformCrossOver(self) if crossover is None else crossover
mutator = ChangeOneMutator(self) if mutator is None else mutator

super().__init__(length, fitness_fn, maximize, max_val, crossover, mutator)
10 changes: 5 additions & 5 deletions src/mlrose_ky/opt_probs/max_k_color_opt.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
import networkx as nx
import numpy as np

from mlrose_ky.algorithms.crossovers import UniformCrossover
from mlrose_ky.algorithms.crossovers import UniformCrossOver
from mlrose_ky.algorithms.mutators import ChangeOneMutator
from mlrose_ky.fitness import MaxKColor
from mlrose_ky.opt_probs.discrete_opt import DiscreteOpt
@@ -34,8 +34,8 @@ class MaxKColorOpt(DiscreteOpt):
max_colors : int, default=None
Maximum number of colors to use for coloring the graph.
crossover : UniformCrossover, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossover`.
crossover : UniformCrossOver, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossOver`.
mutator : ChangeOneMutator, default=None
Mutation operation used for reproduction. If None, defaults to `ChangeOneMutator`.
@@ -68,7 +68,7 @@ def __init__(
fitness_fn: Any = None,
maximize: bool = False,
max_colors: int = None,
crossover: "UniformCrossover" = None,
crossover: "UniformCrossOver" = None,
mutator: "ChangeOneMutator" = None,
source_graph: nx.Graph = None,
):
@@ -126,7 +126,7 @@ def __init__(
self.max_val: int = max_colors

# Use default crossover and mutator if none are provided
crossover = UniformCrossover(self) if crossover is None else crossover
crossover = UniformCrossOver(self) if crossover is None else crossover
mutator = ChangeOneMutator(self) if mutator is None else mutator
super().__init__(length, fitness_fn, maximize, max_colors, crossover, mutator)

10 changes: 5 additions & 5 deletions src/mlrose_ky/opt_probs/queens_opt.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

import numpy as np

from mlrose_ky.algorithms.crossovers import UniformCrossover
from mlrose_ky.algorithms.crossovers import UniformCrossOver
from mlrose_ky.algorithms.mutators import ChangeOneMutator
from mlrose_ky.fitness.queens import Queens
from mlrose_ky.opt_probs.discrete_opt import DiscreteOpt
@@ -27,8 +27,8 @@ class QueensOpt(DiscreteOpt):
maximize : bool, default=False
Whether to maximize the fitness function. Set :code:`False` for minimization problems.
crossover : UniformCrossover, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossover`.
crossover : UniformCrossOver, default=None
Crossover operation used for reproduction. If None, defaults to `UniformCrossOver`.
mutator : ChangeOneMutator, default=None
Mutation operation used for reproduction. If None, defaults to `ChangeOneMutator`.
@@ -53,7 +53,7 @@ def __init__(
length: int = None,
fitness_fn: Any = None,
maximize: bool = False,
crossover: "UniformCrossover" = None,
crossover: "UniformCrossOver" = None,
mutator: "ChangeOneMutator" = None,
):
# Ensure that either fitness_fn or length is provided
@@ -77,7 +77,7 @@ def __init__(
self.max_val: int = length

# Use default crossover and mutator if none are provided
crossover = UniformCrossover(self) if crossover is None else crossover
crossover = UniformCrossOver(self) if crossover is None else crossover
mutator = ChangeOneMutator(self) if mutator is None else mutator
super().__init__(length, fitness_fn, maximize, length, crossover, mutator)

6 changes: 3 additions & 3 deletions src/mlrose_ky/opt_probs/tsp_opt.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@

import numpy as np

from mlrose_ky.algorithms.crossovers import TSPCrossover
from mlrose_ky.algorithms.crossovers import TSPCrossOver
from mlrose_ky.algorithms.mutators import SwapMutator
from mlrose_ky.fitness import TravellingSales
from mlrose_ky.opt_probs.discrete_opt import DiscreteOpt
@@ -69,8 +69,8 @@ def __init__(

self.length: int = length

# Initialize the parent class with the TSPCrossover and SwapMutator
super().__init__(length, fitness_fn, maximize, max_val=length, crossover=TSPCrossover(self), mutator=SwapMutator(self))
# Initialize the parent class with the TSPCrossOver and SwapMutator
super().__init__(length, fitness_fn, maximize, max_val=length, crossover=TSPCrossOver(self), mutator=SwapMutator(self))

# Ensure that the fitness function type is 'tsp'
if self.fitness_fn.get_prob_type() != "tsp":
13 changes: 1 addition & 12 deletions src/mlrose_ky/runners/_nn_runner_base.py
Original file line number Diff line number Diff line change
@@ -150,17 +150,6 @@ def __init__(
self.cv_results_df: pd.DataFrame | None = None
self.best_params: dict | None = None

def dynamic_runner_name(self) -> str:
"""
Generates a dynamic name for the runner based on the class name and experiment name.
Returns
-------
str
The dynamic name for the runner.
"""
return f"{self.__class__.__name__}_{self._experiment_name}"

def run(self) -> tuple[pd.DataFrame | None, pd.DataFrame | None, pd.DataFrame | None, Any | None]:
"""
Executes the runner, performing grid search and handling the results.
@@ -182,7 +171,7 @@ def run(self) -> tuple[pd.DataFrame | None, pd.DataFrame | None, pd.DataFrame |
search_results = pk.load(pickle_file)
else:
run_start = time.perf_counter()
search_results = self.perform_grid_search(
search_results = self._perform_grid_search(
classifier=self.classifier,
parameters=self.grid_search_parameters,
x_train=self.x_train,
14 changes: 7 additions & 7 deletions src/mlrose_ky/runners/_runner_base.py
Original file line number Diff line number Diff line change
@@ -53,20 +53,20 @@ class _RunnerBase(ABC):
_sigint_params: tuple[int, Any] | None = None

@classmethod
def get_runner_name(cls) -> str:
def runner_name(cls) -> str:
"""Get a short name for the runner class."""
return get_short_name(cls)

def get_dynamic_runner_name(self) -> str:
def dynamic_runner_name(self) -> str:
"""Get the dynamic name of the runner, if set, otherwise return the default runner name."""
dynamic_runner_name = self._dynamic_short_name or self.get_runner_name()
dynamic_runner_name = self._dynamic_short_name or self.runner_name()

if not dynamic_runner_name:
raise ValueError("dynamic_runner_name is None")

return dynamic_runner_name

def set_dynamic_runner_name(self, name: str):
def _set_dynamic_runner_name(self, name: str):
"""Set a dynamic runner name."""
self._dynamic_short_name = name

@@ -285,7 +285,7 @@ def run_experiment(self, algorithm: Any, **kwargs: Any) -> tuple[pd.DataFrame |

value_sets = list(itertools.product(*values))

logging.info(f"Running {self.get_dynamic_runner_name()}")
logging.info(f"Running {self.dynamic_runner_name()}")
run_start = time.perf_counter()

for value_set in value_sets:
@@ -380,7 +380,7 @@ def _get_pickle_filename_root(self, name: str) -> str:
"""Generate the root filename for the pickle file based on experiment metadata."""
return build_data_filename(
output_directory=self._output_directory,
runner_name=self.get_dynamic_runner_name(),
runner_name=self.dynamic_runner_name(),
experiment_name=self._experiment_name,
df_name=name,
)
@@ -598,7 +598,7 @@ def save_state(
logging.debug(data_desc)

logging.debug(
f"runner_name:[{self.get_dynamic_runner_name()}], experiment_name:[{self._experiment_name}], "
f"runner_name:[{self.dynamic_runner_name()}], experiment_name:[{self._experiment_name}], "
+ ("" if attempt is None else f"attempt:[{attempt}], ")
+ f"iteration:[{iteration}], done:[{done}], "
f"time:[{t:.2f}], fitness:[{fitness:.4f}]"
2 changes: 1 addition & 1 deletion src/mlrose_ky/runners/nngs_runner.py
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@ def __init__(
)

# Update short name based on the algorithm
self.set_dynamic_runner_name(f"{get_short_name(self)}_{get_short_name(algorithm)}")
self._set_dynamic_runner_name(f"{get_short_name(self)}_{get_short_name(algorithm)}")

def run_one_experiment_(self, algorithm: Any, total_args: dict, **params: dict) -> tuple | None:
"""
8 changes: 4 additions & 4 deletions tests/test_gridsearch.py
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ def test_perform_grid_search(self, grid_search_mixin, sample_data, dummy_classif
"""Should perform grid search with a classifier and return GridSearchCV object"""
X_train, X_test, y_train, y_test = sample_data

search_results = grid_search_mixin.perform_grid_search(
search_results = grid_search_mixin._perform_grid_search(
classifier=dummy_classifier, x_train=X_train, y_train=y_train, cv=3, parameters=param_grid
)

@@ -79,7 +79,7 @@ def test_perform_grid_search(self, grid_search_mixin, sample_data, dummy_classif
def test_handle_empty_input(self, grid_search_mixin):
"""Should handle empty input data gracefully"""
with pytest.raises(ValueError):
grid_search_mixin.perform_grid_search(
grid_search_mixin._perform_grid_search(
classifier=DummyClassifier(), x_train=np.array([]), y_train=np.array([]), cv=3, parameters={"strategy": ["most_frequent"]}
)

@@ -172,7 +172,7 @@ def test_perform_grid_search_with_verbose(self, grid_search_mixin, sample_data,
X_train, X_test, y_train, y_test = sample_data

# Perform grid search with verbose output enabled
search_results = grid_search_mixin.perform_grid_search(
search_results = grid_search_mixin._perform_grid_search(
dummy_classifier, X_train, y_train, cv=3, parameters=grid_search_parameters, verbose=True
)

@@ -187,7 +187,7 @@ def test_perform_grid_search_with_multiple_jobs(self, grid_search_mixin, sample_
X_train, X_test, y_train, y_test = sample_data

# Perform grid search with n_jobs set to 2
search_results = grid_search_mixin.perform_grid_search(
search_results = grid_search_mixin._perform_grid_search(
dummy_classifier, X_train, y_train, cv=3, parameters=grid_search_parameters, n_jobs=2
)

4 changes: 2 additions & 2 deletions tests/test_opt_probs/test_discrete_opt.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
import mlrose_ky
from mlrose_ky.opt_probs import DiscreteOpt
from mlrose_ky.fitness import OneMax
from mlrose_ky.algorithms import OnePointCrossover
from mlrose_ky.algorithms import OnePointCrossOver


class TestDiscreteOpt:
@@ -164,7 +164,7 @@ def test_reproduce_mut1_max2(self):
def test_reproduce_mut1_max_gt2(self):
"""Test reproduce method when mutation_prob is 1 and max_val is greater than 2"""
problem = DiscreteOpt(5, OneMax(), max_val=3)
problem._crossover = OnePointCrossover(problem)
problem._crossover = OnePointCrossOver(problem)
father = np.zeros(5)
mother = np.ones(5) * 2
child = problem.reproduce(father, mother, mutation_prob=1)
2 changes: 1 addition & 1 deletion tests/test_runners/test_ga_runner.py
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ def test_garunner_initialization_with_additional_kwargs(self, problem, runner_kw
runner = GARunner(**runner_kwargs, **additional_kwargs)

assert runner.problem == problem
assert runner.get_runner_name() == "ga"
assert runner.runner_name() == "ga"
assert runner._experiment_name == runner_kwargs["experiment_name"]
assert runner.seed == runner_kwargs["seed"]
assert runner.iteration_list == runner_kwargs["iteration_list"]
2 changes: 1 addition & 1 deletion tests/test_runners/test_mimic_runner.py
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ def test_mimicrunner_initialization_with_additional_kwargs(self, problem, runner
runner = MIMICRunner(**runner_kwargs, **additional_kwargs)

assert runner.problem == problem
assert runner.get_runner_name() == "mimic"
assert runner.runner_name() == "mimic"
assert runner._experiment_name == runner_kwargs["experiment_name"]
assert runner.seed == runner_kwargs["seed"]
assert runner.iteration_list == runner_kwargs["iteration_list"]
4 changes: 2 additions & 2 deletions tests/test_runners/test_nn_runner_base.py
Original file line number Diff line number Diff line change
@@ -96,7 +96,7 @@ def test_nn_runner_base_run_method(self):

with (
patch.object(runner, "_setup", return_value=None) as mock_setup,
patch.object(runner, "perform_grid_search", return_value=mock_grid_search_result) as mock_grid_search,
patch.object(runner, "_perform_grid_search", return_value=mock_grid_search_result) as mock_grid_search,
patch.object(runner, "_tear_down", return_value=None) as mock_tear_down,
patch.object(runner, "_print_banner", return_value=None) as mock_print_banner,
):
@@ -127,7 +127,7 @@ def test_nn_runner_base_teardown_removes_files(self):
output_directory="test_output",
)

runner.get_runner_name = MagicMock(return_value="TestRunner")
runner.runner_name = MagicMock(return_value="TestRunner")
runner.best_params = {"param1": 0.1, "param2": 1}
runner._output_directory = "test_output"
runner.replay_mode = MagicMock(return_value=False)
2 changes: 1 addition & 1 deletion tests/test_runners/test_rhc_runner.py
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ def test_rhc_runner_initialization_with_additional_kwargs(self, problem, runner_
runner = RHCRunner(**runner_kwargs, **additional_kwargs)

assert runner.problem == problem
assert runner.get_runner_name() == "rhc"
assert runner.runner_name() == "rhc"
assert runner._experiment_name == runner_kwargs["experiment_name"]
assert runner.seed == runner_kwargs["seed"]
assert runner.iteration_list == runner_kwargs["iteration_list"]
2 changes: 1 addition & 1 deletion tests/test_runners/test_sa_runner.py
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ def test_sarunner_initialization_with_additional_kwargs(self, problem, runner_kw
runner = SARunner(**runner_kwargs, **additional_kwargs)

assert runner.problem == problem
assert runner.get_runner_name() == "sa"
assert runner.runner_name() == "sa"
assert runner._experiment_name == runner_kwargs["experiment_name"]
assert runner.seed == runner_kwargs["seed"]
assert runner.iteration_list == runner_kwargs["iteration_list"]
4 changes: 2 additions & 2 deletions tests/test_runners/test_skmlp_runner.py
Original file line number Diff line number Diff line change
@@ -83,7 +83,7 @@ def test_dynamic_runner_name(self, runner_kwargs):
"""Test that the runner name is set dynamically based on the algorithm."""
runner = SKMLPRunner(**runner_kwargs)
expected_name = "skmlp"
assert runner.get_runner_name() == expected_name
assert runner.runner_name() == expected_name

def test_grid_search_scorer_method(self, runner):
"""Test that the grid search scorer method is set correctly."""
@@ -102,6 +102,6 @@ def test_skmlp_runner_initialization_with_additional_kwargs(self, runner_kwargs)
additional_kwargs = {"custom_arg": "custom_value"}
runner = SKMLPRunner(**runner_kwargs, **additional_kwargs)

assert runner.get_runner_name() == "skmlp"
assert runner.runner_name() == "skmlp"
assert runner.classifier.mlp.early_stopping == runner_kwargs["early_stopping"]
assert runner.classifier.mlp.random_state == SEED

0 comments on commit 6d92a16

Please sign in to comment.