import numpy as np
import pandas as pd

# Заданные параметры для функции
a, b, c, d = 14, 2, -26, 1

# Целевая функция
def target_function(x):
    return a + b * x + c * x**2 + d * x**3

# Диапазон x
x_min, x_max = -10, 53

# Длина битовой строки (хромосомы)
chromosome_length = 6
population_size = 6  # количество особей

# Функция для генерации случайных значений X в заданном диапазоне
def generate_random_x_values(size, x_min=-10, x_max=53):
    # Генерируем случайные числа в диапазоне [0, 63]
    random_values = np.random.randint(0, 2**chromosome_length, size=size)
    # Масштабируем их в нужный диапазон
    scaled_values = x_min + (random_values * (x_max - x_min) / (2**chromosome_length - 1))
    return np.round(scaled_values).astype(int)

# Функция для генерации случайных чисел для отбора
def generate_random_selection_numbers(size):
    return np.random.randint(0, 101, size=size)

# Функция для генерации сбалансированных групп
def generate_balanced_groups(size):
    # Создаем список групп, где каждая группа встречается ровно два раза
    groups = []
    for i in range(1, (size // 2) + 1):
        groups.extend([i, i])
    np.random.shuffle(groups)
    return groups

# Используем предопределенные значения (можно закомментировать для случайной генерации)
USE_PREDETERMINED_VALUES = False

if USE_PREDETERMINED_VALUES:
    x_values = [36, 35, 29, 40, 30, 51]  # Предопределенные значения X
    random_numbers = [91, 21, 12, 7, 24, 15]  # Предопределенные случайные числа
    group_ids = [1, 3, 2, 1, 2, 3]  # Предопределенные группы
else:
    np.random.seed()  # Инициализация генератора случайных чисел
    x_values = generate_random_x_values(population_size)
    random_numbers = generate_random_selection_numbers(population_size)
    group_ids = generate_balanced_groups(population_size)

# Создаем DataFrame для хранения данных
table = pd.DataFrame({
    'Особь': x_values,
})

# Вычисление целевой функции для каждого x
table['f(x)'] = table['Особь'].apply(target_function)

# Вычисляем сумму значений функции для нормализации
total_fx = table['f(x)'].sum()
table['P_i'] = table['f(x)'] / total_fx  # Вероятность отбора
table['S_i'] = table['P_i'] * 100  # В процентах

# Вычисляем границы для отбора
boundaries = [0]
for si in table['S_i']:
    boundaries.append(boundaries[-1] + si)
table['Границы'] = [(boundaries[i], boundaries[i + 1]) for i in range(len(boundaries) - 1)]

# Добавляем сгенерированные случайные числа
table['Случайные числа'] = random_numbers

# Определяем, какая особь соответствует каждой границе
def get_selected_individual(rnd_number):
    for idx, (low, high) in enumerate(table['Границы']):
        if low <= rnd_number < high:
            return idx
    return None

table['Пул'] = table['Случайные числа'].apply(get_selected_individual)

# Добавляем сгенерированные группы
table['Группы'] = group_ids

# Определяем пары для скрещивания на основе выбранных особей и групп
pairing_indices = []
for group, members in table.groupby('Группы'):
    selected_inds = members['Пул'].tolist()
    # Если группа имеет более одного члена, создаем пары
    for i in range(0, len(selected_inds) - 1, 2):
        pairing_indices.append((selected_inds[i], selected_inds[i + 1]))

# Вывод итоговой таблицы
print("Итоговая таблица:")
print(table)

# Функция скрещивания с выводом информации о процессе
def crossover(parent1, parent2):
    # Преобразование в бинарный формат
    parent1_bin = f"{parent1:06b}"
    parent2_bin = f"{parent2:06b}"

    # Скрещивание по описанному правилу
    offspring1_bin = parent1_bin[:3] + parent2_bin[3:]
    offspring2_bin = parent2_bin[:3] + parent1_bin[3:]

    # Преобразуем обратно в десятичное представление
    offspring1 = int(offspring1_bin, 2)
    offspring2 = int(offspring2_bin, 2)

    # Вывод информации о процессе скрещивания
    print(f"\nРодитель 1 (десятичный): {parent1}, (бинарный): {parent1_bin}")
    print(f"Родитель 2 (десятичный): {parent2}, (бинарный): {parent2_bin}")
    print(f"Потомок 1 (десятичный): {offspring1}, (бинарный): {offspring1_bin}")
    print(f"Потомок 2 (десятичный): {offspring2}, (бинарный): {offspring2_bin}")

    return offspring1, offspring2

# Создаем потомков и добавляем их в таблицу
offspring_list = []
for parent1_idx, parent2_idx in pairing_indices:
    parent1 = table.at[parent1_idx, 'Особь']
    parent2 = table.at[parent2_idx, 'Особь']
    off1, off2 = crossover(parent1, parent2)
    offspring_list.extend([off1, off2])

# Заполняем колонку потомков
table['Потомки'] = pd.Series(offspring_list)






скажи правильно ли происходит скрещивание в моем коде 
также думаю можно увеличить количество потомков до 5 то есть чтобы происходило 5 прогонов 
так вот каждое новое поколение должно так же проходить через функцию
и так как я понял нужно найти лучшую особь правильно?