структуры и массивы - PullRequest
       3

структуры и массивы

1 голос
/ 03 января 2012

Я сейчас смотрю на это:

некоторый генетический алгоритм

Это некоторый адаптированный код:

struct Chromosome
{
    public bool[] genes;
    public int fitness;
}

Я никогда не использовалструктурирует в моих эволюционных алгоритмах / генетических алгоритмах.Не бессмысленно ли использовать массивы в структурах, особенно когда мне приходится делать глубокие копии?Есть ли преимущество использования структур в этом сценарии?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 03 января 2012

Я не вижу никаких проблем с этим ... В GA это все о проверке пригодности ваших кандидатов. структура просто капсулирует всю информацию для вашего кандидата. следовательно, фитнес напрямую связан с вашим геном. Имеет смысл хранить его в одном классе / структуре.

Если вы не сохраняете фитнес с вашим геном, вы должны каким-то образом отобразить его. Это было бы ненужным хлопотом. Или, если вы вообще не хотите хранить данные о пригодности, вам придется пересчитывать их каждый раз, когда вы сравниваете двух кандидатов друг с другом. Не будет мудрым. особенно если оценка пригодности довольно сложна (например, в ГА для оценки лучших параметров для моделирования).

Я бы использовал класс, который реализует интерфейс IComparable. Два кандидата были бы чем-то сравнены по пригодности. Затем вам нужно только отсортировать список кандидатов и выбрать, например, 10 лучших кандидатов для следующего поколения (всегда зависит от типа используемой вами ГА).

о массиве bool ... Я тоже не вижу проблем с этим. Если это то, как ваш ген представлен лучше всего ... идеально :). Представление в виде целого числа также хорошо, но в некоторых случаях это может усложнить операцию x-over ... всегда зависит от регистра ...

1 голос
/ 03 января 2012

Обычно мы используем struct для представления чего-то, что можно считать довольно примитивным. Согласно MSDN , это должен быть тип, представляющий одно «значение», размером 16 байт или менее и т. Д.

Главное, что следует иметь в виду при struct, - это семантика типа значения, поэтому передача этого в функции и из нее создаст копию. С точки зрения затрат это не будет слишком плохо, поскольку вы копируете 1 ссылку (на массив bool) и 1 int, но это создает некоторые интересные побочные эффекты, если вы попытаетесь изменить ссылку на массив в другом методе или из копия.

Многие полагают, что struct всегда будет более эффективным, чем class, но это не всегда так, и обычно эта микрооптимизация более опасна, чем полезна, потому что она вводит побочные эффекты работы с типом значения .

Что касается массива bool, вы можете создавать и устанавливать биты в int или использовать специализированный класс BitArray в BCL.

Таким образом, если коротко, то если это устаревший код и вы хотите сохранить struct, он будет работать, но он может помешать вам, если вы ожидаете, что он будет действовать как class когда прошло / скопировано. Однако, смотря на то, что он держит, он не соответствует руководству MSDN, для которого struct лучше всего подходит.

1 голос
/ 03 января 2012

В этом случае массив bool не будет автоматически копироваться глубоко.Таким образом, вы не пользуетесь структурами, потому что когда вы назначаете хромосому новой, в обоих случаях ссылка будет на один и тот же bool []

Вместо использования bool [] вы можете простоиспользуйте число: скажем, int.Хромосома с генами = 3 представляет ген: 0000 0000 0000 0000 0000 0011. Хромосома с генами = 42134 представляет ген: 0000 0000 1010 0100 1001 0110. int - 32 бита, что означает, что вы можете представлять хромосомы с 2 32 генов таким образом.Вам не нужно беспокоиться о глубоком копировании массива, и это также быстрее и эффективнее с точки зрения потребления памяти.Используйте Int64, если вам нужно больше генов.

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

        //The following creates a random chromosome with restrictions
        //to the genes as described in the following:

        //Let's say that the following pattern must be adhered to: 
        //byte 1 = xxxx xxxx (anything)
        //byte 2 = 1011 xxxx (restricted)
        //byte 3 = [0000 or 1111] xxxx (restricted)
        //byte 4 = 0000 1111 (fixed value)

        Random rnd = new Random();
        byte[] randomByte = new byte[1]; //xxxx xxxx xxxx xxxx

        byte restrictedByte2 = 
            (byte)(Math.Pow(2,7) * 1 + Math.Pow(2,6) * 0 + 
            Math.Pow(2,5) * 1 + Math.Pow(2,4) * 1 + 
            rnd.Next(0, 16)); //1011 xxxx

        //in byte 3, the first (most significant) for bits are restricted to either 0000 or 1111. 
        //That's either number 0 * 16 = 0 or number 15 * 16 = 240. I multiplied by 2^4 because it's shifted
        //4 bytes to the left.
        byte higherBits = (byte)(rnd.Next(0, 2/*upper bound exclusive*/) == 1?240:0);
        //random lower bits (xxxx).
        byte lowerBits = (byte)(Math.Pow(2,0) * rnd.Next(0, 2) + Math.Pow(2,1) * rnd.Next(0, 2) + 
            Math.Pow(2,2) * rnd.Next(0, 2) + Math.Pow(2,3) * rnd.Next(0, 2) + 
            rnd.Next(0, 16));

        byte restrictedByte3 = (byte)(lowerBits + higherBits);

        byte restrictedByte4 = 143; //constant

        //Create an Int32 from the four bytes.
        int randomMutation = BitConverter.ToInt32(
            new byte[] { randomByte[1], restrictedByte2, restrictedByte3, restrictedByte4 }, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...