精通遗传算法和蚁群算法
import numpy as np
import random
# 输入
C = np.array([[0, 15, 20, 0], [15, 0, 10, 10], [20, 10, 0, 5], [0, 10, 5, 0]])
D = np.array([[0, 10, 10], [10, 0, 10], [10, 10, 0]])
n = D.shape[0]
# 参数
population_size = 100
max_generations = 100
crossover_rate = 0.8
mutation_rate = 0.2
ant_num = 50
pheromone_evaporation_rate = 0.5
pheromones = np.ones_like(D)
def initialize_population():
return [np.random.randint(0, C.max(), size=n*n) for _ in range(population_size)]
def generate_chromosome():
chromosome = []
for i in range(D.shape[0]):
for j in range(D.shape[1]):
if i < j:
chromosome.append(random.randint(0, min(D[i,j], choose_best_physical_path_weight(i, j, C))))
else:
chromosome.append(0)
return chromosome
def choose_best_physical_path_weight(logical_source, logical_target, C):
paths = find_all_physical_paths(logical_source, logical_target, C, [logical_source])
if not paths:
return 0
# 获取最佳路径的最小权重
best_path_weights = [C[path[i]][path[i+1]] for path in paths for i in range(len(path)-1)]
return min(best_path_weights) if best_path_weights else 0
def construct_solution_by_ant():
solution = np.zeros_like(D)
for i in range(D.shape[0]):
for j in range(D.shape[1]):
if i < j and random.random() < pheromones[i, j]:
solution[i, j] = random.randint(0, min(D[i,j], choose_best_physical_path_weight(i, j, C)))
return solution
def fitness(chromosome):
S = np.array(chromosome).reshape(D.shape)
T = np.sum(S)
G = compute_gini(S)
return T / np.exp(G)
def compute_gini(S):
sorted_redundancy = np.sort(S.flatten())
cum_redundancy = np.cumsum(sorted_redundancy)
total_redundancy = np.sum(sorted_redundancy)
y = cum_redundancy / total_redundancy
x = np.arange(1, n*n+1) / (n*n)
G = 1 - np.sum((x[1:] - x[:-1]) * (y[1:] + y[:-1]))
return G
def select_parents(population, fitnesses):
idx = np.argsort(fitnesses)
return [population[i] for i in idx[:int(0.5*len(idx))]]
def crossover(parent1, parent2):
if random.random() < crossover_rate:
point = random.randint(0, len(parent1))
return np.concatenate((parent1[:point], parent2[point:]))
else:
return parent1
def mutate(chromosome):
for i in range(len(chromosome)):
if random.random() < mutation_rate:
chromosome[i] = random.randint(0, C.max())
return chromosome
def construct_solution_by_ant():
solution = np.zeros_like(D)
for i in range(D.shape[0]):
for j in range(D.shape[1]):
if i < j and random.random() < pheromones[i, j]:
solution[i, j] = random.randint(0, C.max())
return solution
def update_pheromone(solution):
global pheromones
pheromones = (1 - pheromone_evaporation_rate) * pheromones + solution
# 修改迭代次数
max_generations = 2000
# 重新执行主算法
population = initialize_population()
for generation in range(max_generations):
fitnesses = [fitness(chromosome) for chromosome in population]
parents = select_parents(population, fitnesses)
offspring = []
for i in range(0, len(parents) - 1, 2):
offspring1 = crossover(parents[i], parents[i+1])
offspring2 = crossover(parents[i+1], parents[i])
offspring.append(mutate(offspring1))
offspring.append(mutate(offspring2))
# 确保种群非空
if not offspring:
offspring = initialize_population()
population = offspring
for _ in range(ant_num):
solution = construct_solution_by_ant()
update_pheromone(solution)
# 确保在求最大值之前种群非空
if not population:
population = initialize_population()
best_solution = max(population, key=fitness)
S_best = best_solution.reshape(D.shape)
# 假定 C 矩阵的0值表示两节点之间没有直接连接,非0值表示有连接并给出连接的权重。
def find_all_physical_paths(source, target, C, current_path):
if source == target:
return [current_path]
paths = []
for i, value in enumerate(C[source]):
if value > 0 and i not in current_path:
new_path = current_path + [i]
paths.extend(find_all_physical_paths(i, target, C, new_path))
return paths
def choose_best_physical_path(logical_source, logical_target, C):
paths = find_all_physical_paths(logical_source, logical_target, C, [logical_source])
# 选择最佳物理路径的方法可以根据需要进一步定义,这里我们简单地选择第一个路径作为最佳路径。
# 实际应用中可能会根据其他标准,如路径的长度、权重等来选择。
return paths[0] if paths else []
# 输出结果
print("编号\t逻辑网络边起点n\t逻辑网络边终点m\t配置负载Se\t物理网络节点1\t物理网络节点2\t物理网络节点3\t物理网络节点4")
counter = 1
for i in range(n):
for j in range(n):
if i < j: # 确保n小于m
physical_path = choose_best_physical_path(i, j, C)
print(f"{counter}\t{i+1}\t{j+1}\t{S_best[i,j]}", end="\t")
for k in range(4):
if k < len(physical_path):
print(physical_path[k] + 1, end="\t")
else:
print(0, end="\t")
print()
counter += 1