我是丽丽呀 2021-12-04 18:52 采纳率: 0%
浏览 351
已结题

ACO(蚁群算法)和GA(遗传算法)算法的融合

问题遇到的现象和发生背景

python代码转MATLAB

我想要达到的结果

import tkinter
from functools import reduce
import numpy as np
import random
import math
import matplotlib.pyplot as plt
import time

# 初始化GA参数
prob, mutationProb, population, gaIter, MaxGaIter = 0.8, 0.08, 200, 0, 100

# 初始化ACA参数
alpha, beta, rho, q, generation, generations = 1, 2, 0.4, 100, 0, 200
cities, ants = 50, 50
best_lengthls = []
mean_lengthls = []
distance_x = [
    178, 272, 176, 171, 650, 499, 267, 703, 408, 437, 491, 74, 532,
    416, 626, 42, 271, 359, 163, 508, 229, 576, 147, 560, 35, 714,
    757, 517, 64, 314, 675, 690, 391, 628, 87, 240, 705, 699, 258,
    428, 614, 36, 360, 482, 666, 597, 209, 201, 492, 294]
distance_y = [
    170, 395, 198, 151, 242, 556, 57, 401, 305, 421, 267, 105, 525,
    381, 244, 330, 395, 169, 141, 380, 153, 442, 528, 329, 232, 48,
    498, 265, 343, 120, 165, 50, 433, 63, 491, 275, 348, 222, 288,
    490, 213, 524, 244, 114, 104, 552, 70, 425, 227, 331]

distance_graph = np.zeros((cities, cities))  # 初始化城市距离,城市i到j的距离dij

for i in range(cities):
    for j in range(cities):
        temp_distance = pow((distance_x[i] - distance_x[j]), 2) + pow((distance_y[i] - distance_y[j]), 2)  # 二维空间的距离
        temp_distance = pow(temp_distance, 0.5)
        distance_graph[i][j] = temp_distance  # 将各个城市之间的距离进行存储,

eta = 1.0 / (distance_graph + np.diag([1e10] * cities))  # 启发式函数  eta从i城市到j城市的可见度
path = np.zeros((ants, cities), dtype=np.int)  # dtype=np.int 数据类型
# 最佳路径
best_path = []
best_length = np.inf  # np.inf 表示+∞,是没有确切的数值的,类型为浮点型

# 存放GA算法的输出:若干组优秀解
gaOutput = np.zeros((population, cities))


# 染色体的路程代价函数  计算每个染色体对应的总长度
def myLength(index_path):
    fit = 0
    for i in range(cities - 1):
        tmp = distance_graph[index_path[i]][index_path[i + 1]]
        fit += tmp
    fit += distance_graph[index_path[-1]][index_path[0]]
    return fit


# GA
# 初始化种群
pops = np.zeros((population, cities), dtype=np.int)
temp = np.arange(cities)
for i in range(population):
    np.random.shuffle(temp)
    pops[i] = temp


# 交叉函数
def cross(pop):
    numbers = np.uint8(population * prob) - 1
    if numbers % 2 != 0:
        numbers += 1
    index = random.sample(range(1, population), numbers)
    new_pops1 = np.zeros((population, cities), dtype=np.int)
    # 确保精英不会进去交配
    new_pops1[0] = pop[np.argmin(fits)]
    # 将不需要交叉的染色体直接复制到新的种群中
    for i in range(1, population):
        if not index.__contains__(i):
            new_pops1[i] = pop[i]
    # 交叉
    j = 0
    while j < numbers:
        # w需要交叉的位数
        w = 0
        if cities < 10:
            w = cities
        elif ((cities / 10) - np.floor(cities / 10)) >= np.random.random() and cities > 10:
            w = math.ceil(cities / 10) + 10
        else:
            w = math.floor(cities / 10) + 10
        p = np.random.randint(0, cities - w + 1)
        for i in range(w):
            x = pop[index[j + 1]].tolist().index(pop[index[j]][p + i - 1])
            y = pop[index[j]].tolist().index(pop[index[j + 1]][p + i - 1])
            # exchange  \是换行
            pop[index[j + 1]][p + i - 1], pop[index[j]][p + i - 1] = pop[index[j]][p + i - 1], pop[index[j + 1]][p + i - 1]
            pop[index[j + 1]][x], pop[index[j]][y] = pop[index[j]][y], \
                                                     pop[index[j + 1]][x]

        # 等待所有位置交叉完成 再重新赋值
        new_pops1[index[j]] = pop[index[j]]
        new_pops1[index[j + 1]] = pop[index[j + 1]]
        j += 2
    return new_pops1


# 变异函数
def mutation(per_pop):
    # 生成两个变异位置
    cross_points = np.random.randint(0, cities, 2)
    cross_point_1, cross_point_2 = cross_points[0], cross_points[1]
    # 交换位置
    per_pop[cross_point_1], per_pop[cross_point_2] = per_pop[cross_point_2], per_pop[cross_point_1]
    return per_pop


# 选择函数
def select(pop, fit):
    prob_fit = fit / sum(fit)
    cum_prob = np.cumsum(prob_fit)
    new_pop = np.zeros((population, cities))
    # fitness最小的个体被保留 必定进入下一代
    new_pop[0] = pop[np.argmin(fit)]
    for i in range(1, population):
        tmp = np.random.random()
        for j in range(population):
            # 被选中
            if tmp < cum_prob[j]:
                new_pop[i] = pop[j]
                break
    return new_pop.astype(int)


def fitness(l, m, maxlen, minlen):  # 适应度函数每次迭代都要计算每个染色体在本种群内部的优先级别,类似归一化参数。越大约好!
    fit = np.zeros(population)
    for i in range(len(l)):
        fit[i] = (1 - (l[i] - minlen) / (maxlen - minlen + 0.001)) ** m
    return fit


m = 3  # 适应值归一化淘汰加速指数

# 主循环
while gaIter < MaxGaIter:
    length = np.zeros(population)
    # 计算适应度值
    for i in range(population):
        length[i] = myLength(pops[i])
    # 归一化
    maxlen = max(length)  # 最大回路
    minlen = min(length)  # 最小回路
    fits = fitness(length, m, maxlen, minlen)
    # 选择
    pops = select(pops, fits)

    # 交叉操作
    pops = cross(pop=pops)

    # 变异
    for i in range(population):
        if mutationProb > np.random.random():
            pops[i] = mutation(pops[i])
    gaIter += 1
# 输出所有的路径长度
# print("所有路径长度:\n",pops)
for a in pops:
    print("每个染色体对应长度:\n", myLength(a))
gaOutput = pops
pheromone = np.zeros((cities, cities))
# 每一条dij和dji路径 出现一次加k的信息素浓度
#
# k=0.6
# k = q / length.mean()

for i in range(int(population)):
    for j in range(cities - 1):
        pheromone[gaOutput[i][j]][gaOutput[i][j + 1]] += q / length[i]
        pheromone[gaOutput[i][j + 1]][gaOutput[i][j]] += q / length[i]
    pheromone[gaOutput[i][-1]][gaOutput[i][0]] += q / length[i]
    pheromone[gaOutput[i][0]][gaOutput[i][-1]] += q / length[i]
print("初始化信息素矩阵:\n", pheromone)
# 根据gaOutput 初始化信息素矩阵

print("从i城市到j城市的可见度:\n", eta)  # eta:从i城市到j城市的可见度
while generation < generations:
    # 初始化蚂蚁位置
    if ants < cities:
        path[:, 0] = np.random.permutation(cities)[:ants]
    else:
        path[:cities, 0] = np.random.permutation(cities)[:]
        path[cities:, 0] = np.random.permutation(cities)[:ants - cities]
    length = np.zeros(ants)
    # 计算第k只蚂蚁从i城市到达j城市的概率
    # 遍历每一只蚂蚁
    for k in range(ants):
        # 搜索一条路就
        visited = path[k, 0]
        unvisited = set(range(cities))
        unvisited.remove(visited)

        for i in range(1, cities):
            l_unvisited = list(unvisited)
            prob_next_city = np.zeros(len(l_unvisited), dtype=np.float64)
            for j in range(len(l_unvisited)):
                prob_next_city[j] = pow(pheromone[visited][l_unvisited[j]], alpha) * pow(eta[visited][l_unvisited[j]],
                                                                                         beta)
                # 解决精度问题
                if prob_next_city[j] == 0.0:
                    prob_next_city[j] = 0.00001

            prob_next_city = prob_next_city / np.sum(prob_next_city, dtype=float)
            prob_next_city = np.cumsum(prob_next_city)
            temp_prob = np.random.random()
            next_city = -1
            # 轮盘赌算法
               for p in range(len(prob_next_city)):
                # 第p个城市赌成功
                if not math.isnan(prob_next_city[p]):
                    if prob_next_city[p] >= temp_prob:
                        next_city = l_unvisited[p]
                        break

            unvisited.remove(next_city)
            path[k, i] = next_city
            length[k] += distance_graph[visited][next_city]
            visited = next_city
        length[k] += distance_graph[visited][path[k, 0]]
    mean_lengthls.append(sum(length)/ants)

    # 调整最短长度和最佳路径
    if length.min() < best_length:
        best_length = length.min()
        best_path = path[length.argmin()]


    tmp_pheromone = np.zeros((cities, cities))
    #list = []
    for i in range(ants):
        for j in range(cities - 1):
            # 使用了蚁环算法   蚁周模型:释放总量一定,利用路径整体信息计算
            # length[i]为第i只蚂蚁当前次遍历的路径长度 作为整体信息进行信息素的更新
            tmp_pheromone[path[i, j]][path[i, j + 1]] += q / length[i]
            # 从j城市到i城市的距离dji与dij一致 因此信息素浓度一致
            if tmp_pheromone[path[i, j + 1]][path[i, j]] < tmp_pheromone[path[i, j]][path[i, j + 1]]:
                tmp_pheromone[path[i, j + 1]][path[i, j]] = tmp_pheromone[path[i, j]][path[i, j + 1]]
        tmp_pheromone[path[i, cities - 1]][path[i, 0]] += q / length[i]
        # 蚁密算法  蚁密模型:每段路释放量一定:
        # tmp_pheromone[path[i, j]][path[i, j + 1]] += q
        # tmp_pheromone[path[i, cities - 1]][path[i, 0]] += q
        # 蚁量算法 与当前城市之间距离成反比   蚁量模型:释放总量一定,利用路径局部信息计算:
        # tmp_pheromone[path[i, j]][path[i, j + 1]] += q / distance_graph[path[i, j]][path[i, j + 1]]
        # tmp_pheromone[path[i, cities - 1]][path[i, 0]] += q / distance_graph[path[i, cities - 1]][path[i, 0]]
    # 更新从i到j城市的路径的信息素浓度
    pheromone = (1 - rho) * pheromone + tmp_pheromone
    generation += 1
    best_lengthls.append(best_length)
    print("当前迭代次数:", generation, "\n当前最短长度:", best_length)

print("迭代次数:", generations)
print("最佳路径:", best_path)
print("最短长度:", best_length)
print('返回的数据类型', type(linesList))
print('数据大小:', len(linesList))

# 如遇中文显示问题可加入以下代码
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题

# 绘图
x = [i for i in range(200)]
y1 = best_lengthls
y2 = mean_lengthls
l1, = plt.plot(x, y2, color='red', linewidth=1.0, linestyle='--', label='平均距离')
l2, = plt.plot(x, y1, label='最短距离')


# 简单的设置legend(设置位置)
# 位置在右上角
plt.legend(loc='upper right')
plt.xlabel('迭代次数')
plt.xticks( np.arange(0, 250, 50))
plt.ylabel('距离')
plt.yscale('log')
plt.title('GA_ACO各代最短距离与平均距离对比')
plt.show()

各位,能帮帮我么,我想用GA和ACO结合,这是我找的python代码,怎么转成MATLAB代码呀,或者说你们谁有用MATLAB写的GA和ACO融合算法求解TSP问题的代码呢

  • 写回答

1条回答 默认 最新

  • 有问必答小助手 2021-12-06 11:25
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


    因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

    评论

报告相同问题?

问题事件

  • 系统已结题 12月12日
  • 创建了问题 12月4日

悬赏问题

  • ¥50 请教 麒麟系统挂载怎么安装
  • ¥15 如何在ns3中实现路径的自由切换
  • ¥20 SpringBoot+Vue3
  • ¥15 IT从业者的调查问卷
  • ¥65 LineageOs-21.0系统编译问题
  • ¥30 关于#c++#的问题,请各位专家解答!
  • ¥15 App的会员连续扣费
  • ¥15 不同数据类型的特征融合应该怎么做
  • ¥15 用proteus软件设计一个基于8086微处理器的简易温度计
  • ¥15 用联想小新14Pro