Обсуждение статьи "Генетические алгоритмы - это просто!" - страница 7

 
joo:

1) Повторных вычислений ФФ не происходит, так как выполняется проверка по исторической базе хромосом - если хоть раз ФФ выполнялась ранее для такой особи то значение берётся из базы.

2) Здесь есть один нюанс с поселением новой колонии в популяцию. Но о нем я, пожалуй, умолчу. :) Сделай так, как тебе представляется более правильным и о результатах расскажи пожалуйста - после этого я расскажу о нюансе.

1) Ну-ну. Сказочник. :)   У тебя там как минимум одна ошибка.

Так действительные числа сравнивают только.. мммм... математики, да.

        if (Colony[Ge][chromos]!=historyHromosomes[Ge][Ch1])
          break;

При таком сравнении разница в пятнадцатом знаке после плавающей точки признает гены различными.  И она всегда обязательно будет, ибо судьба. ;)

Надо хотя бы так:

        if (fabs(Colony[Ge][chromos]-historyHromosomes[Ge][Ch1]) > delta)  // к примеру  0.00001 < delta < 0.00000000001
          break;

И в точь такая же плюшка у тебя при удалении дублей.  Не сомневаюсь что ты тестировал удаление дублей отдельно от ген. алгоритма, потому у тебя наверняка есть иллюзия работоспособности этого фрагмента.


2) Как всё таинственно...   Где тонко там и рвётся.  :)

Всё там решаемо, с нюансами или без.  Лады, сделаю - покажу как сделал.

 
MetaDriver:

1) Ну-ну. Сказочник. :)  

2) У тебя там как минимум одна ошибка. Так действительные числа сравнивают только.. мммм... математики, да. При таком сравнении разница в пятнадцатом знаке после плавающей точки признает гены различными.  И она всегда обязательно будет, ибо судьба. ;)

Надо хотя бы так:

3) И в точь такая же плюшка у тебя при удалении дублей.  Не сомневаюсь что ты тестировал удаление дублей отдельно от ген. алгоритма, потому у тебя наверняка есть иллюзия работоспособности этого фрагмента.

4) Как всё таинственно...   Где тонко там и рвётся.  :) Всё там решаемо, с нюансами или без.  Лады, сделаю - покажу как сделал.

1) Сказочник? Хмм, я, к сожалению, не понял юмора. Проверка по базе происходит в функции CheckHistoryChromosomes(chromos,historyHromosomes)  которая вызывается из     GetFitness(historyHromosomes). Поэтому я сказал правильно - повторных запусков ФФ не происходит.

2) Сверка с базой происходит с проверкой по генам. А каждый ген уже при появлении новой хромосомы при сохранении в колонию нормализуется SelectInDiscreteSpace(temp,RangeMinimum,RangeMaximum,Precision,3). Поэтому и тут "сказок" нет.

3) См. 2)

4) Никакой таинственности. Код открыт и прозрачен. А нюанс действительно есть (он связан не с проблемами реализации, а с качеством сходимости).

 
joo:

1) Сказочник? Хмм, я, к сожалению, не понял юмора. Проверка по базе происходит в функции CheckHistoryChromosomes(chromos,historyHromosomes)  которая вызывается из     GetFitness(historyHromosomes). Поэтому я сказал правильно - повторных запусков ФФ не происходит.

2) Сверка с базой происходит с проверкой по генам. А каждый ген уже при появлении новой хромосомы при сохранении в колонию нормализуется SelectInDiscreteSpace(temp,RangeMinimum,RangeMaximum,Precision,3). Поэтому и тут "сказок" нет.

3) См. 2)

1,2,3)  Уболтал. Почти. Нормализация действительно есть.  Правда это всё равно не повод сравнивать на равенство действительные числа "без зазора". :)

SelectInDiscreteSpace() слегка переделал. Не понравилось то, что ты Step корректируешь внутри. Не царское это дело - юзера поправлять. По крайней мере не в этот раз.

У юзера могут быть разумные соображения сделать Step "иррациональным" по отношению к диапазону изменений гена.

Получилось так:

double SelectInDiscreteSpace
(
double In, 
double InMin, 
double InMax, 
double step, 
int    RoundMode
)
{
  if (step==0.0)
    return(In);
  // обеспечим правильность границ
  if ( InMax < InMin )
  {
    double temp = InMax; InMax = InMin; InMin = temp;
  }
  // при нарушении - вернем нарушенную границу
  if ( In < InMin ) return( InMin );
//  if ( In > InMax ) return( InMax );                                // А это сделаем в конце, всё равно придётся
  if ( InMax == InMin || step <= 0.0 ) return( InMin );
  // приведем к заданному масштабу
//  step = (InMax - InMin) / MathCeil ( (InMax - InMin) / step );     // Не, не будем приводить к "заданному масштабу"
  switch ( RoundMode )
  {
  case 1:  In = ( InMin + step * MathFloor ( ( In - InMin ) / step ) );
  case 2:  In = ( InMin + step * MathCeil  ( ( In - InMin ) / step ) );
  default: In = ( InMin + step * MathRound ( ( In - InMin ) / step ) );
  }
  return fmin(In,InMax);
}
 
MetaDriver:

SelectInDiscreteSpace() слегка переделал. Не понравилось то, что ты Step корректируешь внутри. Не царское это дело - юзера поправлять. По крайней мере не в этот раз.

У юзера могут быть разумные соображения сделать Step "иррациональным" по отношению к диапазону изменений гена.

Получилось так:

Дело в том, что step может быть таким, что будет разбивать пространство на нецелое количество участков, а это не есть гуд, так как тут же торчмя встает вопрос, с какой стороны от входного числа "выхватывать" значение на числовой прямой (неизвестно что "правее",справа или слева)  - мой алгоритм даёт адекватный ответ, а твой увы. Именно поэтому нужно делать так:

step = (InMax - InMin) / MathCeil ( (InMax - InMin) / step );

Вот несколько сравнительных примеров результатов работы твоего и моего кода:



Результат


Мой Твой
In 2,2 2 2
InMIN 2
InMAX 3
Step 0,8






Результат


Мой Твой
In 2,8 3 2,8
InMIN 2
InMAX 3
Step 0,8






Результат


Мой Твой
In 2,2 2,25 2,3
InMIN 2
InMAX 3
Step 0,3
 
Смысл у такой нормализации другой, нежели у NormalizeDouble (), но дело хозяйское, кому не нравится, тот может использовать нормализацию до нужного знака, а не с заданным шагом как в SelectInDiscreteSpace().
 
joo:
Смысл у такой нормализации другой, нежели у NormalizeDouble (), но дело хозяйское, кому не нравится, тот может использовать нормализацию до нужного знака, а не с заданным шагом как в SelectInDiscreteSpace().

Это всё понятно, как и предыдущий пост.

Андрей, тут все перечисленные  варианты имеют право на существование. Твой тоже само собой. Пристального внимания заслуживает плавающая, изменяющаяся по ходу оптимизации дискретность.

--

Про всё в целом :

По хорошему - нужно настроек добавлять, библиотечку генетических операторов и т.п.  И продумывать заранее удобное расширение и использование.

Вот подумываю переписать всё на объекты, сделать более  могучий интерфейс и программный и пользовательский (графический, с множеством настройек во вкладках). Кое чего добавить, чего-то соптимизировать.

Точнее, пока в раздумьях - делать на основе твоего кода (использовать фрагменты) или переписать всё заново.

Хочешь принять участие - пиши в личку.

Не факт, что буду публиковать. Посмотрим. Пока для себя хочу сделать.


 
MetaDriver:

Про всё в целом :

1) По хорошему - нужно настроек добавлять, библиотечку генетических операторов и т.п.  И продумывать заранее удобное расширение и использование.

2) Точнее, пока в раздумьях - делать на основе твоего кода (использовать фрагменты) или переписать всё заново.

3) Хочешь принять участие - пиши в личку.

1) А я наоборот пытаюсь уменьшить количество параметров UGA без уменьшения гибкости в управлении.

2) Я знаю несколько человек, которые используют код из статьи в своих проектах так, как есть, и тех, которые переписали код заново с 0.

3) Написал в личку.

 
MetaDriver:

Это всё понятно, как и предыдущий пост.

Андрей, тут все перечисленные  варианты имеют право на существование. Твой тоже само собой. Пристального внимания заслуживает плавающая, изменяющаяся по ходу оптимизации дискретность.

--

Про всё в целом :

По хорошему - нужно настроек добавлять, библиотечку генетических операторов и т.п.  И продумывать заранее удобное расширение и использование.

Вот подумываю переписать всё на объекты, сделать более  могучий интерфейс и программный и пользовательский (графический, с множеством настройек во вкладках). Кое чего добавить, чего-то соптимизировать.

Точнее, пока в раздумьях - делать на основе твоего кода (использовать фрагменты) или переписать всё заново.

...

Владимир так тебе шашечки или ехать?

ты хочешь красивый код или собрать ГА круче тестерного?

Я лично считаю что тестерный довольно крут, один только нюанс мало параметров.

 
Urain:

Владимир так тебе шашечки или ехать?

ты хочешь красивый код или собрать ГА круче тестерного?

Я лично считаю что тестерный довольно крут, один только нюанс мало параметров.

Хочу удобный код. Удобный для использования, расширения, модификации и встраивания.

 
MetaDriver:

Хочу удобный код. Удобный для использования, расширения, модификации и встраивания.

Тогда опиши объектную модель ГА. Создай классы пустышки по описанной моделе, а затем заполняй их кодом и прописывай взаимодействие.