Кроссовер со строковыми кодированными хромосомами

Я реализую генетический алгоритм (ГА). Есть 43 номера [Расположения скорой помощи] на выбор (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39), я выбираю 3 места, так как у меня есть 3 машины скорой помощи.

Я могу разместить свою машину скорой помощи только в 3 местах среди 1-39 locations (Ограничение).

Образец хромосомы: [000010000000000000100000000000100000000]. Это означает, что я хочу поставить свою машину скорой помощи на 5th, 19th, and 31 positions. Биты напротив позиций 5th, 19th и 31 равны 1, а остальные позиции равны 0. Другими словами, я включаю 5-bit, 19-bit, and 31-bit.

скажем

Candidate solution 1 (111000000000000000000000000000000000000) 

и

Candidate Solution 2 (000000000000000000000000000000000000111)

Мои решения-кандидаты закодированы в 39-битном коде, я хочу сделать кроссовер этих 39-битных. Вышеуказанные два решения-кандидата немного странные. Что здесь можно сделать?

Что может быть хорошим подходом для выполнения перекрестного перемещения при размещении машин скорой помощи в 3 местах среди 1-39 locations?

Я понятия не имею, что вы подразумеваете под словом «кроссовер». Вы имеете в виду перестановку битов? Вы можете перевернуть строку в Python, выполнив s[::-1]. Если вы просто хотите поставить биты в обратном порядке, то вместо добавления 1 << i добавьте 1 << (31-i).

Tim Roberts 05.10.2022 21:56

@TimRoberts Я использую генетический алгоритм для кроссинговера. Мне нужно создать потомство/ребенка из родительских хромосом.

LearningLogic 05.10.2022 22:01

@AdilAbid Итак, как именно это связано с машинами скорой помощи?

pigrammer 05.10.2022 22:04

@pigrammer Мне нужно изучить мое пространство для поиска. Моя область поиска 9139. Следуя генетическому алгоритму, мне нужно выполнить мутацию и скрещивание, чтобы найти 3 лучших места для размещения моих машин скорой помощи.

LearningLogic 05.10.2022 22:07
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
101
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ОП вопрос

Есть много способов выполнить кроссовер - в этом примере, поскольку мы должны получить одинаковое количество битов на входе и выходе, я использовал кроссовер между битами, позволяя 0-3 бита обмениваться местами между двумя входами. .

Предоставленное решение является динамическим и будет работать для хромосом любой длины с любым количеством перевернутых битов (1).

import random
from typing import Union
def crossover(cs1: str, cs2: str) -> Union[str, str]:
    if len(cs1) != len(cs2):
        raise Exception("Candidate solutions input are of different length.")
    # get the flipped bits in each string
    cs1_bits = [index for index, gene in enumerate(cs1) if gene == "1"]
    cs2_bits = [index for index, gene in enumerate(cs2) if gene == "1"]
    if len(cs1_bits) != len(cs2_bits):
        raise Exception("Candidate solutions input have different number of flipped bits.")
    index: int = random.randint(0, len(cs1_bits))
    sol1_bits, sol2_bits = cs1_bits[:index] + cs2_bits[index:], cs2_bits[:index] + cs1_bits[index:]
    output_1 = ""
    output_2 = ""
    for i in range(len(cs1)):
        if i in sol1_bits:
            output_1 += "1"
        else:
            output_1 += "0"
        if i in sol2_bits:
            output_2 += "1"
        else:
            output_2 += "0"
    return output_1, output_2

Пример ввода/вывода для решения OP.

# Input
"111000000000000000000000000000000000000", "000000000000000000000000000000000000111"
# Output
'110000000000000000000000000000000000001', '001000000000000000000000000000000000110'

Как выполнить стандартный кроссовер

Вы выполняете кроссовер в генетическом алгоритме, выбирая случайный индекс по длине числа значений, в вашем случае вы выберете значение от 0 до 38 (39 вариантов).

Затем вы разделите оба входа и соедините переднюю часть cs1 с задней частью cs2 и наоборот.

from typing import Union
import random
def crossover(cs1: str, cs2: str) -> Union[str, str]:
    index: int = random.randint(0, len(cs1))
    return cs1[:index] + cs2[index:], cs2[:index] + cs1[index:]

Если у вас есть значения:

cs1 = "111000000000000000000000000000000000000"
cs2 = "000000000000000000000000000000000000111"

Кроссинговер с индексом 1 вернет:

output_1 = "100000000000000000000000000000000000111"
output_2 = "011000000000000000000000000000000000000"

Кроссинговер с индексом 5 вернет:

output_1 = "111000000000000000000000000000000000111"
output_2 = "000000000000000000000000000000000000000"

Можете ли вы также предложить мне, как «мутировать» cs1 = "111000000000000000000000000000000000000" хорошо и организованно? Так же, как кроссовер?

LearningLogic 05.10.2022 22:45

Задайте другой вопрос, ответьте мне здесь, когда вы это сделаете, и я отвечу на него за вас.

Jeremy Savage 05.10.2022 22:48

Я разместил еще один вопрос для мутации. Пожалуйста, посмотрите. Это мой вопрос (stackoverflow.com/questions/73966258/…)

LearningLogic 05.10.2022 22:57

У меня есть вопрос. Если мы посмотрим на output_1 = "111000000000000000000000000000000000111", я получаю six1's. Однако мне необходимо оставить только 3bits (всего 3 машины скорой помощи) после пересечения границы. Что мне делать?

LearningLogic 06.10.2022 19:28

@JeremySavage Я думаю, что кроссовер unform может решить такие проблемы. Это решение в основном приведет к незаконному потомству.

ExploringAI 06.10.2022 19:44

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

Jeremy Savage 06.10.2022 22:16

@JeremySavage Код вашего решения основан на One Point Crossover, Multi-Point Crossover или Uniform Crossover?

ExploringAI 07.10.2022 16:39

Решение представляет собой вариант кроссовера one-point. Выбирается index, а затем биты с обеих сторон индекса меняются местами. Поскольку у вас есть только 3 возможных решения, выбранных одновременно, я думаю, что one-point имеет смысл. Вы также можете использовать uniform crossover для решения этой проблемы, но multi-point crossover не имеет смысла из-за отсутствия доступных решений.

Jeremy Savage 07.10.2022 23:00

Другие вопросы по теме