"Genetik Algoritmalar - Çok Kolay!" makalesi için tartışma - sayfa 9

 

Nüfus büyüklüğünün hesaplanmasını öneriyorum:

  ChromosomeCount=GeneCount*11;                                      //Kolonideki kromozom sayısı
Erişim adresi: http: //habrahabr.ru/blogs/algorithm/122222/
Генетический алгоритм: боремся с преждевременной сходимостью
  • habrahabr.ru
В предыдущем очерке (Выбор размера популяции для генетического алгоритма) был определен минимальный размер популяции необходимый для работоспособности генетического алгоритма: N = 1 + LOG2(1/(1-P1^(1/L))), где P1 — требуемая вероятность того, что случайный набор хромосом будет содержать все необходимые элементы для каждого локуса; L — длина...
 

Makale için çok teşekkür ederim! Eğer bu olmasaydı - genetik yöntemlerin ne olduğunu asla öğrenemezdim :)

Ama bir soru var! Veritabanından kromozomları kontrol ettiğimizde - bir eşleşme durumunda - veritabanındaki kromozom indeksinden bir birim çıkarılacaktır. Neden? Peki ya indeks sıfırsa?

//Search the chromosomes in the database to find the same one.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //Check genes as long as the gene index is less than the number of genes and as long as the same genes are found
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][chromos]!=historyHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //Eğer özdeş genlerin sayısı aynıysa, veritabanından hazır bir çözüm alabilirsiniz
    if (cnt==GeneCount)
      Colony[0][chromos]=historyHromosomes[0][Ch1-1];

Nerede yanlış yapıyorum?

 
Rich:

Nüfus büyüklüğünün hesaplanmasını öneriyorum:

Atıfta bulunulan kaynağın yetkinliğine itiraz etmeyeceğim, ancak aynı fikirde değilim.

GA'nın optimizasyon problemlerinde kullanılmasının fizibilitesi, doğrudan aramaya kıyasla optimumun belirlenmesi için gereken FF çalıştırma sayısının azaltılmasında yatmaktadır.

Eğer öneriyi takip edersek

ChromosomeCount=GeneCount*11

1000 argümanlı problem 11000 bireylik bir popülasyon büyüklüğü gerektirecektir! Ve bu sadece 1 epokta 11000 FF çalışması demektir! Rastgele gen üretimi de kullanabilirsiniz ve sonuç optimumun bulunmasında çok daha düşük olmayacaktır. Verilen kaynak, büyük bir popülasyonda, popülasyonu her çağda iyileştirmeye doğru daha da geliştirmek için yeterli genetik materyal olacağına dair bir "bahis" yapar. Ben de aynı şeyi başarmaya çalışıyorum, ancak FF çalışmalarının toplam artışı olmadan genetik operatörlerle olasılıklarla oynayarak.

 
MigVRN:

Makale için çok teşekkür ederim! Eğer bu olmasaydı - genetik yöntemlerin ne olduğunu asla öğrenemezdim :)

Ama bir soru var! Veritabanından kromozomları kontrol ettiğimizde - bir eşleşme durumunda - veritabanındaki kromozom indeksinden bir birim çıkarılacaktır. Neden? Peki ya endeks sıfırsa?

Nerede hata yapıyorum???

  //Veritabanında herhangi bir kromozom depolanmışsa
  if (ChrCountInHistory>0)
  {
    //Search the chromosomes in the database to find the same one.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //Check genes as long as the gene index is less than the number of genes and as long as 
      //...aynı genleri al.
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][position]!=HistoryHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //Eğer olduğu kadar çok özdeş gen varsa 
    //...veritabanından hazır çözüm
    if (cnt==GeneCount)
      Colony[0][position]=HistoryHromosomes[0][Ch1-1];
    //Veritabanında böyle bir kromozom yoksa, bunun için FF hesaplayacağız....
    else
    {
      FitnessFunction();
      //... ve eğer veritabanında yer varsa, kaydedeceğiz.
      if (ChrCountInHistory<10000)
      {
        for (Ge=0;Ge<=GeneCount;Ge++)
          HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
        ChrCountInHistory++;
      }
    }
  }
  //Eğer taban boşsa, kromozom için FF'yi hesaplayın ve tabanda saklayın
  else
  {
    FitnessFunction();
    for (Ge=0;Ge<=GeneCount;Ge++)
      HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
    ChrCountInHistory++;
  }

Veritabanı yalnızca veritabanında en az bir kromozom varsa kontrol edilir. Veritabanı arama kodunun tüm bölümünden alıntı yapmadınız.

Bu nedenle, tabanda kromozom olmadığı ancak oluğun kontrol edildiği durum imkansızdır.

 
joo:

Veritabanı kontrolü yalnızca veritabanında en az bir kromozom olduğunda gerçekleştirilir. Tabana göre arama için kodun tüm bölümünü vermediniz.

Bu nedenle, veritabanında kromozom olmadığı, ancak oluk kontrolünün yapıldığı durum imkansızdır.

Bu kadar hızlı bir cevap için teşekkür ederim! Ben tam olarak sizin bahsettiğiniz şeyi kastetmemiştim!

1) Veritabanında gerçekten bir kromozom olduğunu varsayalım (ChrCountInHistory = 1 - yani dizi boyutu bire eşittir) - o zaman veritabanındaki indeksi sıfırdır! (ChrCountInHistory varsayılan olarak sıfırdır - dizideki bir elemanın indeksi sıfırdır).

Ve bu indeksten bir çıkarırız:

Colony[0][position]=HistoryHromosomes[0][Ch1-1]; 

ayrıca, arama Ch1=0'dan başlar.

2) HistoryHromosomes[Ge][Ch1 ] ile karşılaştırırız ve HistoryHromosomes[0][Ch1-1] atarız.

Документация по MQL5: Операции с массивами / ArrayRange
Документация по MQL5: Операции с массивами / ArrayRange
  • www.mql5.com
Операции с массивами / ArrayRange - Документация по MQL5
 

Haklısınız, teşekkür ederim.

Yapılması gereken bu:

Colony[0][position]=HistoryHromosomes[0][Ch1]; 
 
joo:

Haklısınız, teşekkür ederim.

Gitmenin yolu bu:

Hmm.

Şimdi HistoryHromosomes[0][Ch1] üzerinde"Array out of range", her şey doğru görünmesine rağmen...

 

joo:

Haklısınız, teşekkür ederim.

Rica ederim! Önemli olan, şimdi eskisinden daha iyi çalışıyor olması :)

joo:

Hmm.

Şimdi HistoryHromosomes[0][Ch1] üzerinde "Array out of range", ancak her şey doğru görünüyor ...

Nedenini söylemek zor - analiz etmek için farklı kodlarımız var. Belki de sorun "position" değişkenidir - makaledeki karşılığı "chromos". Makaledeki kodu muhtemelen 10 kez inceledim - hatanın nerede olduğunu anlayamadım :( Makaledeki örnekleri daha sonra kontrol edeceğim - belki bir şeyler daha netleşir.

Not: Eğer bir değişken ~150 değerden oluşuyorsa hafıza bankası kullanmak doğru olur. Ve geçmişte 100000 birey var. Belki böyle bir durumda hesaplamak, hepsini kontrol etmekten (aramaktan) daha hızlı olur? Kontrol etmediniz mi?

 
MigVRN:

Not: Eğer bir değişken ~150 değerden oluşuyorsa bir hafıza bankası kullanmak doğrudur. Ve geçmişte 100000 birey var. Belki böyle bir durumda saymak, hepsini kontrol etmekten (tekrar kontrol etmekten) daha hızlı olur? Kontrol etmediniz mi?

Her şey FF'yi hesaplamak için gereken süreye bağlıdır. Eğer FF sadece matematiksel bir fonksiyon ise, o zaman banka makul değildir. Ancak FF geçmiş çalışmaları (nöron öğrenme vb.) ve diğer kaynak yoğun görevleri kullanıyorsa, banka gereklidir ve optimizasyon süresini önemli ölçüde azaltabilir.

Bu aynı zamanda genlerin doğruluğuna da bağlıdır. Genler ne kadar "kaba" olursa, tekrarlar o kadar sık meydana gelir ve bir kromozom bankası kullanmak o kadar mantıklı olur.

 
MigVRN:
....

:)

Hala bir hata yok, kafamı çok karıştırdınız. Burada bir test betiği yaptım, deneyin, her şeyi anlayacaksınız.

for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][position]!=HistoryHromosomes[Ge][Ch1])
          break;
        cnt++;
      }

Burada, kromozomu Ch1'in pozisyonu ile karşılaştırmasına rağmen, üst döngüde +1 atanır, bu yüzden daha sonra -1'i çıkarırım.

Katılıyorum, biraz çarpık, daha iyi yapılabilirdi.

İşte kontrol etmek için bir komut dosyası:

//+------------------------------------------------------------------+
//|Kontrol et.mq5 |
//|Telif Hakkı 2011, JQS aka Joo |
//| https://www.mql5.com/ru/users/joo |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, JQS aka Joo"
#property link      "https://www.mql5.com/ru/users/joo"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Betik program başlatma işlevi|
//+------------------------------------------------------------------+

double Colony[][5];
double HistoryHromosomes[][3];

int ChrCountInHistory=5;
int GeneCount=5;
int position=0;

void OnStart()
{
  ArrayResize(Colony,GeneCount+1);            ArrayInitialize(Colony,0.0);
  ArrayResize(HistoryHromosomes,GeneCount+1); ArrayInitialize(HistoryHromosomes,0.0);

  Colony[1][0]=7.0;
  Colony[2][0]=8.0;
  Colony[3][0]=9.0;
  Colony[4][0]=3.0;
  Colony[5][0]=2.0;

  HistoryHromosomes[0][0]=8.0;
  //-------------------------
  HistoryHromosomes[1][0]=7.0;
  HistoryHromosomes[2][0]=8.0;
  HistoryHromosomes[3][0]=9.0;
  HistoryHromosomes[4][0]=3.0;
  HistoryHromosomes[5][0]=1.0;//başka bir gen


  HistoryHromosomes[0][1]=7.0;
  //-------------------------
  HistoryHromosomes[1][1]=7.0;
  HistoryHromosomes[2][1]=8.0;
  HistoryHromosomes[3][1]=6.0;//başka bir gen
  HistoryHromosomes[4][1]=3.0;
  HistoryHromosomes[5][1]=2.0;

  HistoryHromosomes[0][2]=11.0;
  //-------------------------
  HistoryHromosomes[1][2]=7.0;
  HistoryHromosomes[2][2]=8.0;
  HistoryHromosomes[3][2]=9.0;
  HistoryHromosomes[4][2]=3.0;
  HistoryHromosomes[5][2]=2.0;

  CheckHistoryChromosomes();

  Print(Colony[0][0]);
}
//+------------------------------------------------------------------+

//------------------------------------------------------------------------------
//Checking a chromosome against a chromosome database.
void CheckHistoryChromosomes()
{
  //----------------------------------------------------------------------------
  int   Ch1=0;  //Veritabanından kromozom indeksi
  int   Ge =0;  //Gen İndeksi
  int   cnt=0;  //Eşsiz genlerin sayacı. Herhangi bir gen farklıysa 
                //- bir kromozom benzersiz olarak tanınır
  //----------------------------------------------------------------------------
  //Veritabanında herhangi bir kromozom depolanmışsa
  if (ChrCountInHistory>0)
  {
    //Search the chromosomes in the database to find the same one.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //Check genes as long as the gene index is less than the number of genes and as long as 
      //...aynı genleri al.
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][position]!=HistoryHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //Eğer olduğu kadar çok özdeş gen varsa 
    //...veritabanından hazır çözüm
    if (cnt==GeneCount)
    {
      Colony[0][position]=HistoryHromosomes[0][Ch1-1];
    }
    //Veritabanında böyle bir kromozom yoksa, bunun için FF hesaplayacağız....
    else
    {
      FitnessFunction();
      //... ve eğer veritabanında yer varsa, kaydedeceğiz.
      if (ChrCountInHistory<5)
      {
        for (Ge=0;Ge<=GeneCount;Ge++)
          HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
        ChrCountInHistory++;
      }
    }
  }
  //Eğer taban boşsa, kromozom için FF'yi hesaplayın ve tabanda saklayın
  else
  {
    FitnessFunction();
    for (Ge=0;Ge<=GeneCount;Ge++)
      HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
    ChrCountInHistory++;
  }
}
//------------------------------------------------------------------------------

void FitnessFunction()
{
  Colony[0][position]=20.0;
}