기고글 토론 "유전 알고리즘-쉬워요" - 페이지 9

 

인구 규모를 계산하는 것이 좋습니다:

  ChromosomeCount=GeneCount*11;                                      //콜로니의 염색체 수
검색 출처: http: //habrahabr.ru/blogs/algorithm/122222/
Генетический алгоритм: боремся с преждевременной сходимостью
  • habrahabr.ru
В предыдущем очерке (Выбор размера популяции для генетического алгоритма) был определен минимальный размер популяции необходимый для работоспособности генетического алгоритма: N = 1 + LOG2(1/(1-P1^(1/L))), где P1 — требуемая вероятность того, что случайный набор хромосом будет содержать все необходимые элементы для каждого локуса; L — длина...
 

기사 정말 감사합니다! 그것이 아니었다면 - 나는 유전 적 방법이 무엇인지 결코 배우지 못했습니다 :)

하지만 한 가지 질문이 있습니다! 데이터베이스에서 염색체를 확인할 때 일치하는 경우 데이터베이스의 염색체 색인에서 한 단위가 차감됩니다. 왜 그럴까요? 지수가 0이면 어떻게 되나요?

//데이터베이스에서 염색체를 검색하여 동일한 염색체를 찾습니다.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //유전자 지수가 유전자 수보다 작고 동일한 유전자가 발견되는 한 유전자를 확인합니다.
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][chromos]!=historyHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //동일한 유전자의 수가 동일한 경우 데이터베이스에서 기성 솔루션을 가져올 수 있습니다.
    if (cnt==GeneCount)
      Colony[0][chromos]=historyHromosomes[0][Ch1-1];

제가 어디가 틀렸나요?

 
Rich:

인구 규모를 계산하는 것이 좋습니다:

인용된 출처의 능력에 대해서는 이의를 제기하지 않겠지만, 저는 동의하지 않습니다.

최적화 문제에서 GA를 사용할 수 있는 타당성은 직접 검색에 비해 최적을 결정하는 데 필요한 FF 실행 횟수를 줄이는 데 있습니다.

권장 사항을 따르면

ChromosomeCount=GeneCount*11

인수가 1000개인 문제에는 11000명의 모집단 규모가 필요합니다! 그리고 그것은 단 한 번의 에포크에서 11000번의 FF 실행입니다! 무작위 유전자 생성을 사용할 수도 있으며 최적의 결과를 찾는 데 크게 열등하지 않습니다. 주어진 출처는 대규모 인구에서 각 시대마다 개선을 향해 인구를 더욱 발전시키기에 충분한 유전 물질이있을 것이라고 "내기"합니다. 나는 동일한 것을 달성하려고 노력하고 있지만 FF 실행의 총 증가없이 유전 연산자로 확률을 재생하여 동일한 것을 달성하려고합니다.

 
MigVRN:

기사 정말 감사합니다! 그것이 아니었다면 - 나는 유전 적 방법이 무엇인지 결코 배우지 못했습니다 :)

하지만 한 가지 질문이 있습니다! 데이터베이스에서 염색체를 확인할 때 일치하는 경우 데이터베이스의 염색체 색인에서 한 단위가 차감됩니다. 왜 그럴까요? 그리고 지수가 0이면 어떻게 될까요?

제가 어디가 틀렸나요?

  //염색체가 데이터베이스에 저장되어 있는 경우
  if (ChrCountInHistory>0)
  {
    //데이터베이스에서 염색체를 검색하여 동일한 염색체를 찾습니다.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //유전자 지수가 유전자 수보다 적고 다음과 같은 경우 유전자를 확인합니다. 
      //...동일한 유전자를 얻습니다.
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][position]!=HistoryHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //동일한 유전자가 그 수만큼 많으면 
    //...데이터베이스의 기성 솔루션
    if (cnt==GeneCount)
      Colony[0][position]=HistoryHromosomes[0][Ch1-1];
    //데이터베이스에 해당 염색체가 없는 경우 FF를 계산합니다....
    else
    {
      FitnessFunction();
      //... 데이터베이스에 여유 공간이 있으면 저장합니다.
      if (ChrCountInHistory<10000)
      {
        for (Ge=0;Ge<=GeneCount;Ge++)
          HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
        ChrCountInHistory++;
      }
    }
  }
  //베이스가 비어있는 경우, 염색체에 대한 FF를 계산하여 베이스에 저장합니다.
  else
  {
    FitnessFunction();
    for (Ge=0;Ge<=GeneCount;Ge++)
      HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
    ChrCountInHistory++;
  }

데이터베이스에 염색체가 하나 이상 있는 경우에만 데이터베이스가 확인됩니다. 데이터베이스 검색 코드의 전체 섹션을 인용하지 않았습니다.

따라서 데이터베이스에 염색체가 없는데 홈이 확인되는 경우는 불가능합니다.

 
joo:

데이터베이스 검사는 데이터베이스에 염색체가 하나 이상 있는 경우에만 수행됩니다. 염기별 검색을 위한 코드의 전체 섹션을 제공하지 않았습니다.

따라서 데이터베이스에 염색체가 없는데 홈 검사가 수행되는 경우는 불가능합니다.

신속한 답변에 감사드립니다! 나는 당신이 말하는 것을 정확히 의미하지 않았습니다!

1) 데이터베이스에 실제로 하나의 염색체가 있다고 가정합니다 (ChrCountInHistory = 1 - 즉, 배열 차원이 1과 같음) - 데이터베이스의 색인은 0입니다! (ChrCountInHistory는 기본적으로 0입니다. 배열에 있는 요소의 인덱스는 0입니다).

그리고 이 인덱스에서 1을 뺍니다:

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

게다가 검색은 Ch1=0부터 시작됩니다 .

2) HistoryHromosomes[Ge][Ch1 ]과 비교하여 HistoryHromosomes[0][Ch1-1]을 할당합니다.

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

맞습니다, 감사합니다.

그렇게 하세요:

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

맞습니다, 감사합니다.

그렇게 해야죠:

흠.

이제 모든 것이 올바른 것 같지만 HistoryHromosomes[0][Ch1]에서"범위를 벗어난 배열"을 실행합니다...

 

joo:

맞습니다, 감사합니다.

천만에요! 중요한 것은 이전보다 훨씬 더 잘 작동한다는 것입니다 :)

joo:

흠.

이제 모든 것이 올바른 것 같지만 HistoryHromosomes[0][Ch1]에서 "범위를 벗어난 배열"이 발생합니다....

분석할 코드가 달라서 이유를 말하기는 어렵습니다. 아마도 "위치" 변수 때문일 수 있습니다. 이 기사에서 "위치"의 아날로그는 "염색체"입니다. 기사의 코드를 10번 정도 살펴봤는데 버그가 어디에 있는지 이해할 수 없었습니다 :( 나중에 기사의 예제에서 확인해보겠습니다 - 아마도 뭔가 더 명확해질 것입니다.

추신 : 변수가 최대 150개의 값으로 구성된 경우 메모리 뱅크를 사용하는 것이 정당합니다. 그리고 역사에는 100,000 명의 개인이 있습니다. 그런 경우 모든 것을 확인 (검색)하는 것보다 계산하는 것이 더 빠를까요? 아직 확인하지 않으셨나요?

 
MigVRN:

추신 : 변수가 최대 150개의 값으로 구성된 경우 메모리 뱅크를 사용하는 것이 정당합니다. 그리고 역사에는 100,000 명의 개인이 있습니다. 이런 경우 모두 확인(재확인)하는 것보다 계산하는 것이 더 빠를 있을까요? 아직 확인하지 않으셨나요?

그것은 모두 FF를 계산하는 데 필요한 시간에 달려 있습니다. FF가 단순한 수학적 함수라면 은행은 합리적이지 않습니다. 그러나 FF가 히스토리 실행(뉴런 학습 등) 및 기타 리소스 집약적 작업을 사용하는 경우 뱅크가 필요하며 최적화 시간을 크게 줄일 수 있습니다.

글쎄, 그것은 또한 유전자의 정확성에 달려 있습니다. 유전자가 "더 거칠수록" 반복이 더 자주 발생하고 염색체 은행을 사용하는 것이 더 합리적입니다.

 
MigVRN:
....

:)

그래도 오류가 없어서 많이 혼란 스러웠습니다. 여기에 테스트 스크립트를 만들었으니 시도해 보면 모든 것을 이해할 수 있습니다.

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

여기에서는 염색체를 Ch1의 위치와 비교하지만 상단 루프에서 +1이 할당되어 있으므로 나중에 -1을 뺍니다.

나는 동의합니다. 약간 비뚤어 져서 더 잘할 수 있습니다.

다음은 이를 확인할 수 있는 스크립트입니다:

//+------------------------------------------------------------------+
//|Check.mq5 |
//|저작권 2011, JQS 일명 주 | |
//| 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"
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 기능|
//+------------------------------------------------------------------+

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;//다른 유전자


  HistoryHromosomes[0][1]=7.0;
  //-------------------------
  HistoryHromosomes[1][1]=7.0;
  HistoryHromosomes[2][1]=8.0;
  HistoryHromosomes[3][1]=6.0;//다른 유전자
  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]);
}
//+------------------------------------------------------------------+

//------------------------------------------------------------------------------
//염색체 데이터베이스에 대해 염색체를 확인합니다.
void CheckHistoryChromosomes()
{
  //----------------------------------------------------------------------------
  int   Ch1=0;  //데이터베이스의 염색체 색인
  int   Ge =0;  //유전자 색인
  int   cnt=0;  //고유 유전자 카운터. 유전자가 다른 경우 
                //- 염색체는 고유한 것으로 인식됩니다.
  //----------------------------------------------------------------------------
  //염색체가 데이터베이스에 저장되어 있는 경우
  if (ChrCountInHistory>0)
  {
    //데이터베이스에서 염색체를 검색하여 동일한 염색체를 찾습니다.
    for (Ch1=0;Ch1<ChrCountInHistory && cnt<GeneCount;Ch1++)
    {
      cnt=0;
      //유전자 지수가 유전자 수보다 작고 다음과 같은 경우 유전자를 확인합니다. 
      //...동일한 유전자를 얻습니다.
      for (Ge=1;Ge<=GeneCount;Ge++)
      {
        if (Colony[Ge][position]!=HistoryHromosomes[Ge][Ch1])
          break;
        cnt++;
      }
    }
    //동일한 유전자가 그 수만큼 많으면 
    //...데이터베이스의 기성 솔루션
    if (cnt==GeneCount)
    {
      Colony[0][position]=HistoryHromosomes[0][Ch1-1];
    }
    //데이터베이스에 해당 염색체가 없는 경우 FF를 계산합니다....
    else
    {
      FitnessFunction();
      //... 데이터베이스에 여유 공간이 있으면 저장합니다.
      if (ChrCountInHistory<5)
      {
        for (Ge=0;Ge<=GeneCount;Ge++)
          HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
        ChrCountInHistory++;
      }
    }
  }
  //베이스가 비어있는 경우, 염색체에 대한 FF를 계산하여 베이스에 저장합니다.
  else
  {
    FitnessFunction();
    for (Ge=0;Ge<=GeneCount;Ge++)
      HistoryHromosomes[Ge][ChrCountInHistory]=Colony[Ge][position];
    ChrCountInHistory++;
  }
}
//------------------------------------------------------------------------------

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