Add 'algorytmy_genetyczne.py'
This commit is contained in:
parent
5342416278
commit
213f34a0df
374
algorytmy_genetyczne.py
Normal file
374
algorytmy_genetyczne.py
Normal file
@ -0,0 +1,374 @@
|
||||
|
||||
import numpy as np
|
||||
from .decay import GeomDecay
|
||||
|
||||
|
||||
def hill_climb(problem, max_iters=np.inf, restarts=0, init_state=None,
|
||||
curve=False, random_state=None):
|
||||
"""
|
||||
best_state array containing state that optimizes the fitness function.
|
||||
best_fitness Value of fitness function at best state.
|
||||
fitness_curve array containing the fitness at every iteration.
|
||||
"""
|
||||
if (not isinstance(max_iters, int) and max_iters != np.inf
|
||||
and not max_iters.is_integer()) or (max_iters < 0):
|
||||
raise Exception("""max_iters must be a positive integer.""")
|
||||
|
||||
if (not isinstance(restarts, int) and not restarts.is_integer()) \
|
||||
or (restarts < 0):
|
||||
raise Exception("""restarts must be a positive integer.""")
|
||||
|
||||
if init_state is not None and len(init_state) != problem.get_length():
|
||||
raise Exception("""init_state must have same length as problem.""")
|
||||
|
||||
# Set random seed
|
||||
if isinstance(random_state, int) and random_state > 0:
|
||||
np.random.seed(random_state)
|
||||
|
||||
best_fitness = -1*np.inf
|
||||
best_state = None
|
||||
|
||||
if curve:
|
||||
fitness_curve = []
|
||||
|
||||
for _ in range(restarts + 1):
|
||||
# Initialize optimization problem
|
||||
if init_state is None:
|
||||
problem.reset()
|
||||
else:
|
||||
problem.set_state(init_state)
|
||||
|
||||
iters = 0
|
||||
|
||||
while iters < max_iters:
|
||||
iters += 1
|
||||
|
||||
# Find neighbors and determine best neighbor
|
||||
problem.find_neighbors()
|
||||
next_state = problem.best_neighbor()
|
||||
next_fitness = problem.eval_fitness(next_state)
|
||||
|
||||
# If best neighbor is an improvement, move to that state
|
||||
if next_fitness > problem.get_fitness():
|
||||
problem.set_state(next_state)
|
||||
|
||||
else:
|
||||
break
|
||||
|
||||
if curve:
|
||||
fitness_curve.append(problem.get_fitness())
|
||||
|
||||
# Update best state and best fitness
|
||||
if problem.get_fitness() > best_fitness:
|
||||
best_fitness = problem.get_fitness()
|
||||
best_state = problem.get_state()
|
||||
|
||||
best_fitness = problem.get_maximize()*best_fitness
|
||||
|
||||
if curve:
|
||||
return best_state, best_fitness, np.asarray(fitness_curve)
|
||||
|
||||
return best_state, best_fitness
|
||||
|
||||
|
||||
def random_hill_climb(problem, max_attempts=10, max_iters=np.inf, restarts=0,
|
||||
init_state=None, curve=False, random_state=None):
|
||||
|
||||
if (not isinstance(max_attempts, int) and not max_attempts.is_integer()) \
|
||||
or (max_attempts < 0):
|
||||
raise Exception("""max_attempts must be a positive integer.""")
|
||||
|
||||
if (not isinstance(max_iters, int) and max_iters != np.inf
|
||||
and not max_iters.is_integer()) or (max_iters < 0):
|
||||
raise Exception("""max_iters must be a positive integer.""")
|
||||
|
||||
if (not isinstance(restarts, int) and not restarts.is_integer()) \
|
||||
or (restarts < 0):
|
||||
raise Exception("""restarts must be a positive integer.""")
|
||||
|
||||
if init_state is not None and len(init_state) != problem.get_length():
|
||||
raise Exception("""init_state must have same length as problem.""")
|
||||
|
||||
# Set random seed
|
||||
if isinstance(random_state, int) and random_state > 0:
|
||||
np.random.seed(random_state)
|
||||
|
||||
best_fitness = -1*np.inf
|
||||
best_state = None
|
||||
|
||||
if curve:
|
||||
fitness_curve = []
|
||||
|
||||
for _ in range(restarts + 1):
|
||||
# Initialize optimization problem and attempts counter
|
||||
if init_state is None:
|
||||
problem.reset()
|
||||
else:
|
||||
problem.set_state(init_state)
|
||||
|
||||
attempts = 0
|
||||
iters = 0
|
||||
|
||||
while (attempts < max_attempts) and (iters < max_iters):
|
||||
iters += 1
|
||||
|
||||
# Find random neighbor and evaluate fitness
|
||||
next_state = problem.random_neighbor()
|
||||
next_fitness = problem.eval_fitness(next_state)
|
||||
|
||||
# If best neighbor is an improvement,
|
||||
# move to that state and reset attempts counter
|
||||
if next_fitness > problem.get_fitness():
|
||||
problem.set_state(next_state)
|
||||
attempts = 0
|
||||
|
||||
else:
|
||||
attempts += 1
|
||||
|
||||
if curve:
|
||||
fitness_curve.append(problem.get_fitness())
|
||||
|
||||
# Update best state and best fitness
|
||||
if problem.get_fitness() > best_fitness:
|
||||
best_fitness = problem.get_fitness()
|
||||
best_state = problem.get_state()
|
||||
|
||||
best_fitness = problem.get_maximize()*best_fitness
|
||||
|
||||
if curve:
|
||||
return best_state, best_fitness, np.asarray(fitness_curve)
|
||||
|
||||
return best_state, best_fitness
|
||||
|
||||
|
||||
def simulated_annealing(problem, schedule=GeomDecay(), max_attempts=10,
|
||||
max_iters=np.inf, init_state=None, curve=False,
|
||||
random_state=None):
|
||||
|
||||
if (not isinstance(max_attempts, int) and not max_attempts.is_integer()) \
|
||||
or (max_attempts < 0):
|
||||
raise Exception("""max_attempts must be a positive integer.""")
|
||||
|
||||
if (not isinstance(max_iters, int) and max_iters != np.inf
|
||||
and not max_iters.is_integer()) or (max_iters < 0):
|
||||
raise Exception("""max_iters must be a positive integer.""")
|
||||
|
||||
if init_state is not None and len(init_state) != problem.get_length():
|
||||
raise Exception("""init_state must have same length as problem.""")
|
||||
|
||||
# Set random seed
|
||||
if isinstance(random_state, int) and random_state > 0:
|
||||
np.random.seed(random_state)
|
||||
|
||||
# Initialize problem, time and attempts counter
|
||||
if init_state is None:
|
||||
problem.reset()
|
||||
else:
|
||||
problem.set_state(init_state)
|
||||
|
||||
if curve:
|
||||
fitness_curve = []
|
||||
|
||||
attempts = 0
|
||||
iters = 0
|
||||
|
||||
while (attempts < max_attempts) and (iters < max_iters):
|
||||
temp = schedule.evaluate(iters)
|
||||
iters += 1
|
||||
|
||||
if temp == 0:
|
||||
break
|
||||
|
||||
else:
|
||||
# Find random neighbor and evaluate fitness
|
||||
next_state = problem.random_neighbor()
|
||||
next_fitness = problem.eval_fitness(next_state)
|
||||
|
||||
# Calculate delta E and change prob
|
||||
delta_e = next_fitness - problem.get_fitness()
|
||||
prob = np.exp(delta_e/temp)
|
||||
|
||||
# If best neighbor is an improvement or random value is less
|
||||
# than prob, move to that state and reset attempts counter
|
||||
if (delta_e > 0) or (np.random.uniform() < prob):
|
||||
problem.set_state(next_state)
|
||||
attempts = 0
|
||||
|
||||
else:
|
||||
attempts += 1
|
||||
|
||||
if curve:
|
||||
fitness_curve.append(problem.get_fitness())
|
||||
|
||||
best_fitness = problem.get_maximize()*problem.get_fitness()
|
||||
best_state = problem.get_state()
|
||||
|
||||
if curve:
|
||||
return best_state, best_fitness, np.asarray(fitness_curve)
|
||||
|
||||
return best_state, best_fitness
|
||||
|
||||
|
||||
def genetic_alg(problem, pop_size=200, mutation_prob=0.1, max_attempts=10,
|
||||
max_iters=np.inf, curve=False, random_state=None):
|
||||
|
||||
if pop_size < 0:
|
||||
raise Exception("""pop_size must be a positive integer.""")
|
||||
elif not isinstance(pop_size, int):
|
||||
if pop_size.is_integer():
|
||||
pop_size = int(pop_size)
|
||||
else:
|
||||
raise Exception("""pop_size must be a positive integer.""")
|
||||
|
||||
if (mutation_prob < 0) or (mutation_prob > 1):
|
||||
raise Exception("""mutation_prob must be between 0 and 1.""")
|
||||
|
||||
if (not isinstance(max_attempts, int) and not max_attempts.is_integer()) \
|
||||
or (max_attempts < 0):
|
||||
raise Exception("""max_attempts must be a positive integer.""")
|
||||
|
||||
if (not isinstance(max_iters, int) and max_iters != np.inf
|
||||
and not max_iters.is_integer()) or (max_iters < 0):
|
||||
raise Exception("""max_iters must be a positive integer.""")
|
||||
|
||||
# Set random seed
|
||||
if isinstance(random_state, int) and random_state > 0:
|
||||
np.random.seed(random_state)
|
||||
|
||||
if curve:
|
||||
fitness_curve = []
|
||||
|
||||
# Initialize problem, population and attempts counter
|
||||
problem.reset()
|
||||
problem.random_pop(pop_size)
|
||||
attempts = 0
|
||||
iters = 0
|
||||
|
||||
while (attempts < max_attempts) and (iters < max_iters):
|
||||
iters += 1
|
||||
|
||||
# Calculate breeding probabilities
|
||||
problem.eval_mate_probs()
|
||||
|
||||
# Create next generation of population
|
||||
next_gen = []
|
||||
|
||||
for _ in range(pop_size):
|
||||
# Select parents
|
||||
selected = np.random.choice(pop_size, size=2,
|
||||
p=problem.get_mate_probs())
|
||||
parent_1 = problem.get_population()[selected[0]]
|
||||
parent_2 = problem.get_population()[selected[1]]
|
||||
|
||||
# Create offspring
|
||||
child = problem.reproduce(parent_1, parent_2, mutation_prob)
|
||||
next_gen.append(child)
|
||||
|
||||
next_gen = np.array(next_gen)
|
||||
problem.set_population(next_gen)
|
||||
|
||||
next_state = problem.best_child()
|
||||
next_fitness = problem.eval_fitness(next_state)
|
||||
|
||||
# If best child is an improvement,
|
||||
# move to that state and reset attempts counter
|
||||
if next_fitness > problem.get_fitness():
|
||||
problem.set_state(next_state)
|
||||
attempts = 0
|
||||
|
||||
else:
|
||||
attempts += 1
|
||||
|
||||
if curve:
|
||||
fitness_curve.append(problem.get_fitness())
|
||||
|
||||
best_fitness = problem.get_maximize()*problem.get_fitness()
|
||||
best_state = problem.get_state()
|
||||
|
||||
if curve:
|
||||
return best_state, best_fitness, np.asarray(fitness_curve)
|
||||
|
||||
return best_state, best_fitness
|
||||
|
||||
|
||||
def mimic(problem, pop_size=200, keep_pct=0.2, max_attempts=10,
|
||||
max_iters=np.inf, curve=False, random_state=None, fast_mimic=False):
|
||||
"""Use MIMIC to find the optimum for a given optimization problem.
|
||||
|
||||
"""
|
||||
if problem.get_prob_type() == 'continuous':
|
||||
raise Exception("""problem type must be discrete or tsp.""")
|
||||
|
||||
if pop_size < 0:
|
||||
raise Exception("""pop_size must be a positive integer.""")
|
||||
elif not isinstance(pop_size, int):
|
||||
if pop_size.is_integer():
|
||||
pop_size = int(pop_size)
|
||||
else:
|
||||
raise Exception("""pop_size must be a positive integer.""")
|
||||
|
||||
if (keep_pct < 0) or (keep_pct > 1):
|
||||
raise Exception("""keep_pct must be between 0 and 1.""")
|
||||
|
||||
if (not isinstance(max_attempts, int) and not max_attempts.is_integer()) \
|
||||
or (max_attempts < 0):
|
||||
raise Exception("""max_attempts must be a positive integer.""")
|
||||
|
||||
if (not isinstance(max_iters, int) and max_iters != np.inf
|
||||
and not max_iters.is_integer()) or (max_iters < 0):
|
||||
raise Exception("""max_iters must be a positive integer.""")
|
||||
|
||||
# Set random seed
|
||||
if isinstance(random_state, int) and random_state > 0:
|
||||
np.random.seed(random_state)
|
||||
|
||||
if curve:
|
||||
fitness_curve = []
|
||||
|
||||
if fast_mimic not in (True, False):
|
||||
raise Exception("""fast_mimic mode must be a boolean.""")
|
||||
else:
|
||||
problem.mimic_speed = fast_mimic
|
||||
|
||||
# Initialize problem, population and attempts counter
|
||||
problem.reset()
|
||||
problem.random_pop(pop_size)
|
||||
attempts = 0
|
||||
iters = 0
|
||||
|
||||
while (attempts < max_attempts) and (iters < max_iters):
|
||||
iters += 1
|
||||
|
||||
# Get top n percent of population
|
||||
problem.find_top_pct(keep_pct)
|
||||
|
||||
# Update probability estimates
|
||||
problem.eval_node_probs()
|
||||
|
||||
# Generate new sample
|
||||
new_sample = problem.sample_pop(pop_size)
|
||||
problem.set_population(new_sample)
|
||||
|
||||
next_state = problem.best_child()
|
||||
|
||||
next_fitness = problem.eval_fitness(next_state)
|
||||
|
||||
# If best child is an improvement,
|
||||
# move to that state and reset attempts counter
|
||||
if next_fitness > problem.get_fitness():
|
||||
problem.set_state(next_state)
|
||||
attempts = 0
|
||||
|
||||
else:
|
||||
attempts += 1
|
||||
|
||||
if curve:
|
||||
fitness_curve.append(problem.get_fitness())
|
||||
|
||||
best_fitness = problem.get_maximize()*problem.get_fitness()
|
||||
best_state = problem.get_state().astype(int)
|
||||
|
||||
if curve:
|
||||
return best_state, best_fitness, np.asarray(fitness_curve)
|
||||
|
||||
return best_state, best_fitness
|
Loading…
Reference in New Issue
Block a user