Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 09b7300

Browse files
Merge pull request #327 from ahmedfgad/github-actions
Improve gene_constraint
2 parents e6ba8e1 + 1de7028 commit 09b7300

File tree

7 files changed

+165
-62
lines changed

7 files changed

+165
-62
lines changed

‎README.md

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Check documentation of the [PyGAD](https://pygad.readthedocs.io/en/latest).
88

99
[![PyPI Downloads](https://pepy.tech/badge/pygad)](https://pepy.tech/project/pygad) [![Conda Downloads](https://img.shields.io/conda/dn/conda-forge/pygad.svg?label=Conda%20Downloads)](
10-
https://anaconda.org/conda-forge/PyGAD) [![PyPI version](https://badge.fury.io/py/pygad.svg)](https://badge.fury.io/py/pygad) ![Docs](https://readthedocs.org/projects/pygad/badge) [![PyGAD PyTest / Python 3.11](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml) [![PyGAD PyTest / Python 3.10](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml) [![PyGAD PyTest / Python 3.9](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml) [![PyGAD PyTest / Python 3.8](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml) [![PyGAD PyTest / Python 3.7](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py37.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py37.yml) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Translation](https://hosted.weblate.org/widgets/weblate/-/svg-badge.svg)](https://hosted.weblate.org/engage/weblate/) [![REUSE](https://api.reuse.software/badge/github.com/WeblateOrg/weblate)](https://api.reuse.software/info/github.com/WeblateOrg/weblate) [![Stack Overflow](https://img.shields.io/badge/stackoverflow-Ask%20questions-blue.svg)](
10+
https://anaconda.org/conda-forge/PyGAD) [![PyPI version](https://badge.fury.io/py/pygad.svg)](https://badge.fury.io/py/pygad)![Docs](https://readthedocs.org/projects/pygad/badge)[![PyGAD PyTest / Python 3.13](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py313.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py313.yml) [![PyGAD PyTest / Python 3.12](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py312.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py312.yml) [![PyGAD PyTest / Python 3.11](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py311.yml) [![PyGAD PyTest / Python 3.10](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py310.yml) [![PyGAD PyTest / Python 3.9](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py39.yml) [![PyGAD PyTest / Python 3.8](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml/badge.svg)](https://github.com/ahmedfgad/GeneticAlgorithmPython/actions/workflows/main_py38.yml) [![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Translation](https://hosted.weblate.org/widgets/weblate/-/svg-badge.svg)](https://hosted.weblate.org/engage/weblate/) [![REUSE](https://api.reuse.software/badge/github.com/WeblateOrg/weblate)](https://api.reuse.software/info/github.com/WeblateOrg/weblate) [![Stack Overflow](https://img.shields.io/badge/stackoverflow-Ask%20questions-blue.svg)](
1111
https://stackoverflow.com/questions/tagged/pygad) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ahmedfgad/GeneticAlgorithmPython/badge)](https://securityscorecards.dev/viewer/?uri=github.com/ahmedfgad/GeneticAlgorithmPython) [![DOI](https://zenodo.org/badge/DOI/10.1007/s11042-023-17167-y.svg)](https://doi.org/10.1007/s11042-023-17167-y)
1212

1313
![PYGAD-LOGO](https://user-images.githubusercontent.com/16560492/101267295-c74c0180-375f-11eb-9ad0-f8e37bd796ce.png)
@@ -253,16 +253,6 @@ Get started with the genetic algorithm by reading the tutorial titled [**Introdu
253253

254254
[![Introduction to Genetic Algorithm](https://user-images.githubusercontent.com/16560492/82078259-26252d00-96e1-11ea-9a02-52a99e1054b9.jpg)](https://www.linkedin.com/pulse/introduction-optimization-genetic-algorithm-ahmed-gad)
255255

256-
## Tutorial: Build Neural Networks in Python
257-
258-
Read about building neural networks in Python through the tutorial titled [**Artificial Neural Network Implementation using NumPy and Classification of the Fruits360 Image Dataset**](https://www.linkedin.com/pulse/artificial-neural-network-implementation-using-numpy-fruits360-gad) available at these links:
259-
260-
* [LinkedIn](https://www.linkedin.com/pulse/artificial-neural-network-implementation-using-numpy-fruits360-gad)
261-
* [Towards Data Science](https://towardsdatascience.com/artificial-neural-network-implementation-using-numpy-and-classification-of-the-fruits360-image-3c56affa4491)
262-
* [KDnuggets](https://www.kdnuggets.com/2019/02/artificial-neural-network-implementation-using-numpy-and-image-classification.html)
263-
264-
[![Building Neural Networks Python](https://user-images.githubusercontent.com/16560492/82078281-30472b80-96e1-11ea-8017-6a1f4383d602.jpg)](https://www.linkedin.com/pulse/artificial-neural-network-implementation-using-numpy-fruits360-gad)
265-
266256
## Tutorial: Optimize Neural Networks with Genetic Algorithm
267257

268258
Read about training neural networks using the genetic algorithm through the tutorial titled [**Artificial Neural Networks Optimization using Genetic Algorithm with Python**](https://www.linkedin.com/pulse/artificial-neural-networks-optimization-using-genetic-ahmed-gad) available at these links:
@@ -273,29 +263,6 @@ Read about training neural networks using the genetic algorithm through the tuto
273263

274264
[![Training Neural Networks using Genetic Algorithm Python](https://user-images.githubusercontent.com/16560492/82078300-376e3980-96e1-11ea-821c-aa6b8ceb44d4.jpg)](https://www.linkedin.com/pulse/artificial-neural-networks-optimization-using-genetic-ahmed-gad)
275265

276-
## Tutorial: Building CNN in Python
277-
278-
To start with coding the genetic algorithm, you can check the tutorial titled [**Building Convolutional Neural Network using NumPy from Scratch**](https://www.linkedin.com/pulse/building-convolutional-neural-network-using-numpy-from-ahmed-gad) available at these links:
279-
280-
- [LinkedIn](https://www.linkedin.com/pulse/building-convolutional-neural-network-using-numpy-from-ahmed-gad)
281-
- [Towards Data Science](https://towardsdatascience.com/building-convolutional-neural-network-using-numpy-from-scratch-b30aac50e50a)
282-
- [KDnuggets](https://www.kdnuggets.com/2018/04/building-convolutional-neural-network-numpy-scratch.html)
283-
- [Chinese Translation](http://m.aliyun.com/yunqi/articles/585741)
284-
285-
[This tutorial](https://www.linkedin.com/pulse/building-convolutional-neural-network-using-numpy-from-ahmed-gad)) is prepared based on a previous version of the project but it still a good resource to start with coding CNNs.
286-
287-
[![Building CNN in Python](https://user-images.githubusercontent.com/16560492/82431022-6c3a1200-9a8e-11ea-8f1b-b055196d76e3.png)](https://www.linkedin.com/pulse/building-convolutional-neural-network-using-numpy-from-ahmed-gad)
288-
289-
## Tutorial: Derivation of CNN from FCNN
290-
291-
Get started with the genetic algorithm by reading the tutorial titled [**Derivation of Convolutional Neural Network from Fully Connected Network Step-By-Step**](https://www.linkedin.com/pulse/derivation-convolutional-neural-network-from-fully-connected-gad) which is available at these links:
292-
293-
* [LinkedIn](https://www.linkedin.com/pulse/derivation-convolutional-neural-network-from-fully-connected-gad)
294-
* [Towards Data Science](https://towardsdatascience.com/derivation-of-convolutional-neural-network-from-fully-connected-network-step-by-step-b42ebafa5275)
295-
* [KDnuggets](https://www.kdnuggets.com/2018/04/derivation-convolutional-neural-network-fully-connected-step-by-step.html)
296-
297-
[![Derivation of CNN from FCNN](https://user-images.githubusercontent.com/16560492/82431369-db176b00-9a8e-11ea-99bd-e845192873fc.png)](https://www.linkedin.com/pulse/derivation-convolutional-neural-network-from-fully-connected-gad)
298-
299266
## Book: Practical Computer Vision Applications Using Deep Learning with CNNs
300267

301268
You can also check my book cited as [**Ahmed Fawzy Gad 'Practical Computer Vision Applications Using Deep Learning with CNNs'. Dec. 2018, Apress, 978-1-4842-4167-7**](https://www.amazon.com/Practical-Computer-Vision-Applications-Learning/dp/1484241665) which discusses neural networks, convolutional neural networks, deep learning, genetic algorithm, and more.

‎examples/example_gene_constraint.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import pygad
2+
import numpy
3+
4+
"""
5+
An example of using the gene_constraint parameter.
6+
7+
"""
8+
9+
function_inputs = [4,-2,3.5,5,-11,-4.7]
10+
desired_output = 44
11+
12+
def fitness_func(ga_instance, solution, solution_idx):
13+
output = numpy.sum(solution*function_inputs)
14+
fitness = 1.0 / (numpy.abs(output - desired_output) + 0.000001)
15+
return fitness
16+
17+
ga_instance = pygad.GA(num_generations=100,
18+
num_parents_mating=5,
19+
sol_per_pop=10,
20+
num_genes=len(function_inputs),
21+
mutation_num_genes=6,
22+
fitness_func=fitness_func,
23+
allow_duplicate_genes=False,
24+
gene_space=range(100),
25+
gene_type=int,
26+
sample_size=100,
27+
random_seed=10,
28+
gene_constraint=[lambda x,v: [val for val in v if val>=98],
29+
lambda x,v: [val for val in v if val>=98],
30+
lambda x,v: [val for val in v if 80<val<90],
31+
None,
32+
lambda x,v: [val for val in v if 20<val<40],
33+
None]
34+
)
35+
36+
ga_instance.run()
37+
print(ga_instance.population)

‎pygad/helper/misc.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ def mutation_change_gene_dtype_and_round(self,
128128
gene_value=gene_value)
129129
return gene_value_new
130130

131+
def validate_gene_constraint_callable_output(self,
132+
selected_values,
133+
values):
134+
if type(selected_values) in [list, numpy.ndarray]:
135+
selected_values_set = set(selected_values)
136+
if selected_values_set.issubset(values):
137+
pass
138+
else:
139+
return False
140+
else:
141+
return False
142+
143+
return True
144+
131145
def filter_gene_values_by_constraint(self,
132146
values,
133147
solution,
@@ -144,30 +158,30 @@ def filter_gene_values_by_constraint(self,
144158
It returns None if no values satisfy the constraint. Otherwise, an array of values that satisfy the constraint is returned.
145159
"""
146160

147-
# A list of the indices where the random values satisfy the constraint.
148-
filtered_values_indices = []
161+
if self.gene_constraint and self.gene_constraint[gene_idx]:
162+
pass
163+
else:
164+
raise Exception(f"Either the gene at index {gene_idx} is not assigned a callable/function or the gene_constraint itself is not used.")
165+
149166
# A temporary solution to avoid changing the original solution.
150167
solution_tmp = solution.copy()
151-
# Loop through the random values to filter the ones satisfying the constraint.
152-
forvalue_idx, valueinenumerate(values):
153-
solution_tmp[gene_idx] =value
154-
# Check if the constraint is satisfied.
155-
ifself.gene_constraint[gene_idx](solution_tmp):
156-
# The current value satisfies the constraint.
157-
filtered_values_indices.append(value_idx)
168+
filtered_values=self.gene_constraint[gene_idx](solution_tmp, values.copy())
169+
result=self.validate_gene_constraint_callable_output(selected_values=filtered_values,
170+
values=values)
171+
if result:
172+
pass
173+
else:
174+
raiseException("The output from the gene_constraint callable/function must be a list or NumPy array that is subset of the passed values (second argument).")
158175

159176
# After going through all the values, check if any value satisfies the constraint.
160-
if len(filtered_values_indices) > 0:
177+
if len(filtered_values) > 0:
161178
# At least one value was found that meets the gene constraint.
162179
pass
163180
else:
164181
# No value found for the current gene that satisfies the constraint.
165-
if not self.suppress_warnings:
166-
warnings.warn(f"No value found for the gene at index {gene_idx} with value {solution[gene_idx]} that satisfies its gene constraint.")
182+
if not self.suppress_warnings: warnings.warn(f"Failed to find a value that satisfies its gene constraint for the gene at index {gene_idx} with value {solution[gene_idx]} at generation {self.generations_completed}.")
167183
return None
168184

169-
filtered_values = values[filtered_values_indices]
170-
171185
return filtered_values
172186

173187
def get_gene_dtype(self, gene_index):

‎pygad/helper/unique.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def solve_duplicate_genes_randomly(self,
6969

7070
if temp_val in new_solution:
7171
num_unsolved_duplicates = num_unsolved_duplicates + 1
72-
if not self.suppress_warnings: warnings.warn(f"Failed to find a unique value for gene with index {duplicate_index} whose value is {solution[duplicate_index]}. Consider adding more values in the gene space or use a wider range for initial population or random mutation.")
72+
if not self.suppress_warnings: warnings.warn(f"Failed to find a unique value for gene with index {duplicate_index} whose value is {solution[duplicate_index]} at generation {self.generations_completed}. Consider adding more values in the gene space or use a wider range for initial population or random mutation.")
7373
else:
7474
# Unique gene value found.
7575
new_solution[duplicate_index] = temp_val
@@ -320,7 +320,7 @@ def unique_genes_by_space(self,
320320

321321
if temp_val in solution:
322322
num_unsolved_duplicates = num_unsolved_duplicates + 1
323-
if not self.suppress_warnings: warnings.warn(f"Failed to find a unique value for gene with index {duplicate_index} whose value is {solution[duplicate_index]}. Consider adding more values in the gene space or use a wider range for initial population or random mutation.")
323+
if not self.suppress_warnings: warnings.warn(f"Failed to find a unique value for gene with index {duplicate_index} whose value is {solution[duplicate_index]} at generation {self.generations_completed+1}. Consider adding more values in the gene space or use a wider range for initial population or random mutation.")
324324
else:
325325
solution[duplicate_index] = temp_val
326326

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /