İçeriğe atla
Üyelik kaydınızı yaparak son yazılan içeriklerden haberdar olun! ×

Yapay Zeka

  • makale
    55
  • yorum
    2
  • görüntüleme
    717.221

Gene Expression Programming (GEP)


Doğuhan ELMA

197 görünüm

Gene Expression Programming (GEP), genetik programlama (GP) ve genetik algoritmalar (GA) arasında bir bağlantı kurmayı hedefleyen bir evrimsel algoritma türüdür. GEP, Portekizli bilim insanı Candida Ferreira tarafından 2001 yılında geliştirilmiştir.

GEP, genetik programlamada kullanılan ağaç temsili yerine, genetik algoritmalarda kullanılan lineer kromozom temsilini kullanır. Bu, GEP'nin genetik algoritmaların avantajlarından (örneğin, basit çaprazlama ve mutasyon işlemleri) yararlanmasını sağlar, aynı zamanda genetik programlamadaki karmaşık programları ifade edebilmesine olanak tanır.

Gene Expression Programming'in ana fikri, genler ve gen ifadesi kavramlarına dayanır. GEP'de, bir kromozom birden çok gen içerir ve her gen bir alt programı temsil eder. Genler, gen ifadesi süreci boyunca ağaç yapılarına dönüştürülür, böylece bir genin kodladığı alt programı ifade eder. Sonuçta, GEP, birden çok alt programın bir araya gelerek bir bütün programı oluşturduğu modüler bir programlama yaklaşımına sahip olur.

Genlerde yer alan işlemler ve parametreler, gen ifadesi sırasında, genetik algoritmalarda olduğu gibi genellikle rasgele seçilir. Bu, genlerin ağaç yapısına dönüştürülmesi sürecinde, hangi işlemlerin ne zaman ve nerede kullanılacağını belirler.

Bu algoritma, farklı problemler için çeşitli çözümler üretme kapasitesi, genellikle daha karmaşık genetik programlama tekniklerine kıyasla daha hızlı çalışma süresi ve genetik algoritmalardaki tüm evrimsel operatörlerin (seçilim, çaprazlama, mutasyon vb.) kullanılabilme özellikleri nedeniyle popülerdir.

Genel olarak, GEP, GA ve GP'nin birleşimini kullanarak genetik evrim algoritmalarının daha geniş bir uygulama alanına sahip olmasını sağlar. Bu tür bir yaklaşım, genetik programlamadaki ağaç tabanlı yapıların karmaşıklığını ve genetik algoritmalardaki basit genetik operatörlerin etkinliğini birleştirir. GEP, karmaşık programları üretebilme yeteneği ve genetik algoritmalardaki evrimsel operatörlerin etkinliği sayesinde genetik programlamada kullanılan diğer yöntemlere göre çeşitli avantajlara sahiptir.

import random
import operator

# Parametreler
POPULATION_SIZE = 100
GENOME_LENGTH = 20
GENERATIONS = 50
OPERATORS = [operator.add, operator.sub, operator.mul, operator.truediv]
TERMINALS = list(range(10))

# Birey sınıfı
class Individual:
    def __init__(self, genome):
        self.genome = genome
        self.fitness = self.evaluate()

    def evaluate(self):
        # Gen ifadesi
        stack = []
        for gene in self.genome:
            if isinstance(gene, int):
                stack.append(gene)
            else:
                if len(stack) < 2:
                    return float('inf')  # Geçersiz ifade
                a = stack.pop()
                b = stack.pop()
                try:
                    result = gene(b, a)  # Hedef işlemi gerçekleştir
                except ZeroDivisionError:
                    result = float('inf')  # Sıfıra bölme
                stack.append(result)
        return abs(42 - stack[0])  # Hedef: 42

# Popülasyonun başlangıcı
population = []
for _ in range(POPULATION_SIZE):
    genome = [random.choice(OPERATORS + TERMINALS) for _ in range(GENOME_LENGTH)]
    individual = Individual(genome)
    population.append(individual)

# Evrimsel döngü
for generation in range(GENERATIONS):
    population.sort(key=lambda x: x.fitness)
    print(f"Generation {generation}, Best fitness: {population[0].fitness}")
    if population[0].fitness == 0:
        break  # Optimal çözüme ulaşıldı
    next_population = population[:POPULATION_SIZE//10]  # Elitizm
    for _ in range((POPULATION_SIZE - len(next_population)) // 2):
        parent1 = random.choice(population[:POPULATION_SIZE//2])
        parent2 = random.choice(population[:POPULATION_SIZE//2])
        crossover_point = random.randint(1, GENOME_LENGTH - 1)
        child1 = parent1.genome[:crossover_point] + parent2.genome[crossover_point:]
        child2 = parent2.genome[:crossover_point] + parent1.genome[crossover_point:]
        if random.random() < 0.1:  # Mutasyon
            mutation_point = random.randint(0, GENOME_LENGTH - 1)
            child1[mutation_point] = random.choice(OPERATORS + TERMINALS)
            mutation_point = random.randint(0, GENOME_LENGTH - 1)
            child2[mutation_point] = random.choice(OPERATORS + TERMINALS)
        next_population += [Individual(child1), Individual(child2)]
    population = next_population

Bu örnek, gen ifadesini basit bir şekilde gerçekleştirir: her bir gen, bir operatör veya terminal sembolüdür ve genler, bir yığıt üzerinde işlem yapmak için kullanılır. Bu nedenle, bu örnek yalnızca basit aritmetik ifadeleri (örneğin, Reverse Polish notation) oluşturabilir ve daha karmaşık GEP uygulamaları için gen ifadesini ve genetik operatörleri daha fazla geliştirmeniz gerekebilir. Bu kod ayrıca, gen ifadesi sırasında geçersiz ifadelerin (örneğin, operatörler için yeterli sayıda terminal bulunmaması) oluşabileceği durumları da göz önünde bulundurur. Bu tür ifadelerin doğru bir şekilde ele alınması, GEP'nin uygulamalarında önemli bir zorluk olabilir. Bu, gen ifadesi sürecini daha karmaşık ve esnek hale getirerek çözülebilir. Örneğin, genler, operatörler ve operandlar için ayrı alanlara sahip karmaşık genler tanımlayabilirsiniz.

Bu Python kodu, Gene Expression Programming (GEP) algoritmasının temel bir uygulamasını temsil eder. İşte kodun ana bölümleri ve nasıl çalıştığına dair genel bir açıklama:

- Birey sınıfı Bu sınıf, bir gen ifadesini temsil eden bir "bireyi" tanımlar. Bireyin genleri, işlemleri (operatörler) veya parametreleri (terminaller) temsil eder. Bireyin uygunluk değeri, genlerin ifade ettiği işlem sonucunun belirli bir hedef değerden (bu örnekte 42) ne kadar uzak olduğu ile belirlenir. 

- Popülasyonun başlangıcı: Başlangıçta, popülasyon rastgele genlere sahip bireylerle doldurulur. Bu genler operatörleri veya terminalleri temsil eder. 

- Evrimsel döngü: Her nesilde, en uygun bireyler seçilir ve yeni bir popülasyon oluşturmak için çaprazlanır ve mutasyona uğrar. Çaprazlama, iki ebeveynin genlerini birleştirerek yeni "çocuk" bireyler oluşturur. Mutasyon, bir genin rastgele değiştirilmesiyle gerçekleşir. Bu süreç, genetik algoritmalarda doğal evrimin temel mekanizmalarını taklit eder.

Kodun çıktısı, her neslin en iyi uygunluk değerini yazar. Bu, algoritmanın zamanla daha iyi çözümler bulduğunu gösterir. Eğer bir bireyin uygunluk değeri 0'a ulaşırsa, bu optimal çözüme ulaşıldığı anlamına gelir ve döngü durur.

Bu örnekte, gen ifadesi işlemi basit bir yığıt mekanizması kullanılarak gerçekleştirilir ve genler basit aritmetik işlemleri temsil eder. Bu yüzden, oluşturulan ifadeler Reverse Polish notation formatında olacaktır.

Kodun son hali, genetik evrimin temel mekanizmalarını kullanarak bir işlemi (bu örnekte hedef sayıyı 42 yapmayı) optimize etmeye çalışan bir GEP algoritmasının basit bir uygulamasını sunar.

Bu, GEP'nin en basit formudur ve daha karmaşık problemleri çözebilmek için daha gelişmiş gen ifadesi ve genetik operatörlerin kullanılması gerekebilir. Ayrıca, uygunluk fonksiyonu da çözülmek istenen probleme bağlı olarak değiştirilebilir.

0 Yorum


Önerilen Yorumlar

Görüntülenecek yorum yok.

Misafir
Yorum ekle...

×   Zengin metin olarak yapıştırıldı.   Bunun yerine düz metin olarak yapıştır

  Yalnızca 75 emojiye izin verilir.

×   Bağlantınız otomatik olarak gömüldü.   Bunun yerine bağlantı olarak görüntüle

×   Önceki içeriğiniz geri yüklendi.   Düzenleyiciyi temizle

×   Görüntüleri doğrudan yapıştıramazsınız. URL'den resim yükleyin veya ekleyin.

×
×
  • Create New...