Skip to content

Commit

Permalink
Refactor .runners: GA, MIMIC, SA, RHC (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
knakamura13 committed Sep 5, 2024
1 parent e51ea60 commit 084844e
Show file tree
Hide file tree
Showing 39 changed files with 403 additions and 172 deletions.
2 changes: 1 addition & 1 deletion src/mlrose_ky/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""MLROSe initialization file."""
"""mlrose-ky initialization file."""

# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/crossovers/_crossover_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class _CrossoverBase(ABC):
'length' property.
"""

def __init__(self, optimization_problem: Any) -> None:
def __init__(self, optimization_problem: Any):
"""
Initialize the CrossoverBase with the given optimization problem.
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/crossovers/one_point_crossover.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class OnePointCrossover(_CrossoverBase):
_CrossoverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any) -> None:
def __init__(self, optimization_problem: Any):
"""
Initialize the OnePointCrossover with the given optimization problem.
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/crossovers/tsp_crossover.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TSPCrossover(_CrossoverBase):
_CrossoverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any) -> None:
def __init__(self, optimization_problem: Any):
"""
Initialize the TSPCrossover with the given optimization problem.
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/crossovers/uniform_crossover.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class UniformCrossover(_CrossoverBase):
_CrossoverBase : Abstract base class for crossover operations.
"""

def __init__(self, optimization_problem: Any) -> None:
def __init__(self, optimization_problem: Any):
"""
Initialize the UniformCrossover with the given optimization problem.
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/decay/arithmetic_decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ArithDecay:
5.25
"""

def __init__(self, init_temp: float = 1.0, decay: float = 0.0001, min_temp: float = 0.001) -> None:
def __init__(self, init_temp: float = 1.0, decay: float = 0.0001, min_temp: float = 0.001):
self.init_temp: float = init_temp
self.decay: float = decay
self.min_temp: float = min_temp
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/decay/custom_decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CustomSchedule:
15
"""

def __init__(self, schedule: Callable[..., float], **kwargs) -> None:
def __init__(self, schedule: Callable[..., float], **kwargs):
self.schedule: Callable[..., float] = schedule
self.kwargs: dict = kwargs

Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/decay/exponential_decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ExpDecay:
7.788007830714049
"""

def __init__(self, init_temp: float = 1.0, exp_const: float = 0.005, min_temp: float = 0.001) -> None:
def __init__(self, init_temp: float = 1.0, exp_const: float = 0.005, min_temp: float = 0.001):
self.init_temp: float = init_temp
self.exp_const: float = exp_const
self.min_temp: float = min_temp
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/decay/geometric_decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GeomDecay:
7.737809374999998
"""

def __init__(self, init_temp: float = 1.0, decay: float = 0.99, min_temp: float = 0.001) -> None:
def __init__(self, init_temp: float = 1.0, decay: float = 0.99, min_temp: float = 0.001):
self.init_temp: float = init_temp
self.decay: float = decay
self.min_temp: float = min_temp
Expand Down
3 changes: 2 additions & 1 deletion src/mlrose_ky/algorithms/mutators/_mutator_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ class _MutatorBase(ABC):
An instance of an optimization problem that the mutator will operate on.
"""

def __init__(self, opt_prob: Any) -> None:
def __init__(self, opt_prob: Any):
super().__init__()

self._opt_prob: Any = opt_prob
self._length: int = opt_prob.length

Expand Down
3 changes: 2 additions & 1 deletion src/mlrose_ky/algorithms/mutators/discrete_mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class DiscreteMutator(_MutatorBase):
An instance of an optimization problem that the mutator will operate on.
"""

def __init__(self, opt_prob: Any) -> None:
def __init__(self, opt_prob: Any):
super().__init__(opt_prob)

self._max_val: int = opt_prob.max_val

def mutate(self, child: np.ndarray, mutation_probability: float) -> np.ndarray:
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/algorithms/mutators/gene_swap_mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SwapMutator(_MutatorBase):
An instance of an optimization problem that the mutator will operate on.
"""

def __init__(self, opt_prob: Any) -> None:
def __init__(self, opt_prob: Any):
super().__init__(opt_prob)

def mutate(self, child: np.ndarray, mutation_probability: float) -> np.ndarray:
Expand Down
3 changes: 2 additions & 1 deletion src/mlrose_ky/algorithms/mutators/single_gene_mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ class ChangeOneMutator(_MutatorBase):
An instance of an optimization problem that the mutator will operate on.
"""

def __init__(self, opt_prob: Any) -> None:
def __init__(self, opt_prob: Any):
super().__init__(opt_prob)

self._max_val: int = opt_prob.max_val

def mutate(self, child: np.ndarray, mutation_probability: float) -> np.ndarray:
Expand Down
3 changes: 2 additions & 1 deletion src/mlrose_ky/algorithms/mutators/single_shift_mutator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class ShiftOneMutator(_MutatorBase):
An instance of an optimization problem that the mutator will operate on.
"""

def __init__(self, opt_prob: Any) -> None:
def __init__(self, opt_prob: Any):
super().__init__(opt_prob)

self._max_val: int = opt_prob.max_val

def mutate(self, child: np.ndarray, mutation_probability: float) -> np.ndarray:
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/fitness/continuous_peaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ContinuousPeaks:
with `max_val = 2`) optimization problems only.
"""

def __init__(self, t_pct: float = 0.1) -> None:
def __init__(self, t_pct: float = 0.1):
self.t_pct: float = t_pct
self.prob_type: str = "discrete"

Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/fitness/max_k_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def get_prob_type(self) -> str:
"""
return self.prob_type

def set_graph(self, graph) -> None:
def set_graph(self, graph):
"""Set the graph edges from an external graph representation.
Parameters
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/fitness/one_max.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class OneMax:
The One Max fitness function is suitable for use in either discrete or continuous-state optimization problems.
"""

def __init__(self) -> None:
def __init__(self):
self.prob_type: str = "either"

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/fitness/travelling_salesperson.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TravellingSalesperson:
fitness function object.
"""

def __init__(self, coords: list[tuple] = None, distances: list[tuple] = None) -> None:
def __init__(self, coords: list[tuple] = None, distances: list[tuple] = None):
# Ensure that at least one of coords or distances is provided
if coords is None and distances is None:
raise ValueError("At least one of coords and distances must be specified.")
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/gridsearch/grid_search_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class GridSearchMixin:
Flag indicating whether to apply argmax to predictions and ground truths before scoring.
"""

def __init__(self, scorer_method: Callable = None) -> None:
def __init__(self, scorer_method: Callable = None):
"""
Initializes the GridSearchMixin with a specified scoring method.
Expand Down
2 changes: 1 addition & 1 deletion src/mlrose_ky/neural/_nn_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def __init__(self):
pass

@abstractmethod
def fit(self, X: np.ndarray, y: np.ndarray = None, init_weights: np.ndarray = None) -> None:
def fit(self, X: np.ndarray, y: np.ndarray = None, init_weights: np.ndarray = None):
"""
Fit the neural network to the data.
Expand Down
5 changes: 3 additions & 2 deletions src/mlrose_ky/neural/_nn_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import numpy as np
from sklearn.preprocessing import LabelBinarizer

from mlrose_ky.algorithms.decay import GeomDecay
from mlrose_ky.algorithms.ga import genetic_alg
from mlrose_ky.algorithms.rhc import random_hill_climb
Expand Down Expand Up @@ -71,7 +72,7 @@ def __init__(
self.predicted_probs: np.ndarray = np.array([])
self.fitness_curve: list[float] = []

def _validate(self) -> None:
def _validate(self):
"""Validate the model parameters."""
if (not isinstance(self.max_iters, int) and self.max_iters != np.inf) or self.max_iters < 0:
raise ValueError(f"max_iters must be a positive integer, got {self.max_iters}.")
Expand Down Expand Up @@ -109,7 +110,7 @@ def _validate(self) -> None:
f"'random_hill_climb', 'simulated_annealing', 'genetic_alg', 'gradient_descent', got {self.algorithm}."
)

def _validate_input(self, y: np.ndarray) -> None:
def _validate_input(self, y: np.ndarray):
"""
Add classes_ attribute based on classes present in y.
Expand Down
1 change: 1 addition & 0 deletions src/mlrose_ky/neural/activation/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# License: BSD 3-clause

import warnings

import numpy as np

from mlrose_ky.decorators import short_name
Expand Down
1 change: 1 addition & 0 deletions src/mlrose_ky/neural/linear_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# License: BSD 3-clause

from sklearn.base import RegressorMixin

from mlrose_ky.algorithms.decay import GeomDecay
from ._nn_core import _NNCore

Expand Down
4 changes: 3 additions & 1 deletion src/mlrose_ky/neural/nn_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause

from typing import Any, Optional, Callable

import numpy as np

from mlrose_ky.neural._nn_base import _NNBase
from typing import Any, Optional, Callable


class NNClassifier(_NNBase):
Expand Down
13 changes: 7 additions & 6 deletions src/mlrose_ky/opt_probs/continuous_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

from typing import Any

# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause

import numpy as np

from mlrose_ky.opt_probs.opt_prob import _OptProb


# Authors: Genevieve Hayes (modified by Andrew Rollings, Kyle Nakamura)
# License: BSD 3-clause


class ContinuousOpt(_OptProb):
"""Class for defining continuous-state optimization problems.
Expand Down Expand Up @@ -77,7 +78,7 @@ def calculate_updates(self) -> list:
"""
return self.fitness_fn.calculate_updates()

def find_neighbors(self) -> None:
def find_neighbors(self):
"""Find all neighbors of the current state."""
# Pre-allocate a NumPy array for neighbors (maximum of 2 * length neighbors)
neighbors_matrix = np.zeros((2 * self.length, self.length))
Expand Down Expand Up @@ -145,7 +146,7 @@ def random_neighbor(self) -> np.ndarray:

return neighbor

def random_pop(self, pop_size: int) -> None:
def random_pop(self, pop_size: int):
"""Create a population of random state vectors.
Parameters
Expand Down Expand Up @@ -221,7 +222,7 @@ def reproduce(self, parent_1: np.ndarray, parent_2: np.ndarray, mutation_prob: f

return child

def reset(self) -> None:
def reset(self):
"""Set the current state vector to a random value and reset its fitness."""
self.state = self.random()
self.fitness_evaluations = 0
Expand Down
14 changes: 7 additions & 7 deletions src/mlrose_ky/opt_probs/discrete_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def __init__(
self._mut_mask: np.ndarray | None = None
self._mut_inf: np.ndarray | None = None

def eval_node_probs(self) -> None:
def eval_node_probs(self):
"""Update probability density estimates."""
mutual_info = self._get_mutual_info_impl()

Expand Down Expand Up @@ -143,7 +143,7 @@ def eval_node_probs(self) -> None:
self.node_probs = probs
self.parent_nodes = parent

def set_mimic_fast_mode(self, fast_mode: bool) -> None:
def set_mimic_fast_mode(self, fast_mode: bool):
"""Enable or disable MIMIC fast mode."""
if fast_mode:
mut_mask = np.zeros([self.length, self.length], dtype=bool)
Expand Down Expand Up @@ -214,7 +214,7 @@ def _get_mutual_info_fast(self) -> np.ndarray:

return mutual_info

def find_neighbors(self) -> None:
def find_neighbors(self):
"""Find all neighbors of the current state."""
self.neighbors = []

Expand All @@ -233,7 +233,7 @@ def find_neighbors(self) -> None:
neighbor[i] = j
self.neighbors.append(neighbor)

def find_sample_order(self) -> None:
def find_sample_order(self):
"""Determine order in which to generate sample vector elements."""
sample_order = []
last = [0]
Expand All @@ -253,7 +253,7 @@ def find_sample_order(self) -> None:

self.sample_order = sample_order

def find_top_pct(self, keep_pct: float) -> None:
def find_top_pct(self, keep_pct: float):
"""Select samples with fitness in the top keep_pct percentile.
Parameters
Expand Down Expand Up @@ -318,7 +318,7 @@ def random_neighbor(self) -> np.ndarray:

return neighbor

def random_pop(self, pop_size: int) -> None:
def random_pop(self, pop_size: int):
"""Create a population of random state vectors.
Parameters
Expand Down Expand Up @@ -367,7 +367,7 @@ def reproduce(self, parent_1: np.ndarray, parent_2: np.ndarray, mutation_prob: f
child = self._crossover.mate(parent_1, parent_2)
return self._mutator.mutate(child, mutation_prob)

def reset(self) -> None:
def reset(self):
"""Set the current state vector to a random value and get its fitness."""
self.state = self.random()
self.fitness = self.eval_fitness(self.state)
Expand Down
4 changes: 2 additions & 2 deletions src/mlrose_ky/opt_probs/flip_flop_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ def __init__(
state = np.random.randint(2, size=self.length)
self.set_state(state)

def evaluate_population_fitness(self) -> None:
def evaluate_population_fitness(self):
"""Calculate fitness for the current population."""
self.pop_fitness = self.fitness_fn.evaluate_many(self.population)

def random_pop(self, pop_size: int) -> None:
def random_pop(self, pop_size: int):
"""Create a population of random state vectors.
Parameters
Expand Down
8 changes: 4 additions & 4 deletions src/mlrose_ky/opt_probs/opt_prob.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def eval_fitness(self, state: np.ndarray) -> float:
self.fitness_evaluations += 1
return fitness

def eval_mate_probs(self) -> None:
def eval_mate_probs(self):
"""Calculate the probability of each member of the population reproducing."""
pop_fitness = np.copy(self.pop_fitness)

Expand Down Expand Up @@ -210,7 +210,7 @@ def get_state(self) -> np.ndarray:
"""
return self.state

def set_population(self, new_population: np.ndarray) -> None:
def set_population(self, new_population: np.ndarray):
"""Set a new population and evaluate its fitness.
Parameters
Expand All @@ -221,11 +221,11 @@ def set_population(self, new_population: np.ndarray) -> None:
self.population = new_population
self.evaluate_population_fitness()

def evaluate_population_fitness(self) -> None:
def evaluate_population_fitness(self):
"""Evaluate the fitness of the current population."""
self.pop_fitness = np.array([self.eval_fitness(indiv) for indiv in self.population])

def set_state(self, new_state: np.ndarray) -> None:
def set_state(self, new_state: np.ndarray):
"""Set a new state vector and evaluate its fitness.
Parameters
Expand Down
Loading

0 comments on commit 084844e

Please sign in to comment.