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

 
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:

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

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

Заменил строку 175 на

        NormalizeDouble((double)SumOfCurrentEpoch/MathMax(1,(double)resetCounterFF),2),

 Без этого отчет о работе вылетает с ошибкой.

 
Rich:

Заменил строку 175 на

 Без этого отчет о работе вылетает с ошибкой.

Да, возникнет ошибка деления на 0, если не было улучшений на протяжении заданного количества эпох начиная с первого запуска цикла ген. операторов.

Проще всего, и правильнее логически, присвоить переменной resetCounterFF сразу при инициализации 1:

int    resetCounterFF   =1;//счетчик сбросов "Эпох без улучшений"