Back to Work
Algoritma Genetika - Knapsack Problem
Program ini menggunakan Algoritma Genetika untuk menemukan kombinasi item terbaik yang dapat dimasukkan ke dalam tas dengan kapasitas terbatas, memaksimalkan nilai total tanpa melebihi batas berat.
Parameters
Code & Execution
Output
Click "Run Code" to see output...
📄 View Source Code
import random
# -----------------------------------------------
# 1. Data Masalah Knapsack
# -----------------------------------------------
items = {
'A': {'weight': 7, 'value': 5},
'B': {'weight': 2, 'value': 4},
'C': {'weight': 1, 'value': 7},
'D': {'weight': 9, 'value': 2}
}
capacity = 15
item_list = list(items.keys())
n_items = len(item_list)
# -----------------------------------------------
# 2. Fungsi bantu
# -----------------------------------------------
def decode(chromosome):
""""Kembalikan list item, total berat, total nilai"""
total_weight = 0
total_value = 0
chosen_items = []
for gene, name in zip(chromosome, item_list):
if gene == 1:
total_weight += items[name]['weight']
total_value += items[name]['value']
chosen_items.append(name)
return chosen_items, total_weight, total_value
def fitness(chromosome):
""""Fungsi fitness dengan penalti berat"""
_, total_weight, total_value = decode(chromosome)
if total_weight <= capacity:
return total_value
else:
return 0
def roulette_selection(population, fitnesses):
""""Seleksi roulette wheel"""
total_fit = sum(fitnesses)
if total_fit == 0:
return random.choice(population)
pick = random.uniform(0, total_fit)
current = 0
for chrom, fit in zip(population, fitnesses):
current += fit
if current >= pick:
return chrom
return population[-1]
def crossover(p1, p2):
""""Single-point crossover"""
if len(p1) != len(p2):
raise ValueError("Parent length mismatch")
point = random.randint(1, len(p1) - 1)
child1 = p1[:point] + p2[point:]
child2 = p2[:point] + p1[point:]
return child1, child2
def mutate(chromosome, mutation_rate=0.1):
""""Flip bit dengan probabilitas mutation_rate"""
return [1 - g if random.random() < mutation_rate else g for g in chromosome]
# -----------------------------------------------
# 3. Algoritma Genetika Utama
# -----------------------------------------------
def genetic_algorithm(
pop_size=10, generations=10, crossover_rate=0.8, mutation_rate=0.1,
elitism=True
):
population = [[random.randint(0, 1) for _ in range(n_items)] for _ in range(pop_size)]
for gen in range(generations):
fitnesses = [fitness(ch) for ch in population]
best_index = fitnesses.index(max(fitnesses))
best_chrom = population[best_index]
best_fit = fitnesses[best_index]
best_items, w, v = decode(best_chrom)
print(f"Generasi {gen+1}:")
print(f" Terbaik: {best_chrom} | Item: {best_items} | Berat: {w} | Nilai: {v} | Fitness: {best_fit}")
print("-" * 65)
new_population = []
if elitism:
new_population.append(best_chrom)
while len(new_population) < pop_size:
parent1 = roulette_selection(population, fitnesses)
parent2 = roulette_selection(population, fitnesses)
if random.random() < crossover_rate:
child1, child2 = crossover(parent1, parent2)
else:
child1, child2 = parent1[:], parent2[:]
child1 = mutate(child1, mutation_rate)
child2 = mutate(child2, mutation_rate)
new_population.extend([child1, child2])
population = new_population[:pop_size]
fitnesses = [fitness(ch) for ch in population]
best_index = fitnesses.index(max(fitnesses))
best_chrom = population[best_index]
best_items, w, v = decode(best_chrom)
print(f"\n{'=' * 3} HASIL AKHIR {'=' * 3}")
print(f"Kromosom terbaik: {best_chrom}")
print(f"Item terpilih: {best_items}")
print(f"Total berat: {w} kg")
print(f"Total nilai: ${v}")
print(f"Fitness akhir: {fitness(best_chrom)}")
# -----------------------------------------------
# 4. Jalankan Program
# -----------------------------------------------
if __name__ == "__main__":
random.seed(10)
genetic_algorithm(pop_size=8, generations=8, crossover_rate=0.8, mutation_rate=0.1)