Преобразование double в массив битов для генетического алгоритма в C (++)

Возможный дубликат:
С плавающей запятой к двоичному значению (C ++)

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

Как это сделать? Есть ли библиотечная функция для этого, как в Java? Любая помощь с благодарностью.

0

Решение

Как насчет:

double d = 1234;
unsigned char *b = (unsigned char *)&d;

Предполагая, что double состоит из 8 байтов, вы можете использовать b [0] … b [7].

Другая возможность:

long long x = *(long long *)&d;
2

Другие решения

  • Поскольку вы помечаете вопрос C ++, я бы использовал reinterpret_cast
  • Что касается генетического алгоритма, то вы, вероятно, действительно хотите рассматривать мантиссу, экспоненту и знак ваших двойников независимо. Увидеть «как я могу извлечь мантиссу двойной«
2

Почему вы хотите использовать двоичное представление? То, что что-то более популярно, не означает, что это решение вашей конкретной проблемы.

Существует известное представление генома под названием реальный что вы можете использовать для решения вашей проблемы, не подвергаясь нескольким проблемам двоичного представления, таким как обрывы Хэмминга и различные значения мутаций.

Пожалуйста, обратите внимание, что я не говорю о передовых, экспериментальных вещах. Эта статья 1991 года уже описывает проблему, о которой я говорю. Если вы говорите по-испански или по-португальски, я мог бы указать вам на мою личную книгу по GA, но на английском есть множество ссылок, таких как Мелани Митчеллили Eibenкниги, которые могли бы описать эту проблему более глубоко.

Важно иметь в виду, что вам нужно адаптировать генетический алгоритм к вашей проблеме, а не изменять свои потребности, чтобы иметь возможность использовать определенный тип GA.

1

Я бы не стал конвертировать его в массив. Я думаю, если вы делаете генетические вещи, это должно быть производительным. На вашем месте я бы использовал целочисленный тип (как предложено в irrelephant), а затем выполнял мутации и кроссоверы с помощью операций int.

Если вы этого не делаете, вы всегда конвертируете это назад и вперед. А для кроссовера вам нужно перебрать 64 элемента.

Вот пример для кроссовера:

__int64 crossover(__int64 a, __int64 b, int x) {
__int64 mask1 = ...; // left most x bits
__int64 mask2 = ...; // right most 64-x bits

return (a & mask1) + (b & mask2);
}

И для выбора, вы можете просто привести его к двойному.

0

Вы можете сделать это так:

// Assuming a DOUBLE is 64bits

double  d = 42.0; // just a random double
char*   bits = (char*)&d; // access my double byte-by-byte
int     array[64]; // result

for (int i = 0, k = 63; i < 8; ++i) // for each byte of my double
for (char j = 0; j < 8; ++j, --k) // for each bit of each byte of my double
array[k] = (bits[i] >> j) & 1; // is the Jth bit of the current byte 1?

Удачи

0

Либо начните с двоичного представления генома, а затем используйте одноточечные или двухточечные операторы кроссовера, или, если вы хотите использовать реальное кодирование для вашей GA, тогда, пожалуйста, используйте оператор имитированного бинарного кроссовера (SBX) для кроссовера. В большинстве современных реализаций GA используется реальное кодированное представление и соответствующий оператор кроссовера и мутации.

0

Вы могли бы использовать int (или его вариант).

Хитрость заключается в кодировании float из 12.34 как int из 1234,

Поэтому вам просто нужно бросить на поплавок & разделите на 100 во время фитнес-функции и сделайте все ваши мутации & кроссовер на целое число.

Gotchas:

  • Остерегайтесь потери точности, если вам действительно нужен n-й бит.
  • Остерегайтесь знака бит.
  • Остерегайтесь разницы в диапазоне между поплавками & Интс.
0
По вопросам рекламы [email protected]