archieve: homework5
This commit is contained in:
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="com.codeverse.userSettings.MarscodeWorkspaceAppSettingsState">
|
||||||
|
<option name="chatAppRouterInfo" value="chat" />
|
||||||
|
<option name="ckgOperationStatus" value="SUCCESS" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="ai-homework" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="ai-homework" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/homework5.iml" filepath="$PROJECT_DIR$/.idea/homework5.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -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)
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="com.codeverse.userSettings.MarscodeWorkspaceAppSettingsState">
|
||||||
|
<option name="ckgOperationStatus" value="SUCCESS" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="jdk" jdkName="ai-homework" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="ai-homework" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/homework6.iml" filepath="$PROJECT_DIR$/.idea/homework6.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -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()
|
||||||
|
|
||||||
Binary file not shown.
Reference in New Issue
Block a user