Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Genetic Algorithm: Object-Oriented vs Functional Programming

Name: Huynh Tan Tien

Student ID: 2413468


1. Execution Instructions

Ensure Python 3.x and matplotlib are installed (pip install matplotlib). Execute the following commands from the project root (ga-assignment/):

  • Run OOP: python oop/run.py
  • Run FP: python fp/run.py
  • Run Tests: python -m unittest discover -s oop/tests and python -m unittest discover -s fp/tests

Output: Convergence plots (.png) and execution logs (.json) will be generated directly in the reports/ directory.


2. Design Architecture

Object-Oriented Programming (OOP)

The OOP model leverages abstraction and encapsulation to map biological entities to code. The Chromosome and Population classes manage local state internally. Crucially, I implemented the Strategy Design Pattern via abstract base classes (SelectionStrategy, CrossoverStrategy, MutationStrategy). This decouples algorithmic behaviors from the GeneticAlgorithm engine, adhering to the Open/Closed Principle and ensuring seamless extensibility.

Functional Programming (FP)

The FP approach is strictly declarative, discarding classes in favor of immutable data pipelines. State mutation is eliminated by representing chromosomes as immutable tuples. All evolutionary operators are designed as pure functions—they accept inputs and return newly allocated tuples without side-effects. Higher-order functions like map() are utilized for concise, robust fitness evaluations.


3. Paradigm Reflection

Implementing the exact same optimization algorithm across two fundamentally different paradigms highlighted distinct architectural trade-offs between state management and data predictability.

The OOP paradigm provides a highly intuitive mental model for simulation. The biological nature of a Genetic Algorithm maps perfectly to objects interacting within a system. Furthermore, the Strategy pattern makes swapping heuristics (e.g., changing to a Two-Point Crossover) structurally elegant without modifying the core execution loop. However, OOP relies heavily on mutable states. In Python, this introduces the risk of accidental reference modifications (e.g., mutating a parent chromosome instead of its offspring), which required defensive programming techniques like copy.deepcopy to resolve.

Conversely, the FP paradigm excels in systemic predictability and mathematical purity. By strictly enforcing immutability, the entire class of bugs related to hidden state changes is eliminated by design. The logic flows as a clear transformation pipeline. However, this mathematical safety comes with a computational trade-off. Because tuples cannot be mutated in place, the FP approach requires reallocating memory for the entire population array at every single generation, leading to a slightly higher memory and garbage collection overhead compared to OOP.

Conclusion: OOP is structurally superior for modeling extensible simulations with intuitive hierarchies and state tracking. FP, while requiring a shift toward data transformation and incurring minor memory overhead, offers unmatched robustness, declarative clarity, and thread-safety.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages