import neat import numpy as np import os import logging import pickle # En iyi genomu kaydetmek/yüklemek için import random import math import datetime # Log dosyası ismi için # --- Loglama Ayarları --- log_filename = f"quanta_log_{datetime.datetime.now():%Y%m%d_%H%M%S}.log" logging.basicConfig( level=logging.INFO, # Log seviyesi (INFO, DEBUG, WARNING, ERROR, CRITICAL) format='%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s', # Log formatı handlers=[ logging.FileHandler(log_filename), # Dosyaya loglama logging.StreamHandler() # Konsola (ekrana) loglama ] ) logger = logging.getLogger(__name__) logger.info("="*50) logger.info("Quanta Simülatörü Başlatılıyor (Görselleştirme Olmadan)") logger.info("="*50) # --- Simülasyon Parametreleri --- TARGET_PROB_0 = 0.7 # Hedef: %70 olasılıkla 0 üretmek TARGET_PROB_1 = 1.0 - TARGET_PROB_0 # Hedef: %30 olasılıkla 1 üretmek NUM_TRIALS_PER_GENOME = 100 # Her genomu değerlendirmek için yapılacak deneme sayısı MAX_GENERATIONS = 50 # Maksimum evrim nesli (Donanımınıza göre artırılabilir) FITNESS_THRESHOLD = 0.99 # Evrimin durması için ulaşılması gereken minimum fitness logger.info(f"Hedef P(0): {TARGET_PROB_0:.2f}, Hedef P(1): {TARGET_PROB_1:.2f}") logger.info(f"Genom Başına Deneme Sayısı: {NUM_TRIALS_PER_GENOME}") logger.info(f"Maksimum Nesil Sayısı: {MAX_GENERATIONS}") logger.info(f"Fitness Eşiği: {FITNESS_THRESHOLD}") # --- Basit Kuantum Benzeri Davranış (Taklit) --- # Bu fonksiyon, kuantum ölçümünün olasılıksal sonucunu basitçe taklit eder. def simulate_simple_qubit_measurement(prob0=TARGET_PROB_0): if random.random() < prob0: return 0 else: return 1 # --- NEAT Fitness Fonksiyonu --- # Genomları (sinir ağlarını) değerlendirir. # Hedef: Ağın çıktısı TARGET_PROB_0'a yakın olasılıkla 0 olmalı. def eval_genomes(genomes, config): """ Popülasyondaki tüm genomların fitness değerlerini hesaplar. """ for genome_id, genome in genomes: genome.fitness = 0.0 # Başlangıç fitness'ı sıfırla try: net = neat.nn.FeedForwardNetwork.create(genome, config) except Exception as e: logger.error(f"Genome {genome_id} için ağ oluşturulamadı: {e}") genome.fitness = -1.0 # Geçersiz genomları cezalandır continue count_0 = 0 # Her genomu N kez test ederek istatistiksel olarak değerlendir for _ in range(NUM_TRIALS_PER_GENOME): # Ağ Girdisi: Şimdilik sabit bir değer (1.0) kullanıyoruz. # Gelecekte bu girdi, simülasyonun durumunu veya kontrol parametrelerini yansıtabilir. net_input = (1.0,) try: output = net.activate(net_input) # Ağın çıktısını (genellikle 0-1 arası) yorumla # Çıktı < 0.5 ise 0, >= 0.5 ise 1 kabul edelim if output[0] < 0.5: count_0 += 1 except Exception as e: logger.warning(f"Genome {genome_id} ağ aktivasyonunda hata: {e}") # Hata durumunda bu denemeyi atla veya penaltı ver pass # Şimdilik sadece atlıyoruz # Gözlemlenen olasılıkları hesapla observed_prob_0 = count_0 / NUM_TRIALS_PER_GENOME # Fitness Hesaplama: Hedef olasılıklara ne kadar yakın? # Ortalama Karesel Hata (MSE) benzeri bir yaklaşım, ama ters çevrilmiş. # Hata ne kadar küçükse, fitness o kadar yüksek olmalı. error = (observed_prob_0 - TARGET_PROB_0) ** 2 # Fitness = 1 / (hata + epsilon) -> Hata sıfıra yaklaştıkça fitness sonsuza yaklaşır. # Daha stabil bir fitness için: Fitness = 1.0 - hata (0 ile 1 arasında) # Veya hedef eşiğe göre normalize edilebilir. Şimdilik basit tutalım: fitness = max(0.0, 1.0 - math.sqrt(error)) # Hatanın karekökünü 1'den çıkaralım (0-1 arası) genome.fitness = fitness # logger.debug(f"Genome {genome_id}: Fitness = {fitness:.4f}, Gözlenen P(0) = {observed_prob_0:.2f}") # --- NEAT Çalıştırma Fonksiyonu --- def run_neat(config_file): """ NEAT evrimini başlatır ve yönetir. """ logger.info(f"NEAT yapılandırması yükleniyor: {config_file}") try: config = neat.Config(neat.DefaultGenome, neat.DefaultReproduction, neat.DefaultSpeciesSet, neat.DefaultStagnation, config_file) # Fitness eşiğini config dosyasından değil, koddan alalım config.fitness_threshold = FITNESS_THRESHOLD logger.info(f"Yapılandırma yüklendi. Fitness Eşiği: {config.fitness_threshold}") except Exception as e: logger.critical(f"Yapılandırma dosyası yüklenemedi veya geçersiz: {config_file} - Hata: {e}") return None # Hata durumunda None döndür logger.info("Yeni popülasyon oluşturuluyor...") p = neat.Population(config) # İstatistikleri ve loglamayı ayarlama (Sadece konsol çıktısı) p.add_reporter(neat.StdOutReporter(True)) # Görselleştirme için istatistik toplayıcıya gerek yok. # stats = neat.StatisticsReporter() # p.add_reporter(stats) # Periyodik olarak checkpoint (yedek) alma checkpoint_prefix = 'neat-checkpoint-' p.add_reporter(neat.Checkpointer(10, filename_prefix=checkpoint_prefix)) # Her 10 nesilde bir kaydet logger.info(f"Checkpoint dosyaları '{checkpoint_prefix}*' olarak kaydedilecek.") logger.info(f"Evrim başlıyor (Maksimum {MAX_GENERATIONS} nesil)...") try: winner = p.run(eval_genomes, MAX_GENERATIONS) logger.info(' ' + "="*20 + " Evrim Tamamlandı " + "="*20) except Exception as e: logger.critical(f"Evrim sırasında kritik bir hata oluştu: {e}") # Belki son checkpoint'ten devam etme mantığı eklenebilir. return None # En iyi genomu göster/kaydet logger.info(f'En iyi genom bulundu:') logger.info(f' {winner}') # Konsola detaylı genom bilgisini yazdırır # En iyi genomu dosyaya kaydet (pickle ile) winner_filename = "winner_genome.pkl" try: with open(winner_filename, 'wb') as f: pickle.dump(winner, f) logger.info(f"En iyi genom '{winner_filename}' dosyasına başarıyla kaydedildi.") except Exception as e: logger.error(f"En iyi genom kaydedilemedi: {e}") # En iyi genomdan ağı oluştur ve son bir kez test et logger.info(" " + "="*20 + " En İyi Genom Testi " + "="*20) if winner: try: winner_net = neat.nn.FeedForwardNetwork.create(winner, config) test_count_0 = 0 test_trials = 1000 # Daha fazla deneme ile güvenilirliği artır logger.info(f"En iyi ağ {test_trials} kez test ediliyor...") for _ in range(test_trials): net_input = (1.0,) output = winner_net.activate(net_input) if output[0] < 0.5: test_count_0 += 1 observed_prob_0 = test_count_0 / test_trials logger.info(f"Final Test Sonucu: Gözlenen P(0) = {observed_prob_0:.4f} (Hedef: {TARGET_PROB_0:.3f})") logger.info(f"Final Test Sonucu: Gözlenen P(1) = {1.0 - observed_prob_0:.4f} (Hedef: {TARGET_PROB_1:.3f})") final_error = (observed_prob_0 - TARGET_PROB_0) ** 2 logger.info(f"Final Test Hatası (Karesel): {final_error:.6f}") except Exception as e: logger.error(f"En iyi genom test edilirken hata oluştu: {e}") else: logger.warning("Test edilecek bir kazanan genom bulunamadı.") logger.info("="*50) logger.info("Quanta Simülatörü Adım 1 (Görselleştirmesiz) tamamlandı.") logger.info("="*50) return winner # Kazanan genomu döndür if __name__ == '__main__': # Yapılandırma dosyasının yolu (Python betiği ile aynı klasörde olduğunu varsayar) local_dir = os.path.dirname(__file__) config_path = os.path.join(local_dir, 'config-feedforward.txt') if not os.path.exists(config_path): logger.critical(f"Yapılandırma dosyası bulunamadı: {config_path}") logger.critical("Lütfen 'config-feedforward.txt' dosyasını Python betiğiyle aynı klasöre koyun.") else: # NEAT'i çalıştır run_neat(config_path)