From 7d234c0163861af23fbd25f7aaa80e3e2618d791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=A1=E5=9D=82=E3=82=B9=E3=83=90=E3=83=AB?= Date: Mon, 19 May 2025 10:23:14 +0800 Subject: [PATCH] archieve: homework5 --- homework5/.idea/.gitignore | 8 + .../.idea/MarsCodeWorkspaceAppSettings.xml | 7 + homework5/.idea/homework5.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + homework5/.idea/misc.xml | 6 + homework5/.idea/modules.xml | 8 + homework5/.idea/vcs.xml | 6 + homework5/main.py | 110 ++++++++++++ homework6/.idea/.gitignore | 8 + .../.idea/MarsCodeWorkspaceAppSettings.xml | 6 + homework6/.idea/homework6.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + homework6/.idea/misc.xml | 6 + homework6/.idea/modules.xml | 8 + homework6/.idea/vcs.xml | 6 + homework6/main.py | 165 ++++++++++++++++++ requirements.txt | Bin 5 -> 942 bytes 17 files changed, 372 insertions(+) create mode 100644 homework5/.idea/.gitignore create mode 100644 homework5/.idea/MarsCodeWorkspaceAppSettings.xml create mode 100644 homework5/.idea/homework5.iml create mode 100644 homework5/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 homework5/.idea/misc.xml create mode 100644 homework5/.idea/modules.xml create mode 100644 homework5/.idea/vcs.xml create mode 100644 homework5/main.py create mode 100644 homework6/.idea/.gitignore create mode 100644 homework6/.idea/MarsCodeWorkspaceAppSettings.xml create mode 100644 homework6/.idea/homework6.iml create mode 100644 homework6/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 homework6/.idea/misc.xml create mode 100644 homework6/.idea/modules.xml create mode 100644 homework6/.idea/vcs.xml create mode 100644 homework6/main.py diff --git a/homework5/.idea/.gitignore b/homework5/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/homework5/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/homework5/.idea/MarsCodeWorkspaceAppSettings.xml b/homework5/.idea/MarsCodeWorkspaceAppSettings.xml new file mode 100644 index 0000000..99506c3 --- /dev/null +++ b/homework5/.idea/MarsCodeWorkspaceAppSettings.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/homework5/.idea/homework5.iml b/homework5/.idea/homework5.iml new file mode 100644 index 0000000..2051088 --- /dev/null +++ b/homework5/.idea/homework5.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/homework5/.idea/inspectionProfiles/profiles_settings.xml b/homework5/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/homework5/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/homework5/.idea/misc.xml b/homework5/.idea/misc.xml new file mode 100644 index 0000000..6de7068 --- /dev/null +++ b/homework5/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/homework5/.idea/modules.xml b/homework5/.idea/modules.xml new file mode 100644 index 0000000..40c1671 --- /dev/null +++ b/homework5/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/homework5/.idea/vcs.xml b/homework5/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/homework5/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/homework5/main.py b/homework5/main.py new file mode 100644 index 0000000..2561a83 --- /dev/null +++ b/homework5/main.py @@ -0,0 +1,110 @@ +import matplotlib +import numpy as np +from numpy.ma import cos +import matplotlib.pyplot as plt +from matplotlib import cm +from mpl_toolkits.mplot3d import Axes3D +import datetime + +matplotlib.use('Qt5Agg') + +DNA_SIZE = 24 # 编码长度 +POP_SIZE = 100 # 种群大小 +CROSS_RATE = 0.8 # 交叉率 +MUTA_RATE = 0.15 # 变异率 +Iterations = 1000 # 代次数 +X_BOUND = [0, 10] # X区间 +Y_BOUND = [0, 10] # Y区间 + + +def F(x, y): # 适应度函数 + return (6.452 * (x + 0.125 * y) * (cos(x) - cos(2 * y)) ** 2) / ( + 0.8 + (x - 4.2) ** 2 + 2 * (y - 7) ** 2) + 3.226 * y + + +def decodeDNA(pop): # 解码 + x_pop = pop[:, 1::2] # 奇数列表示X + y_pop = pop[:, ::2] # 偶数列表示y + x = x_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (X_BOUND[1] - X_BOUND[0]) + X_BOUND[0] + y = y_pop.dot(2 ** np.arange(DNA_SIZE)[::-1]) / float(2 ** DNA_SIZE - 1) * (Y_BOUND[1] - Y_BOUND[0]) + Y_BOUND[0] + return x, y + + +def getfitness(pop): + x, y = decodeDNA(pop) + temp = F(x, y) + return (temp - np.min(temp)) + 0.0001 # 减去最小的适应度是为了防止适应度出现负数 + + +def select(pop, fitness): # 根据适应度选择 + temp = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True, p=(fitness) / (fitness.sum())) + return pop[temp] + + +def crossmuta(pop, CROSS_RATE): + new_pop = [] + for i in pop: # 遍历种群中的每一个个体,将该个体作为父代 + temp = i # 子代先得到父亲的全部基因 + if np.random.rand() < CROSS_RATE: # 以交叉概率发生交叉 + j = pop[np.random.randint(POP_SIZE)] # 从种群中随机选择另一个个体,并将该个体作为母代 + cpoints1 = np.random.randint(0, DNA_SIZE * 2 - 1) # 随机产生交叉的点 + cpoints2 = np.random.randint(cpoints1, DNA_SIZE * 2) + temp[cpoints1:cpoints2] = j[cpoints1:cpoints2] # 子代得到位于交叉点后的母代的基因 + mutation(temp, MUTA_RATE) # 后代以变异率发生变异 + new_pop.append(temp) + return new_pop + + +def mutation(temp, MUTA_RATE): + if np.random.rand() < MUTA_RATE: # 以MUTA_RATE的概率进行变异 + mutate_point = np.random.randint(0, DNA_SIZE) # 随机产生一个实数,代表要变异基因的位置 + temp[mutate_point] = temp[mutate_point] ^ 1 # 将变异点的二进制为反转 + + +def print_info(pop): # 用于输出结果 + fitness = getfitness(pop) + maxfitness = np.argmax(fitness) # 返回最大值的索引值 + print("max_fitness:", fitness[maxfitness]) + x, y = decodeDNA(pop) + print("最优的基因型:", pop[maxfitness]) + print("(x, y):", (x[maxfitness], y[maxfitness])) + print("F(x,y)_max = ", F(x[maxfitness], y[maxfitness])) + + +def plot_3d(ax): + X = np.linspace(*X_BOUND, 100) + Y = np.linspace(*Y_BOUND, 100) + X, Y = np.meshgrid(X, Y) + Z = F(X, Y) + ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm) + ax.set_zlim(-20, 100) + ax.set_xlabel('x') + ax.set_ylabel('y') + ax.set_zlabel('z') + plt.pause(0.01) # 缩短暂停时间 + # 移除 plt.show() + + +start_t = datetime.datetime.now() +if __name__ == "__main__": + plt.ion() # 提前设置交互模式 + fig = plt.figure() + ax = fig.add_subplot(111, projection='3d') # 修改3D坐标创建方式 + plot_3d(ax) + + pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE * 2)) + for _ in range(Iterations): + x, y = decodeDNA(pop) + if 'sca' in locals(): + sca.remove() + sca = ax.scatter(x, y, F(x, y), c='red', marker='o', s=50) # 增大标记尺寸 + plt.draw() # 强制重绘 + plt.pause(0.01) # 保证足够的更新时间 + pop = np.array(crossmuta(pop, CROSS_RATE)) + fitness = getfitness(pop) + pop = select(pop, fitness) # 选择生成新的种群 +end_t = datetime.datetime.now() +print((end_t - start_t).seconds) +print_info(pop) +plt.ioff() +plot_3d(ax) diff --git a/homework6/.idea/.gitignore b/homework6/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/homework6/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/homework6/.idea/MarsCodeWorkspaceAppSettings.xml b/homework6/.idea/MarsCodeWorkspaceAppSettings.xml new file mode 100644 index 0000000..05ed8ba --- /dev/null +++ b/homework6/.idea/MarsCodeWorkspaceAppSettings.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/homework6/.idea/homework6.iml b/homework6/.idea/homework6.iml new file mode 100644 index 0000000..2051088 --- /dev/null +++ b/homework6/.idea/homework6.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/homework6/.idea/inspectionProfiles/profiles_settings.xml b/homework6/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/homework6/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/homework6/.idea/misc.xml b/homework6/.idea/misc.xml new file mode 100644 index 0000000..6de7068 --- /dev/null +++ b/homework6/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/homework6/.idea/modules.xml b/homework6/.idea/modules.xml new file mode 100644 index 0000000..34661de --- /dev/null +++ b/homework6/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/homework6/.idea/vcs.xml b/homework6/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/homework6/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/homework6/main.py b/homework6/main.py new file mode 100644 index 0000000..dbac13f --- /dev/null +++ b/homework6/main.py @@ -0,0 +1,165 @@ +import numpy as np +import random +import matplotlib.pyplot as plt +import copy + +# 各个城市的坐标 +# City_Map = [[106.54,29.59] +# ,[91.11,29.97] +# ,[87.68,43.77] +# ,[106.27,38.47] +# ,[111.65,40.82] +# ,[108.33,22.84] +# ,[126.63,45.75] +# ,[125.35,43.88] +# ,[123.38,41.8] +# ,[114.48,38.03] +# ,[112.53,37.87] +# ,[101.74,36.56] +# ,[117,36.65] +# ,[113.6,34.76] +# ,[118.78,32.04] +# ,[117.27,31.86]] + +City_Map = 100 * np.random.rand(20, 2) # 随机产生20个城市 + +DNA_SIZE = len(City_Map) # 编码长度 +POP_SIZE = 200 # 种群大小 +CROSS_RATE = 0.6 # 交叉率 +MUTA_RATE = 0.2 # 变异率 +Iterations = 1000 # 迭代次数 + + +def distance(DNA): # 根据DNA的路线计算距离 + dis = 0 + temp = City_Map[DNA[0]] + for i in DNA[1:]: + dis = dis + ((City_Map[i][0] - temp[0]) ** 2 + (City_Map[i][1] - temp[1]) ** 2) ** 0.5 + temp = City_Map[i] + return dis + ((temp[0] - City_Map[DNA[0]][0]) ** 2 + (temp[1] - City_Map[DNA[0]][1]) ** 2) ** 0.5 + + +def getfitness(pop): # 计算种群适应度,这里适应度用距离的倒数表示 + temp = [] + for i in range(len(pop)): + temp.append(1 / (distance(pop[i]))) + return temp - np.min(temp) + + +def select(pop, fitness): # 根据适应度选择,以赌轮盘的形式,适应度越大的个体被选中的概率越大 + s = fitness.sum() + temp = np.random.choice(np.arange(len(pop)), size=POP_SIZE, replace=True, p=(fitness / s)) + p = [] + for i in temp: + p.append(pop[i]) + return p + + +def mutation(DNA, MUTA_RATE): # 进行变异 + if np.random.rand() < MUTA_RATE: # 以MUTA_RATE的概率进行变异 + mutate_point1 = np.random.randint(0, DNA_SIZE) # 随机产生一个实数,代表要变异基因的位置 + mutate_point2 = np.random.randint(0, DNA_SIZE) # 随机产生一个实数,代表要变异基因的位置 + while (mutate_point1 == mutate_point2): # 保证2个所选位置不相等 + mutate_point2 = np.random.randint(0, DNA_SIZE) + DNA[mutate_point1], DNA[mutate_point2] = DNA[mutate_point2], DNA[mutate_point1] # 2个所选位置进行互换 + + +def crossmuta(pop, CROSS_RATE): # 交叉变异 + new_pop = [] + for i in range(len(pop)): # 遍历种群中的每一个个体,将该个体作为父代 + n = np.random.rand() + if n >= CROSS_RATE: # 大于交叉概率时不发生变异,该子代直接进入下一代 + temp = pop[i].copy() + new_pop.append(temp) + + if n < CROSS_RATE: # 小于交叉概率时发生变异 + list1 = pop[i].copy() + list2 = pop[np.random.randint(POP_SIZE)].copy() # 选取种群中另一个个体进行交叉 + status = True + while status: # 产生2个不相等的节点,中间部分作为交叉段,采用部分匹配交叉 + k1 = random.randint(0, len(list1) - 1) + k2 = random.randint(0, len(list2) - 1) + if k1 < k2: + status = False + + k11 = k1 + + fragment1 = list1[k1: k2] + fragment2 = list2[k1: k2] + + list1[k1: k2] = fragment2 + list2[k1: k2] = fragment1 + + del list1[k1: k2] + left1 = list1 + + offspring1 = [] + for pos in left1: + if pos in fragment2: + pos = fragment1[fragment2.index(pos)] + while pos in fragment2: + pos = fragment1[fragment2.index(pos)] + offspring1.append(pos) + continue + offspring1.append(pos) + for i in range(0, len(fragment2)): + offspring1.insert(k11, fragment2[i]) + k11 += 1 + temp = offspring1.copy() + mutation(temp, MUTA_RATE) + + new_pop.append(temp) # 把部分匹配交叉后形成的合法个体加入到下一代种群 + + return new_pop + + +def print_info(pop): # 用于输出结果 + fitness = getfitness(pop) + maxfitness = np.argmax(fitness) # 得到种群中最大适应度个体的索引 + # 打印结果 + print("最优的基因型:", pop[maxfitness]) + print("最短距离:", distance(pop[maxfitness])) + # 按最优结果顺序把地图上的点加入到best_map列表中 + best_map = [] + for i in pop[maxfitness]: + best_map.append(City_Map[i]) + best_map.append(City_Map[pop[maxfitness][0]]) + X = np.array((best_map))[:, 0] + Y = np.array((best_map))[:, 1] + # 绘制地图以及路线 + plt.figure() + plt.rcParams['font.sans-serif'] = ['SimHei'] + plt.scatter(X, Y) + for dot in range(len(X) - 1): + plt.annotate(pop[maxfitness][dot], xy=(X[dot], Y[dot]), xytext=(X[dot], Y[dot])) + plt.annotate('start', xy=(X[0], Y[0]), xytext=(X[0] + 1, Y[0])) + plt.plot(X, Y) + + +if __name__ == "__main__": # 主循环 + # 生成初代种群pop + pop = [] + list = list(range(DNA_SIZE)) + for i in range(POP_SIZE): + random.shuffle(list) + l = list.copy() + pop.append(l) + best_dis = [] + # 进行选择,交叉,变异,并把每代的最优个体保存在best_dis中 + for i in range(Iterations): # 迭代N代 + pop = crossmuta(pop, CROSS_RATE) + fitness = getfitness(pop) + maxfitness = np.argmax(fitness) + best_dis.append(distance(pop[maxfitness])) + pop = select(pop, fitness) # 选择生成新的种群 + + print_info(pop) # 打印信息 + + print('逐代的最小距离:', best_dis) + +# 画图 +plt.figure() +plt.plot(range(Iterations), best_dis) +plt.show() +plt.close() + diff --git a/requirements.txt b/requirements.txt index 296d654528b719e554528b956c4bf5a1516e812c..3f1441ecfc6291a8e9db59507068a71b268d3c33 100644 GIT binary patch literal 942 zcmZuwNp8YG5bSfLJO#wC7&zpT7bGu0jxmXaH+jL~^GT|@XKXA*BU{K_T}$`y`|~P| zRMJTV64XjmE9rr&x~=g& z*Gz-=z|^)0W5~c_U7VO{avS7s;BMk&M$>2K8!+#fz)ri_>vZPa&%D0)7iaz^mXm6k z7pFQ-_M@YKi&QPbch=@g5w=3VfrEaJBZ`?i`NB3zO#O^>9p>HR%?X9M6VLh9z_qB^ zJh-C{*c$K0o3_`)2kl|zNu3UzG6jZAzE#EMKP4k$0SERUneUgi27Y6`Mf6DCX}djY eyf+o75QLln literal 5 Mcmc~R%`K<|00y4|IsgCw