Skip to content

Introduced genetic algorithms #351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Data Structures and Algorithms/Genetic Algorithms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Genetic Algorithms in Problem Solving

## Overview
This repository contains implementations of genetic algorithms (GAs) applied to solve various problems. Genetic algorithms are a family of optimization algorithms inspired by the process of natural selection. They are commonly used to find solutions for complex, non-linear, and multi-objective optimization problems. This collection demonstrates the application of GAs to address different problem domains.


## Problem Domains
- [Knapsack Problem](./knapsack/): Applying GAs to find the best combination of items within a weight limit.

123 changes: 123 additions & 0 deletions Data Structures and Algorithms/Genetic Algorithms/knapsack_problem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import random
import matplotlib.pyplot as plt

"""
This program uses a genetic algorithm to solve the 0/1 Knapsack problem.
In the Knapsack problem, you are given a set of items, each with a value and a weight,
and a knapsack with a weight limit. The goal is to select a combination of items
to maximize the total value without exceeding the weight limit.
This genetic algorithm iteratively evolves a population of candidate solutions to find the best combination.

Knapsack Problem Parameters:
- weight_limit: The weight limit of the knapsack.
- item_list: A list of items, where each item is represented as (value, weight).

Genetic Algorithm Parameters:
- population_size: The size of the population.
- max_generations: The maximum number of generations to run.
- mutation_rate: The probability of mutation for each gene in the chromosome.
- chromosome_length: The number of genes in each chromosome.
"""

# Knapsack Problem Parameters
weight_limit = 56
item_list = [(17, 1), (78, 20), (56, 34), (2, 15), (34, 21), (3, 10)] # (value, weight)

# Genetic Algorithm Parameters
population_size = 100
max_generations = 300
mutation_rate = 0.5
chromosome_length = len(item_list)


def initialize_population():
# Initialize the population with random chromosomes
population = []
for _ in range(population_size):
chromosome = [random.randint(0, 1) for _ in range(chromosome_length)]
population.append(chromosome)
return population


def calculate_fitness(chromosome):
# Calculate the fitness of a chromosome based on its value and weight
total_value = 0
total_weight = 0
for gene, item in zip(chromosome, item_list):
if gene == 1:
total_value += item[0]
total_weight += item[1]
if total_weight > weight_limit:
return 0 # Violates weight constraint
return total_value


def selection(population):
# Select individuals from the population based on their fitness
selected = []
total_fitness = sum(calculate_fitness(chromosome) for chromosome in population)
for _ in range(population_size):
r = random.uniform(0, total_fitness)
cumulative_fitness = 0
for chromosome in population:
cumulative_fitness += calculate_fitness(chromosome)
if cumulative_fitness >= r:
selected.append(chromosome)
break
return selected


def crossover(parent1, parent2):
# Perform one-point crossover to create two children
crossover_point = random.randint(1, chromosome_length - 1)
child1 = parent1[:crossover_point] + parent2[crossover_point:]
child2 = parent2[:crossover_point] + parent1[crossover_point:]
return child1, child2


def mutation(chromosome):
# Apply mutation to a chromosome with a given probability
mutated_chromosome = chromosome[:]
for i in range(chromosome_length):
if random.random() < mutation_rate:
mutated_chromosome[i] = 1 - mutated_chromosome[i]
return mutated_chromosome


def genetic_algorithm():
# Main genetic algorithm loop
population = initialize_population()
fitness_history = []
for generation in range(max_generations):
population = selection(population)
new_population = []
while len(new_population) < population_size:
parent1 = random.choice(population)
parent2 = random.choice(population)
child1, child2 = crossover(parent1, parent2)
mutated_child1 = mutation(child1)
mutated_child2 = mutation(child2)
new_population.extend([mutated_child1, mutated_child2])

best_fit = max(calculate_fitness(chromosome) for chromosome in new_population)
fitness_history.append(best_fit)

population = new_population

best_chromosome = max(population, key=calculate_fitness)
best_fitness = calculate_fitness(best_chromosome)

return best_chromosome, best_fitness, fitness_history


# Run the genetic algorithm and print the result
best_solution, best_fitness_value, fitness_history = genetic_algorithm()
print("Best Solution:", best_solution)
print("Best Fitness Value:", best_fitness_value)

# Plot fitness history
plt.plot(fitness_history)
plt.title('Fitness History')
plt.xlabel('Generation')
plt.ylabel('Fitness')
plt.show()