import numpy as np

import random

# Функция для оценки приспособленности распределения задач

def network_load(tasks_distribution):

return np.sum(tasks_distribution)

# Применение операторов мутации и скрещивания для создания новых кандидатов

def mutation(tasks_distribution):

mutated_tasks_distribution = tasks_distribution.copy()

server_index = np.random.randint(len(tasks_distribution))

task_index = np.random.randint(len(tasks_distribution[0]))

mutated_tasks_distribution[server_index][task_index] = np.random.randint(0, 100)

return mutated_tasks_distribution

def crossover(parent1, parent2):

child = parent1.copy()

for i in range(len(parent1)):

for j in range(len(parent1[0])):

if np.random.rand() > 0.5:

child[i][j] = parent2[i][j]

return child

def replace_worst_part(population, new_candidates):

fitness_values = [network_load(tasks_distribution) for tasks_distribution in population]

sorted_indices = np.argsort(fitness_values)

worst_part_indices = sorted_indices[-len(new_candidates):]

for i, index in enumerate(worst_part_indices):

population[index] = new_candidates[i]

return population

# Определение параметров задачи и алгоритма

num_servers = 3

num_tasks = 5

population_size = 10

num_generations = 100

# Инициализация начальной популяции

population = [np.random.randint(0, 100, (num_servers, num_tasks)) for _ in range(population_size)]

# Основной цикл генетического алгоритма

for generation in range(num_generations):

# Оценка приспособленности текущей популяции

fitness_values = [network_load(tasks_distribution) for tasks_distribution in population]

# Выбор лучших кандидатов для скрещивания

sorted_indices = np.argsort(fitness_values)

best_candidates = [population[i] for i in sorted_indices[:population_size // 2]]

# Создание новых кандидатов с помощью скрещивания и мутации

new_candidates = []

for _ in range(population_size // 2):

parent1 = random.choice(best_candidates)

parent2 = random.choice(best_candidates)

child = crossover(parent1, parent2)

if np.random.rand() < 0.5:

child = mutation(child)

new_candidates.append(child)

# Замена худшей части популяции на новых кандидатов

population = replace_worst_part(population, new_candidates)

# Вывод лучшего результата

best_solution = population[np.argmin([network_load(tasks_distribution) for tasks_distribution in population])]

print("Лучшее распределение задач:", best_solution)

print("Приспособленность:", network_load(best_solution))

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

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

Например, вывод программы может выглядеть следующим образом:

```

Лучшее распределение задач:

[[20 15 10 25 30]

[10 25 20 30 15]

[30 20 25 10 15]]

Приспособленность: 190

```

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

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