Skip to content

Commit f32f78a

Browse files
Basic string grammar fix (TheAlgorithms#7534)
* Grammar edit * Flake8 consistency fix * Apply suggestions from code review Co-authored-by: Christian Clauss <cclauss@me.com>
1 parent ed12703 commit f32f78a

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

genetic_algorithm/basic_string.py

+27-27
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99

1010
import random
1111

12-
# Maximum size of the population. bigger could be faster but is more memory expensive
12+
# Maximum size of the population. Bigger could be faster but is more memory expensive.
1313
N_POPULATION = 200
14-
# Number of elements selected in every generation for evolution the selection takes
15-
# place from the best to the worst of that generation must be smaller than N_POPULATION
14+
# Number of elements selected in every generation of evolution. The selection takes
15+
# place from best to worst of that generation and must be smaller than N_POPULATION.
1616
N_SELECTED = 50
17-
# Probability that an element of a generation can mutate changing one of its genes this
18-
# guarantees that all genes will be used during evolution
17+
# Probability that an element of a generation can mutate, changing one of its genes.
18+
# This will guarantee that all genes will be used during evolution.
1919
MUTATION_PROBABILITY = 0.4
20-
# just a seed to improve randomness required by the algorithm
20+
# Just a seed to improve randomness required by the algorithm.
2121
random.seed(random.randint(0, 1000))
2222

2323

@@ -56,20 +56,20 @@ def basic(target: str, genes: list[str], debug: bool = True) -> tuple[int, int,
5656
f"{not_in_genes_list} is not in genes list, evolution cannot converge"
5757
)
5858

59-
# Generate random starting population
59+
# Generate random starting population.
6060
population = []
6161
for _ in range(N_POPULATION):
6262
population.append("".join([random.choice(genes) for i in range(len(target))]))
6363

64-
# Just some logs to know what the algorithms is doing
64+
# Just some logs to know what the algorithms is doing.
6565
generation, total_population = 0, 0
6666

67-
# This loop will end when we will find a perfect match for our target
67+
# This loop will end when we find a perfect match for our target.
6868
while True:
6969
generation += 1
7070
total_population += len(population)
7171

72-
# Random population created now it's time to evaluate
72+
# Random population created. Now it's time to evaluate.
7373
def evaluate(item: str, main_target: str = target) -> tuple[str, float]:
7474
"""
7575
Evaluate how similar the item is with the target by just
@@ -92,17 +92,17 @@ def evaluate(item: str, main_target: str = target) -> tuple[str, float]:
9292
# concurrent.futures.wait(futures)
9393
# population_score = [item.result() for item in futures]
9494
#
95-
# but with a simple algorithm like this will probably be slower
96-
# we just need to call evaluate for every item inside population
95+
# but with a simple algorithm like this, it will probably be slower.
96+
# We just need to call evaluate for every item inside the population.
9797
population_score = [evaluate(item) for item in population]
9898

99-
# Check if there is a matching evolution
99+
# Check if there is a matching evolution.
100100
population_score = sorted(population_score, key=lambda x: x[1], reverse=True)
101101
if population_score[0][0] == target:
102102
return (generation, total_population, population_score[0][0])
103103

104-
# Print the Best result every 10 generation
105-
# just to know that the algorithm is working
104+
# Print the best result every 10 generation.
105+
# Just to know that the algorithm is working.
106106
if debug and generation % 10 == 0:
107107
print(
108108
f"\nGeneration: {generation}"
@@ -111,21 +111,21 @@ def evaluate(item: str, main_target: str = target) -> tuple[str, float]:
111111
f"\nBest string: {population_score[0][0]}"
112112
)
113113

114-
# Flush the old population keeping some of the best evolutions
115-
# Keeping this avoid regression of evolution
114+
# Flush the old population, keeping some of the best evolutions.
115+
# Keeping this avoid regression of evolution.
116116
population_best = population[: int(N_POPULATION / 3)]
117117
population.clear()
118118
population.extend(population_best)
119-
# Normalize population score from 0 to 1
119+
# Normalize population score to be between 0 and 1.
120120
population_score = [
121121
(item, score / len(target)) for item, score in population_score
122122
]
123123

124-
# Select, Crossover and Mutate a new population
124+
# Select, crossover and mutate a new population.
125125
def select(parent_1: tuple[str, float]) -> list[str]:
126126
"""Select the second parent and generate new population"""
127127
pop = []
128-
# Generate more child proportionally to the fitness score
128+
# Generate more children proportionally to the fitness score.
129129
child_n = int(parent_1[1] * 100) + 1
130130
child_n = 10 if child_n >= 10 else child_n
131131
for _ in range(child_n):
@@ -134,32 +134,32 @@ def select(parent_1: tuple[str, float]) -> list[str]:
134134
][0]
135135

136136
child_1, child_2 = crossover(parent_1[0], parent_2)
137-
# Append new string to the population list
137+
# Append new string to the population list.
138138
pop.append(mutate(child_1))
139139
pop.append(mutate(child_2))
140140
return pop
141141

142142
def crossover(parent_1: str, parent_2: str) -> tuple[str, str]:
143-
"""Slice and combine two string in a random point"""
143+
"""Slice and combine two string at a random point."""
144144
random_slice = random.randint(0, len(parent_1) - 1)
145145
child_1 = parent_1[:random_slice] + parent_2[random_slice:]
146146
child_2 = parent_2[:random_slice] + parent_1[random_slice:]
147147
return (child_1, child_2)
148148

149149
def mutate(child: str) -> str:
150-
"""Mutate a random gene of a child with another one from the list"""
150+
"""Mutate a random gene of a child with another one from the list."""
151151
child_list = list(child)
152152
if random.uniform(0, 1) < MUTATION_PROBABILITY:
153153
child_list[random.randint(0, len(child)) - 1] = random.choice(genes)
154154
return "".join(child_list)
155155

156-
# This is Selection
156+
# This is selection
157157
for i in range(N_SELECTED):
158158
population.extend(select(population_score[int(i)]))
159159
# Check if the population has already reached the maximum value and if so,
160-
# break the cycle. if this check is disabled the algorithm will take
161-
# forever to compute large strings but will also calculate small string in
162-
# a lot fewer generations
160+
# break the cycle. If this check is disabled, the algorithm will take
161+
# forever to compute large strings, but will also calculate small strings in
162+
# a far fewer generations.
163163
if len(population) > N_POPULATION:
164164
break
165165

0 commit comments

Comments
 (0)