Another attempt at this maddess
This commit is contained in:
@ -7,7 +7,7 @@ import EasyGA.decorators
|
|||||||
# Import all the data structure prebuilt modules
|
# Import all the data structure prebuilt modules
|
||||||
from EasyGA.structure import Population as make_population
|
from EasyGA.structure import Population as make_population
|
||||||
from EasyGA.structure import Chromosome as make_chromosome
|
from EasyGA.structure import Chromosome as make_chromosome
|
||||||
from EasyGA.structure import Gene as make_gene
|
from EasyGA.structure import Gene as make_gene
|
||||||
from EasyGA.structure import Population
|
from EasyGA.structure import Population
|
||||||
from EasyGA.structure import Chromosome
|
from EasyGA.structure import Chromosome
|
||||||
from EasyGA.structure import Gene
|
from EasyGA.structure import Gene
|
||||||
@ -17,23 +17,23 @@ from EasyGA.examples import Fitness
|
|||||||
from EasyGA.termination import Termination
|
from EasyGA.termination import Termination
|
||||||
|
|
||||||
# Parent/Survivor Selection Methods
|
# Parent/Survivor Selection Methods
|
||||||
from EasyGA.parent import Parent
|
from EasyGA.parent import Parent
|
||||||
from EasyGA.survivor import Survivor
|
from EasyGA.survivor import Survivor
|
||||||
|
|
||||||
# Genetic Operator Methods
|
# Genetic Operator Methods
|
||||||
from EasyGA.crossover import Crossover
|
from EasyGA.crossover import Crossover
|
||||||
from EasyGA.mutation import Mutation
|
from EasyGA.mutation import Mutation
|
||||||
|
|
||||||
# Default Attributes for the GA
|
# Default Attributes for the GA
|
||||||
from EasyGA.attributes import Attributes
|
from EasyGA.attributes import Attributes
|
||||||
|
|
||||||
# Database class
|
# Database class
|
||||||
from EasyGA.database import sql_database
|
# from EasyGA.database import sql_database
|
||||||
from sqlite3 import Error
|
# from sqlite3 import Error
|
||||||
|
|
||||||
# Graphing package
|
# Graphing package
|
||||||
from EasyGA.database import matplotlib_graph
|
# from EasyGA.database import matplotlib_graph
|
||||||
import matplotlib.pyplot as plt
|
# import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
class GA(Attributes):
|
class GA(Attributes):
|
||||||
@ -46,7 +46,6 @@ class GA(Attributes):
|
|||||||
https://github.com/danielwilczak101/EasyGA/wiki
|
https://github.com/danielwilczak101/EasyGA/wiki
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def evolve(self: GA, number_of_generations: float = float('inf'), consider_termination: bool = True) -> None:
|
def evolve(self: GA, number_of_generations: float = float('inf'), consider_termination: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Evolves the ga until the ga is no longer active.
|
Evolves the ga until the ga is no longer active.
|
||||||
@ -63,9 +62,12 @@ class GA(Attributes):
|
|||||||
if self.population is None:
|
if self.population is None:
|
||||||
self.initialize_population()
|
self.initialize_population()
|
||||||
|
|
||||||
cond1 = lambda: number_of_generations > 0 # Evolve the specified number of generations.
|
# Evolve the specified number of generations.
|
||||||
cond2 = lambda: not consider_termination # If consider_termination flag is set:
|
def cond1(): return number_of_generations > 0
|
||||||
cond3 = lambda: cond2() or self.active() # check termination conditions.
|
# If consider_termination flag is set:
|
||||||
|
def cond2(): return not consider_termination
|
||||||
|
# check termination conditions.
|
||||||
|
def cond3(): return cond2() or self.active()
|
||||||
|
|
||||||
while cond1() and cond3():
|
while cond1() and cond3():
|
||||||
|
|
||||||
@ -74,12 +76,13 @@ class GA(Attributes):
|
|||||||
|
|
||||||
# Create the database here to allow the user to change the
|
# Create the database here to allow the user to change the
|
||||||
# database name and structure before running the function.
|
# database name and structure before running the function.
|
||||||
self.database.create_all_tables(self)
|
# self.database.create_all_tables(self)
|
||||||
|
|
||||||
# Add the current configuration to the config table
|
# Add the current configuration to the config table
|
||||||
self.database.insert_config(self)
|
# self.database.insert_config(self)
|
||||||
|
pass
|
||||||
|
|
||||||
# Otherwise evolve the population.
|
# Otherwise evolve the population.
|
||||||
else:
|
else:
|
||||||
self.parent_selection_impl()
|
self.parent_selection_impl()
|
||||||
self.crossover_population_impl()
|
self.crossover_population_impl()
|
||||||
@ -93,7 +96,7 @@ class GA(Attributes):
|
|||||||
self.sort_by_best_fitness()
|
self.sort_by_best_fitness()
|
||||||
|
|
||||||
# Save the population to the database
|
# Save the population to the database
|
||||||
self.save_population()
|
# self.save_population()
|
||||||
|
|
||||||
# Adapt the ga if the generation times the adapt rate
|
# Adapt the ga if the generation times the adapt rate
|
||||||
# passes through an integer value.
|
# passes through an integer value.
|
||||||
@ -101,10 +104,9 @@ class GA(Attributes):
|
|||||||
if int(adapt_counter) < int(adapt_counter + self.adapt_rate):
|
if int(adapt_counter) < int(adapt_counter + self.adapt_rate):
|
||||||
self.adapt()
|
self.adapt()
|
||||||
|
|
||||||
number_of_generations -= 1
|
number_of_generations -= 1
|
||||||
self.current_generation += 1
|
self.current_generation += 1
|
||||||
|
|
||||||
|
|
||||||
def update_population(self: GA) -> None:
|
def update_population(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
Updates the population to the new population
|
Updates the population to the new population
|
||||||
@ -112,7 +114,6 @@ class GA(Attributes):
|
|||||||
"""
|
"""
|
||||||
self.population.update()
|
self.population.update()
|
||||||
|
|
||||||
|
|
||||||
def reset_run(self: GA) -> None:
|
def reset_run(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
Resets a run by re-initializing the
|
Resets a run by re-initializing the
|
||||||
@ -122,7 +123,6 @@ class GA(Attributes):
|
|||||||
self.current_generation = 0
|
self.current_generation = 0
|
||||||
self.run += 1
|
self.run += 1
|
||||||
|
|
||||||
|
|
||||||
def adapt(self: GA) -> None:
|
def adapt(self: GA) -> None:
|
||||||
"""Adapts the ga to hopefully get better results."""
|
"""Adapts the ga to hopefully get better results."""
|
||||||
|
|
||||||
@ -133,7 +133,6 @@ class GA(Attributes):
|
|||||||
self.set_all_fitness()
|
self.set_all_fitness()
|
||||||
self.sort_by_best_fitness()
|
self.sort_by_best_fitness()
|
||||||
|
|
||||||
|
|
||||||
def adapt_probabilities(self: GA) -> None:
|
def adapt_probabilities(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
Modifies the parent ratio and mutation rates based on the adapt
|
Modifies the parent ratio and mutation rates based on the adapt
|
||||||
@ -153,7 +152,7 @@ class GA(Attributes):
|
|||||||
|
|
||||||
# Difference between best and i-th chromosomes
|
# Difference between best and i-th chromosomes
|
||||||
best_chromosome = self.population[0]
|
best_chromosome = self.population[0]
|
||||||
tol = lambda i: self.dist(best_chromosome, self.population[i])
|
def tol(i): return self.dist(best_chromosome, self.population[i])
|
||||||
|
|
||||||
# Too few converged: cross more and mutate less
|
# Too few converged: cross more and mutate less
|
||||||
if tol(amount_converged//2) > tol(amount_converged//4)*2:
|
if tol(amount_converged//2) > tol(amount_converged//4)*2:
|
||||||
@ -168,13 +167,14 @@ class GA(Attributes):
|
|||||||
self.max_gene_mutation_rate)
|
self.max_gene_mutation_rate)
|
||||||
|
|
||||||
# Weighted average of x and y
|
# Weighted average of x and y
|
||||||
average = lambda x, y: weight * x + (1-weight) * y
|
def average(x, y): return weight * x + (1-weight) * y
|
||||||
|
|
||||||
# Adjust rates towards the bounds
|
# Adjust rates towards the bounds
|
||||||
self.selection_probability = average(bounds[0], self.selection_probability)
|
self.selection_probability = average(
|
||||||
self.chromosome_mutation_rate = average(bounds[1], self.chromosome_mutation_rate)
|
bounds[0], self.selection_probability)
|
||||||
self.gene_mutation_rate = average(bounds[2], self.gene_mutation_rate)
|
self.chromosome_mutation_rate = average(
|
||||||
|
bounds[1], self.chromosome_mutation_rate)
|
||||||
|
self.gene_mutation_rate = average(bounds[2], self.gene_mutation_rate)
|
||||||
|
|
||||||
def adapt_population(self: GA) -> None:
|
def adapt_population(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
@ -201,7 +201,7 @@ class GA(Attributes):
|
|||||||
self.crossover_individual_impl(
|
self.crossover_individual_impl(
|
||||||
self.population[n],
|
self.population[n],
|
||||||
parent,
|
parent,
|
||||||
weight = -3/4,
|
weight=-3/4,
|
||||||
)
|
)
|
||||||
|
|
||||||
# If negative weights can't be used or division by 0, use positive weight
|
# If negative weights can't be used or division by 0, use positive weight
|
||||||
@ -209,7 +209,7 @@ class GA(Attributes):
|
|||||||
self.crossover_individual_impl(
|
self.crossover_individual_impl(
|
||||||
self.population[n],
|
self.population[n],
|
||||||
parent,
|
parent,
|
||||||
weight = +1/4,
|
weight=+1/4,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Stop if we've filled up an entire population
|
# Stop if we've filled up an entire population
|
||||||
@ -217,20 +217,19 @@ class GA(Attributes):
|
|||||||
break
|
break
|
||||||
|
|
||||||
# Replace worst chromosomes with new chromosomes, except for the previous best chromosome
|
# Replace worst chromosomes with new chromosomes, except for the previous best chromosome
|
||||||
min_len = min(len(self.population)-1, len(self.population.next_population))
|
min_len = min(len(self.population)-1,
|
||||||
|
len(self.population.next_population))
|
||||||
if min_len > 0:
|
if min_len > 0:
|
||||||
self.population[-min_len:] = self.population.next_population[:min_len]
|
self.population[-min_len:] = self.population.next_population[:min_len]
|
||||||
self.population.next_population = []
|
self.population.next_population = []
|
||||||
self.population.mating_pool = []
|
self.population.mating_pool = []
|
||||||
|
|
||||||
|
|
||||||
def initialize_population(self: GA) -> None:
|
def initialize_population(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
Sets self.population using the chromosome implementation and population size.
|
Sets self.population using the chromosome implementation and population size.
|
||||||
"""
|
"""
|
||||||
self.population = self.make_population(self.population_impl())
|
self.population = self.make_population(self.population_impl())
|
||||||
|
|
||||||
|
|
||||||
def set_all_fitness(self: GA) -> None:
|
def set_all_fitness(self: GA) -> None:
|
||||||
"""
|
"""
|
||||||
Sets the fitness of each chromosome in the population.
|
Sets the fitness of each chromosome in the population.
|
||||||
@ -251,15 +250,14 @@ class GA(Attributes):
|
|||||||
if chromosome.fitness is None or self.update_fitness:
|
if chromosome.fitness is None or self.update_fitness:
|
||||||
chromosome.fitness = self.fitness_function_impl(chromosome)
|
chromosome.fitness = self.fitness_function_impl(chromosome)
|
||||||
|
|
||||||
|
|
||||||
def sort_by_best_fitness(
|
def sort_by_best_fitness(
|
||||||
self: GA,
|
self: GA,
|
||||||
chromosome_list: Optional[
|
chromosome_list: Optional[
|
||||||
Union[MutableSequence[Chromosome],
|
Union[MutableSequence[Chromosome],
|
||||||
Iterable[Chromosome]]
|
Iterable[Chromosome]]
|
||||||
] = None,
|
] = None,
|
||||||
in_place: bool = True,
|
in_place: bool = True,
|
||||||
) -> MutableSequence[Chromosome]:
|
) -> MutableSequence[Chromosome]:
|
||||||
"""
|
"""
|
||||||
Sorts the chromosome list by fitness based on fitness type.
|
Sorts the chromosome list by fitness based on fitness type.
|
||||||
1st element has best fitness.
|
1st element has best fitness.
|
||||||
@ -314,7 +312,6 @@ class GA(Attributes):
|
|||||||
else:
|
else:
|
||||||
return sorted(chromosome_list, key=key, reverse=reverse)
|
return sorted(chromosome_list, key=key, reverse=reverse)
|
||||||
|
|
||||||
|
|
||||||
def get_chromosome_fitness(self: GA, index: int) -> float:
|
def get_chromosome_fitness(self: GA, index: int) -> float:
|
||||||
"""
|
"""
|
||||||
Computes the converted fitness of a chromosome at an index.
|
Computes the converted fitness of a chromosome at an index.
|
||||||
@ -338,7 +335,6 @@ class GA(Attributes):
|
|||||||
"""
|
"""
|
||||||
return self.convert_fitness(self.population[index].fitness)
|
return self.convert_fitness(self.population[index].fitness)
|
||||||
|
|
||||||
|
|
||||||
def convert_fitness(self: GA, fitness: float) -> float:
|
def convert_fitness(self: GA, fitness: float) -> float:
|
||||||
"""
|
"""
|
||||||
Calculates a modified version of the fitness for various
|
Calculates a modified version of the fitness for various
|
||||||
@ -375,23 +371,19 @@ class GA(Attributes):
|
|||||||
|
|
||||||
return max_fitness - fitness + min_fitness
|
return max_fitness - fitness + min_fitness
|
||||||
|
|
||||||
|
|
||||||
def print_generation(self: GA) -> None:
|
def print_generation(self: GA) -> None:
|
||||||
"""Prints the current generation."""
|
"""Prints the current generation."""
|
||||||
print(f"Current Generation \t: {self.current_generation}")
|
print(f"Current Generation \t: {self.current_generation}")
|
||||||
|
|
||||||
|
|
||||||
def print_population(self: GA) -> None:
|
def print_population(self: GA) -> None:
|
||||||
"""Prints the entire population."""
|
"""Prints the entire population."""
|
||||||
print(self.population)
|
print(self.population)
|
||||||
|
|
||||||
|
|
||||||
def print_best_chromosome(self: GA) -> None:
|
def print_best_chromosome(self: GA) -> None:
|
||||||
"""Prints the best chromosome and its fitness."""
|
"""Prints the best chromosome and its fitness."""
|
||||||
print(f"Best Chromosome \t: {self.population[0]}")
|
print(f"Best Chromosome \t: {self.population[0]}")
|
||||||
print(f"Best Fitness \t: {self.population[0].fitness}")
|
print(f"Best Fitness \t: {self.population[0].fitness}")
|
||||||
|
|
||||||
|
|
||||||
def print_worst_chromosome(self: GA) -> None:
|
def print_worst_chromosome(self: GA) -> None:
|
||||||
"""Prints the worst chromosome and its fitness."""
|
"""Prints the worst chromosome and its fitness."""
|
||||||
print(f"Worst Chromosome \t: {self.population[-1]}")
|
print(f"Worst Chromosome \t: {self.population[-1]}")
|
||||||
|
|||||||
@ -6,8 +6,8 @@ from dataclasses import dataclass, field
|
|||||||
from types import MethodType
|
from types import MethodType
|
||||||
import random
|
import random
|
||||||
|
|
||||||
import sqlite3
|
# import sqlite3
|
||||||
import matplotlib.pyplot as plt
|
# import matplotlib.pyplot as plt
|
||||||
|
|
||||||
from EasyGA.structure import Population
|
from EasyGA.structure import Population
|
||||||
from EasyGA.structure import Chromosome
|
from EasyGA.structure import Chromosome
|
||||||
@ -19,7 +19,7 @@ from EasyGA.parent import Parent
|
|||||||
from EasyGA.survivor import Survivor
|
from EasyGA.survivor import Survivor
|
||||||
from EasyGA.crossover import Crossover
|
from EasyGA.crossover import Crossover
|
||||||
from EasyGA.mutation import Mutation
|
from EasyGA.mutation import Mutation
|
||||||
from EasyGA.database import sql_database, matplotlib_graph
|
# from EasyGA.database import sql_database, matplotlib_graph
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -29,7 +29,8 @@ class Attributes:
|
|||||||
Contains default attributes for each attribute.
|
Contains default attributes for each attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
properties: Dict[str, Any] = field(default_factory=dict, init=False, repr=False, compare=False)
|
properties: Dict[str, Any] = field(
|
||||||
|
default_factory=dict, init=False, repr=False, compare=False)
|
||||||
|
|
||||||
run: int = 0
|
run: int = 0
|
||||||
|
|
||||||
@ -64,61 +65,73 @@ class Attributes:
|
|||||||
max_gene_mutation_rate: float = 0.15
|
max_gene_mutation_rate: float = 0.15
|
||||||
min_gene_mutation_rate: float = 0.01
|
min_gene_mutation_rate: float = 0.01
|
||||||
|
|
||||||
fitness_function_impl: Callable[[Attributes, Chromosome], float] = Fitness.is_it_5
|
fitness_function_impl: Callable[[
|
||||||
make_population: Callable[[Iterable[Iterable[Any]]], Population] = Population
|
Attributes, Chromosome], float] = Fitness.is_it_5
|
||||||
|
make_population: Callable[[
|
||||||
|
Iterable[Iterable[Any]]], Population] = Population
|
||||||
make_chromosome: Callable[[Iterable[Any]], Chromosome] = Chromosome
|
make_chromosome: Callable[[Iterable[Any]], Chromosome] = Chromosome
|
||||||
make_gene: Callable[[Any], Gene] = Gene
|
make_gene: Callable[[Any], Gene] = Gene
|
||||||
|
|
||||||
gene_impl: Callable[[Attributes], Any] = field(default_factory=lambda: rand_1_to_10)
|
gene_impl: Callable[[Attributes], Any] = field(
|
||||||
chromosome_impl: Optional[[Attributes], Iterable[Any]] = field(default_factory=lambda: use_genes)
|
default_factory=lambda: rand_1_to_10)
|
||||||
population_impl: Optional[[Attributes], Iterable[Iterable[Any]]] = field(default_factory=lambda: use_chromosomes)
|
chromosome_impl: Optional[[Attributes], Iterable[Any]] = field(
|
||||||
|
default_factory=lambda: use_genes)
|
||||||
|
population_impl: Optional[[Attributes], Iterable[Iterable[Any]]] = field(
|
||||||
|
default_factory=lambda: use_chromosomes)
|
||||||
|
|
||||||
weighted_random: Callable[[Attributes, float], float] = field(default_factory=lambda: simple_linear)
|
weighted_random: Callable[[Attributes, float], float] = field(
|
||||||
dist: Callable[[Attributes, Chromosome, Chromosome], float] = field(default_factory=lambda: dist_fitness)
|
default_factory=lambda: simple_linear)
|
||||||
|
dist: Callable[[Attributes, Chromosome, Chromosome],
|
||||||
|
float] = field(default_factory=lambda: dist_fitness)
|
||||||
|
|
||||||
parent_selection_impl: Callable[[Attributes], None] = Parent.Rank.tournament
|
parent_selection_impl: Callable[[
|
||||||
crossover_individual_impl: Callable[[Attributes], None] = Crossover.Individual.single_point
|
Attributes], None] = Parent.Rank.tournament
|
||||||
crossover_population_impl: Callable[[Attributes], None] = Crossover.Population.sequential
|
crossover_individual_impl: Callable[[
|
||||||
survivor_selection_impl: Callable[[Attributes], None] = Survivor.fill_in_best
|
Attributes], None] = Crossover.Individual.single_point
|
||||||
mutation_individual_impl: Callable[[Attributes], None] = Mutation.Individual.individual_genes
|
crossover_population_impl: Callable[[
|
||||||
mutation_population_impl: Callable[[Attributes], None] = Mutation.Population.random_avoid_best
|
Attributes], None] = Crossover.Population.sequential
|
||||||
termination_impl: Callable[[Attributes], None] = Termination.fitness_generation_tolerance
|
survivor_selection_impl: Callable[[
|
||||||
|
Attributes], None] = Survivor.fill_in_best
|
||||||
|
mutation_individual_impl: Callable[[
|
||||||
|
Attributes], None] = Mutation.Individual.individual_genes
|
||||||
|
mutation_population_impl: Callable[[
|
||||||
|
Attributes], None] = Mutation.Population.random_avoid_best
|
||||||
|
termination_impl: Callable[[Attributes],
|
||||||
|
None] = Termination.fitness_generation_tolerance
|
||||||
|
|
||||||
database: Database = field(default_factory=sql_database.SQL_Database)
|
#database: Database = field(default_factory=sql_database.SQL_Database)
|
||||||
database_name: str = 'database.db'
|
#database_name: str = 'database.db'
|
||||||
sql_create_data_structure: str = """
|
# sql_create_data_structure: str = """
|
||||||
CREATE TABLE IF NOT EXISTS data (
|
# CREATE TABLE IF NOT EXISTS data (
|
||||||
id INTEGER PRIMARY KEY,
|
# id INTEGER PRIMARY KEY,
|
||||||
config_id INTEGER DEFAULT NULL,
|
# config_id INTEGER DEFAULT NULL,
|
||||||
generation INTEGER NOT NULL,
|
# generation INTEGER NOT NULL,
|
||||||
fitness REAL,
|
# fitness REAL,
|
||||||
chromosome TEXT
|
# chromosome TEXT
|
||||||
);
|
# );
|
||||||
"""
|
# """
|
||||||
|
|
||||||
graph: Callable[[Database], Graph] = matplotlib_graph.Matplotlib_Graph
|
|
||||||
|
|
||||||
|
# graph: Callable[[Database], Graph] = matplotlib_graph.Matplotlib_Graph
|
||||||
|
|
||||||
#============================#
|
#============================#
|
||||||
# Built-in database methods: #
|
# Built-in database methods: #
|
||||||
#============================#
|
#============================#
|
||||||
|
|
||||||
|
# def save_population(self: Attributes) -> None:
|
||||||
|
# """Saves the current population to the database."""
|
||||||
|
# self.database.insert_current_population(self)
|
||||||
|
|
||||||
def save_population(self: Attributes) -> None:
|
# def save_chromosome(self: Attributes, chromosome: Chromosome) -> None:
|
||||||
"""Saves the current population to the database."""
|
# """
|
||||||
self.database.insert_current_population(self)
|
# Saves a chromosome to the database.#
|
||||||
|
|
||||||
|
# Parameters
|
||||||
def save_chromosome(self: Attributes, chromosome: Chromosome) -> None:
|
# ----------
|
||||||
"""
|
# chromosome : Chromosome
|
||||||
Saves a chromosome to the database.
|
# The chromosome to be saved.
|
||||||
|
# """
|
||||||
Parameters
|
# self.database.insert_current_chromosome(
|
||||||
----------
|
# was self.current_generation, chromosome)
|
||||||
chromosome : Chromosome
|
|
||||||
The chromosome to be saved.
|
|
||||||
"""
|
|
||||||
self.database.insert_current_chromosome(self.current_generation, chromosome)
|
|
||||||
|
|
||||||
|
|
||||||
def rand_1_to_10(self: Attributes) -> int:
|
def rand_1_to_10(self: Attributes) -> int:
|
||||||
@ -231,6 +244,7 @@ def get_method(name: str) -> Callable[[Attributes], Callable[..., Any]]:
|
|||||||
getter(ga)(...) -> Any
|
getter(ga)(...) -> Any
|
||||||
The getter property, taking in an object and returning the method.
|
The getter property, taking in an object and returning the method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def getter(self: Attributes) -> Callable[..., Any]:
|
def getter(self: Attributes) -> Callable[..., Any]:
|
||||||
return self.properties[name]
|
return self.properties[name]
|
||||||
return getter
|
return getter
|
||||||
@ -250,6 +264,7 @@ def set_method(name: str) -> Callable[[Attributes, Optional[Callable[..., Any]]]
|
|||||||
setter(ga, method)
|
setter(ga, method)
|
||||||
The setter property, taking in an object and returning nothing.
|
The setter property, taking in an object and returning nothing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setter(self: Attributes, method: Optional[Callable[..., Any]]) -> None:
|
def setter(self: Attributes, method: Optional[Callable[..., Any]]) -> None:
|
||||||
if method is None:
|
if method is None:
|
||||||
pass
|
pass
|
||||||
@ -318,6 +333,7 @@ def get_attr(name: str) -> Callable[[Attributes], Any]:
|
|||||||
getter(ga) -> Any
|
getter(ga) -> Any
|
||||||
A getter method which returns an attribute.
|
A getter method which returns an attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def getter(self: Attributes) -> Any:
|
def getter(self: Attributes) -> Any:
|
||||||
return self.properties[name]
|
return self.properties[name]
|
||||||
return getter
|
return getter
|
||||||
@ -342,6 +358,7 @@ def set_attr(name: str, check: Callable[[Any], bool], error: str) -> Callable[[A
|
|||||||
Raises ValueError(error)
|
Raises ValueError(error)
|
||||||
A setter method which saves to an attribute.
|
A setter method which saves to an attribute.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setter(self: Attributes, value: Any) -> Any:
|
def setter(self: Attributes, value: Any) -> Any:
|
||||||
if check(value):
|
if check(value):
|
||||||
self.properties[name] = value
|
self.properties[name] = value
|
||||||
@ -356,7 +373,8 @@ for name in static_checks:
|
|||||||
name,
|
name,
|
||||||
property(
|
property(
|
||||||
get_attr(name),
|
get_attr(name),
|
||||||
set_attr(name, static_checks[name]["check"], static_checks[name]["error"]),
|
set_attr(name, static_checks[name]
|
||||||
|
["check"], static_checks[name]["error"]),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -385,7 +403,8 @@ def set_max_chromosome_mutation_rate(self: Attributes, value: Optional[float]) -
|
|||||||
|
|
||||||
# Raise error
|
# Raise error
|
||||||
else:
|
else:
|
||||||
raise ValueError("Max chromosome mutation rate must be between 0 and 1")
|
raise ValueError(
|
||||||
|
"Max chromosome mutation rate must be between 0 and 1")
|
||||||
|
|
||||||
|
|
||||||
def get_min_chromosome_mutation_rate(self: Attributes) -> float:
|
def get_min_chromosome_mutation_rate(self: Attributes) -> float:
|
||||||
@ -407,7 +426,8 @@ def set_min_chromosome_mutation_rate(self: Attributes, value: Optional[float]) -
|
|||||||
|
|
||||||
# Raise error
|
# Raise error
|
||||||
else:
|
else:
|
||||||
raise ValueError("Min chromosome mutation rate must be between 0 and 1")
|
raise ValueError(
|
||||||
|
"Min chromosome mutation rate must be between 0 and 1")
|
||||||
|
|
||||||
|
|
||||||
def get_database_name(self: Attributes) -> str:
|
def get_database_name(self: Attributes) -> str:
|
||||||
@ -435,8 +455,10 @@ def get_active(self: Attributes) -> Callable[[Attributes], None]:
|
|||||||
return self.termination_impl
|
return self.termination_impl
|
||||||
|
|
||||||
|
|
||||||
Attributes.max_chromosome_mutation_rate = property(get_max_chromosome_mutation_rate, set_max_chromosome_mutation_rate)
|
Attributes.max_chromosome_mutation_rate = property(
|
||||||
Attributes.min_chromosome_mutation_rate = property(get_min_chromosome_mutation_rate, set_min_chromosome_mutation_rate)
|
get_max_chromosome_mutation_rate, set_max_chromosome_mutation_rate)
|
||||||
|
Attributes.min_chromosome_mutation_rate = property(
|
||||||
|
get_min_chromosome_mutation_rate, set_min_chromosome_mutation_rate)
|
||||||
Attributes.database_name = property(get_database_name, set_database_name)
|
Attributes.database_name = property(get_database_name, set_database_name)
|
||||||
Attributes.graph = property(get_graph, set_graph)
|
Attributes.graph = property(get_graph, set_graph)
|
||||||
Attributes.active = property(get_active)
|
Attributes.active = property(get_active)
|
||||||
|
|||||||
Reference in New Issue
Block a user