pycode_cw/c_cpp/BA.py

627 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import networkx as nx
import numpy as np
import random
import math
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
ind = 10000
n = 35
memlen = 3
state = np.zeros([n, ind + 1])
initx = np.zeros(n)
inity = np.zeros(n)
initz = np.zeros(n)
finalx = np.zeros(n)
finaly = np.zeros(n)
finalz = np.zeros(n)
for i in range(0, n):
# initx[i] = random.random() * 100
# inity[i] = random.random() * 100
# initz[i] = random.random() * 100
# finalx[i] = random.random() * 100
# finaly[i] = random.random() * 100
# finalz[i] = random.random() * 100
# initx[i] = 20*random.random() + 30
# inity[i] = 20*random.random() + 30
# initz[i] = 0
# finalx[i] = 2+i*40/n
# finalz[i] = 75
# finaly[i] = 22-abs(i-16)*20/22
# initx[i] = 2 + i*40/n
# initz[i] = 75
# inity[i] = 22-abs(i-17)*20/17
# finalx[i] = 5+3*int(i%7)
# finalz[i] = 75+3*int(i/7)
# finaly[i] = finalz[i]-15
initx[i] = 15+3*int(i%7)
initz[i] = 75+3*int(i/7)
inity[i] = initz[i]+5
psai = 2*math.pi*i/35
finalx[i] = 120+10*math.cos(psai)
finaly[i] = 80+10*math.sin(psai)
finalz[i] = 50
# initx[i] = 20 + 8 * math.cos(math.pi * 2 * i / n)
# inity[i] = 80 + 8 * math.sin(math.pi * 2 * i / n)
# finalx[i] = 30 + i * 10 / n
# finaly[i] = 15 + i * 15 / n
# initx[i] = 30 + i * 10 / n
# inity[i] = 15 + i * 15 / n
# finalx[i] = 85-15*abs(i-7)/7
# finaly[i] = 60-40*i/n
# initx[i] = 10 + 2 * i * 11 / n
# inity[i] = 20 #+ 10 * math.sin(math.pi * 2 * i / n)
# finalx[i] = 50 - 2 * i * 11 / n
# finaly[i] = 65
# if i <10:
# initx[i] = random.random()*30
# else:
# initx[i] = random.random()*30 + 70
# inity[i] = random.random()*30
# finalx[i] = 50 + 10 * math.cos(math.pi * 2 * i / n)
# finaly[i] = 80 + 10 * math.sin(math.pi * 2 * i / n)
#计算无人机到目标点距离输入无人机群的xy坐标目标位置的xy坐标
def getdis(x1, y1, z1,x2, y2,z2):
dis1 = np.zeros((n, n))
for i in range(0, n):
for j in range(0, n):
dis1[i, j] = math.sqrt((x1[i] - x2[j])**2 + (y1[i] - y2[j])**2+(z1[i] - z2[j])**2)
return dis1
dis = getdis(initx,inity,initz,finalx,finaly,finalz)
#计算无人机之间距离并判断连接关系输入无人机群的xy坐标
def getcon(x1, y1,z1):
juli1 = np.zeros((n, n))
for i in range(0, n):
for j in range(0, n):
juli1[i, j] = math.sqrt((x1[i] - x1[j])**2 + (y1[i] - y1[j])**2+(z1[i] - z1[j])**2)
con = []
for i in range(0, n):
tmpcon = []
for j in range(0, n):
if (juli1[i][j] <= 1000 and i != j):
tmpcon.append(j)
con.append(tmpcon)
return con
# for i in range(0, n):
# for j in range(0, n):
# dis[i, j] = math.sqrt((initx[i] - finalx[j])**2 +
# (inity[i] - finaly[j])**2)
# juli[i, j] = math.sqrt(
# (initx[i] - initx[j])**2 + (inity[i] - inity[j])**2) #建立距离存储表格
mem = np.zeros([n, memlen]) #创建记忆存储表格
# con = []
# for i in range(0, n):
# tmpcon = []
# for j in range(0, n):
# if (juli[i][j] <= 150 and i != j):
# tmpcon.append(j)
# con.append(tmpcon)
def gettasks(dis):
tasks = []
for i in range(0, n):
temptsk = []
for j in range(0, n):
if dis[i, j] <= 1400:
temptsk.append(j)
tasks.append(temptsk)
return tasks
con = getcon(initx,inity,initz)
#创建任务集距离80以内才能作为可选任务
tasks = gettasks(dis)
for i in range(0, n):
state[i, 0] = int(i)
#定义个体寻找相同点的函数
def findrep(s1, co1, repi, t):
count = 0
for vb in range(0, len(co1[repi])):
if s1[repi, t] == s1[co1[repi][vb], t] and repi != vb:
count = count + 1
return count
#定义寻找list最优点位置程序
def findmin(c):
listmin = min(c)
for r in range(0, len(c)):
if c[r] == listmin:
stra = r
break
return stra
def memre(mem):
for q in range(1, memlen):
for p in range(0, n):
mem[p, memlen - q] = mem[p, memlen - 1 - q]
def findrep(choice_place, con, i, t):
a1 = 0
for j in range(0, len(con[i])):
if choice_place == state[con[i][j], t]:
a1 = a1 + 1
return a1
def calchoice(t):
if (t == 0):
choice = 0
else:
if (t < memlen):
choice = int(random.random() * t)
else:
choice = int(random.random() * memlen)
return choice
costsum = np.zeros([n, ind])
stop = np.zeros(n)
# def distribute(tasks, dis, con):
# t = 0
# while t < ind:
# for i in range(0, n):
# costsum[i, t] = (findrep(state[i, t], con, i, t) * 1000 +
# dis[i, int(state[i, t])])
# for p in range(1, memlen):
# for q in range(0, n):
# mem[q, memlen - p] = mem[q, memlen - 1 - p]
# for i in range(0, n):
# if (stop[i] == 0):
# cost = []
# for k in range(0, len(tasks[i])):
# cost.append(dis[i, tasks[i][k]] +
# 1000 * findrep(tasks[i][k], con, i, t))
# mem[i, 0] = tasks[i][findmin(cost)]
# else:
# mem[i, 0] = state[i, t]
# for l in range(0, n):
# choice = calchoice(t)
# state[l, t + 1] = mem[l, choice]
# t = t + 1
# return state
# #如果进行再分配,无人机即使避开了此次的重复选择,在选择新的位置时,仍然将选择其他无人机已经选择但是它不知道的位置。
# state = distribute(tasks, dis, con)
# np.savetxt('D:/ws0.csv', state, fmt="%d", delimiter=",")
#开始计算博弈
for t in range(0, ind):
memre(mem)#需要考虑顺序的影响吗
for i in range(0, n):
costsum[i, t] = (findrep(state[i, t], con,i,t) * 1000 +
dis[i, int(state[i, t])])
for i in range(0, n):
cost = []
for k in range(0, len(tasks[i])):
cost.append(dis[i, tasks[i][k]] +
1000 * findrep(tasks[i][k], con,i,t)) #存储每个选择的花费
#应该改成:首先生成一轮最优解,后续的每一轮依据之前的选择存入状态,用这个状态判断重复。
#经过如此完成多次的反思最终确定结果
#state[i, t] = findmin(cost) #需要后续修改
mem[i, 0] = tasks[i][findmin(cost)]
for l in range(0, n):
if (t == 0):
choice = 0
else:
if (t < memlen):
choice = int(random.random() * t)
else:
choice = int(random.random() * memlen)
state[l, t + 1] = mem[l, choice]
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# plt.title("15架无人机视角下花费变化图")
# plt.xlabel('迭代次数')
# plt.ylabel("花费")
# for i in range(0, n):
# for j in range(0, 500):
# plt.plot([j, j + 1], [costsum[i, j], costsum[i, j + 1]])
# plt.show()
np.savetxt('D:/ws0.csv', state, fmt="%d", delimiter=",")
# np.savetxt('D:/ws3.csv', costsum, fmt="%f", delimiter=",")
#画图1-500次时无人机利润
list = []
for r in range(0, n):
list.append(state[r, ind - 1])
list.sort()
for i in range(0, len(list) - 1):
if (list[i]) == list[i + 1]:
print(list)
print("存在冲突")
break
def getlength(x1, x2, y1, y2,z1,z2):
return math.sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)
def gravi(x1, x2, y1, y2,z1,z2):
length = getlength(x1, x2, y1, y2,z1,z2)
fgra = 30 + length**2
fgrax = fgra * (x2 - x1) / length
fgray = fgra * (y2 - y1) / length
fgraz = fgra * (z2 - z1) / length
return [fgrax, fgray, fgraz]
def repul(x1, x2, y1, y2, z1 , z2):
distance = getlength(x1, x2, y1, y2,z1,z2)
if (distance < 2):
frep = 20 * (2 / distance - 1)**2
else:
frep = 0
frepx = frep * (x1 - x2) / (distance)
frepy = frep * (y1 - y2) / (distance)
frepz = frep * (z1 - z2) / (distance)
return [frepx, frepy, frepz]
def vituralpoint1(x,y,z):
if getlength(x,22,y,45,z,30)<25 and y>(0.5*x+33.5):
fv1x = -40*abs(x-22)
else:
fv1x = 0
fv1y = 0.5*fv1x
fv1z = 0.5*fv1x
return [fv1x,fv1y,fv1z]
position = np.zeros([3, n])
destina = np.zeros([3, n])
for i in range(0, n):
point = int(state[i, ind - 1])
destina[0, i] = finalx[point]
destina[1, i] = finaly[point]
destina[2, i] = finalz[point]
position[0, i] = initx[i]
position[1, i] = inity[i]
position[2, i] = initz[i]
cntstep = 2000
stop = np.zeros(n)
hisplacex = np.zeros([n, cntstep])
hisplacey = np.zeros([n, cntstep])
hisplacez = np.zeros([n, cntstep])
step = 0.5
speedx = np.zeros([n,ind])
speedy = np.zeros([n,ind])
speedz = np.zeros([n,ind])
#引入斥力场
#返回横线与纵向受力椭圆形力场原直线为ax+by=c
#那么距离=abs(ax+by+c)/math.sqrt(a**2+b**2)
#修改x1,x2位置改变初始
def cirfield(x, y, z, x0, y0, z0, r):
length1 = getlength(x,x0,y,y0,z,z0)
if length1 >= 1.2*r:
fr = 0
else:
fr = 3000*(1.2*r/length1 -1)
frx = fr * (x - x0)/length1
fry = fr * (y - y0)/length1
frz = fr * (z - z0)/length1
return [frx,fry,frz]
def linefield(x0,y0,z0,x1,y1,z1,x,y,z):
flx = fly = flz = 0
pointnum = 80
xmid = np.zeros(pointnum)
ymid = np.zeros(pointnum)
zmid = np.zeros(pointnum)
for i in range(0,pointnum-1):
xmid[i] = (x1-x0)/pointnum*i+x0
ymid[i] = (y1-y0)/pointnum*i+y0
zmid[i] = (z1-z0)/pointnum*i+z0
for j in range(0,pointnum-1):
flx = flx+ ballfield(x,y,z,xmid[j],ymid[j],zmid[j],2)[0]
fly = fly+ ballfield(x,y,z,xmid[j],ymid[j],zmid[j],2)[1]
flz = flz+ ballfield(x,y,z,xmid[j],ymid[j],zmid[j],2)[2]
return [flx,fly,flz]
def virpoi(x,y,z,x0,y0,z0):
destan1 = getlength(x,x0,y,y0,z,z0)
fx = (x0-x)/destan1
fy = (y0-y)/destan1
fz = (z0-z)/destan1
return [fx,fy,fz]
def ballfield(x,y,z,x0,y0,z0,r1):
destan2 = getlength(x,x0,y,y0,z,z0)
if destan2 >1.5*r1:
f = 0
else:
f = -8000*(1.5*r1/destan2-1)
fx = f*(x0-x)/destan2
fy = f*(y0-y)/destan2
fz = f*(z0-z)/destan2
return [fx,fy,fz]
def surfield1(x,y,z):
#法向量为a,b,c
if(x + y < (60+2.5*math.sqrt(2))and y<(20) and z<60):
ff1 = 40*(5/(x+y-60)-1)
else:
ff1 = 0
fx = ff1/math.sqrt(2)
fy = fx
return [fx,fy]
def surfield2(x,y,z):
if((0.5*x+y)<(40+2.5*math.sqrt(5)) and z<60 and x<40):
f2 = 50*(5/(0.5*x+y-40)-1)
else:
f2 = 0
fx = f2/math.sqrt(5)
fy = f2*2/math.sqrt(5)
return[fx,fy]
def yuanzhu(x,y,z):
jl1 = math.sqrt((x-50)**2+(y-60)**2)
if(z<80 and jl1<15):
f = 1000*(15/jl1-1)
else:
f = 0
fx = f*(x-50)/jl1
fy = f*(y-60)/jl1
return[fx,fy]
def getangel(v1, v2):
# 分别计算两个向量的模:
module_x = math.sqrt(v1[1]**2 + v1[0]**2 + v1[2]**2)
module_y = math.sqrt(v2[1]**2 + v2[0]**2 + v2[2]**2)
# 计算两个向量的点积
dot_value = v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]
# 计算夹角的cos值
cos_theta = dot_value / (module_x * module_y)
return cos_theta
def renewposi(force):
# if (force != 0):
deltax = position[0, i] - destina[0, i]
deltay = position[1, i] - destina[1, i]
deltaz = position[2, i] - destina[2, i]
line1 = [deltax, deltay, deltaz]
line2 = [forcex, forcey, forcez]
cosangle = getangel(line1, line2)
step = 0.3 * 2**(0.5*cosangle)
# if cosangle > 0.8:
# position[0, i] = position[0, i] - step * forcey / force
# position[1, i] = position[1, i] + step * forcex / force
# else:
position[0, i] = position[0, i] + step * forcex / force
position[1, i] = position[1, i] + step * forcey / force
position[2, i] = position[2, i] + step * forcez / force
speedx[i,jishu] = step * forcex / force
speedy[i,jishu] = step * forcey / force
speedz[i,jishu] = step * forcez / force
# else:
# position[0, i] = position[0, i] + random.uniform(-0.05, 0.05)
# position[1, i] = position[1, i] + random.uniform(-0.05, 0.05)
#添加一个斥力源:中心在某处的圆形
#另一种斥力源的思路:横线障碍,方向为:两个半圆斥力场与两个方向上直线型斥力场
#思考如何处理中途的改进每20步重新分配一次
#在分配时如何处理已经到达的无人机?
#在博弈时发现对方已经到达目标位置就让该无人机变换利润提高他机固定本位置为0或者修改记忆
jishu = 0
while (1):
for i in range(0, n):
forcelist = []
for m in range(0, n):
if (stop[m] == 0 and m != i):
forcelist.append(m)
frepx1 =(0 + ballfield(position[0,i],position[1,i],position[2,i],55,80,65,7)[0]
# +linefield(25,45,35,50,position[0, i],position[1, i])[0]
# #+linefield(70,35,80,55,position[0, i],position[1, i])[0]
# +vituralpoint1(position[0, i],position[1, i])[0]
# +cirfield(position[0, i],position[1, i],65,40,5)[0]
)
frepy1 =(0 + ballfield(position[0,i],position[1,i],position[2,i],55,80,65,7)[1]
# +linefield(25,45,35,50,position[0, i],position[1, i])[1]
# #+linefield(70,35,80,55,position[0, i],position[1, i])[1]
# +vituralpoint1(position[0, i],position[1, i])[1]
# +cirfield(position[0, i],position[1, i],65,40,5)[1]
)
frepz1 =(0+ballfield(position[0,i],position[1,i],position[2,i],55,80,65,7)[2]
)
for count in range(0, len(forcelist)):
listrep = repul(
position[0, i], position[0, forcelist[count]], position[1, i],
position[1, forcelist[count]], position[2, i], position[2, forcelist[count]])
frepx1 = frepx1 + listrep[0]
frepy1 = frepy1 + listrep[1]
frepz1 = frepz1 + listrep[2]
if stop[i] == 0:
listgra = gravi(position[0, i], destina[0, i],position[1, i], destina[1, i],position[2, i], destina[2, i])
forcex = frepx1 + listgra[0]
forcey = frepy1 + listgra[1]
forcez = frepz1 + listgra[2]
force = math.sqrt(forcex**2 + forcey**2 + forcez**2)
renewposi(force)
#一轮位置变化,一次0.5m,接下来判断是否应该停止
hisplacex[i, jishu] = position[0, i]
hisplacey[i, jishu] = position[1, i]
hisplacez[i, jishu] = position[2, i]
if getlength(position[0, i], destina[0, i], position[1, i],
destina[1, i], position[2, i],destina[2, i]) <= 0.2:
stop[i] = 1
#到达目标点后将斥力变为0
if jishu %100 == 0 :
con_re = []
dis_re = np.zeros([n, n])
julire = np.zeros([n, n])
tasksre = []
for d in range(0, n):
for f in range(0, n):
dis_re[d, f] = math.sqrt((position[0, d] - destina[0, f])**2 +
(position[1, d] - destina[1, f])**2 +
(position[2, d] - destina[2, f])**2)
julire[d, f] = math.sqrt((position[0, d] - position[0, f])**2 +
(position[1, d] - position[1, f])**2 +
(position[2, d] - position[2, f])**2)
tasksre = gettasks(dis_re)
for x in range(0, n):
tmpcon = []
for c in range(0, n):
if (julire[x][c] <= 80 and x != c):
tmpcon.append(c)
con_re.append(tmpcon)
statere = np.zeros(n)
for t2 in range(0, n):
statere[t2] = state[t2, ind - 1]
relist = []
recost = []
findsame = []
t1 = ind - 1
for r in range(0, n):
count = 0
for vb in range(0, len(con_re[r])):
if state[r, t1] == state[con_re[r][vb], t1] and r != vb:
count = count + 1
tmsame = []
tmsame.append(r)
tmsame.append(con_re[r][vb])
findsame.append(tmsame)
if (count != 0 ):
relist.append(r)
renum = len(relist)
print(findsame) #位置变化后,寻找到重复的无人机,对其重新分配
for t6 in range(0,int(len(findsame)/2)):
choicelist1 = []
tmpcost = []
for t7 in range(1,len(findsame[t6])):
rebianhao = findsame[t6][t7]
relist1 = []
for t8 in range(0,len(con_re[rebianhao])):
if statere[con_re[rebianhao][t8]] not in relist1:
relist1.append(statere[con_re[rebianhao][t8]])
for t9 in range(len(tasksre[rebianhao])):
if tasksre[rebianhao][t9] not in relist1:
choicelist1.append(tasksre[rebianhao][t9])
for t10 in range(0,len(choicelist1)):
tmpcost.append(dis_re[rebianhao,choicelist1[t10]])
statere[rebianhao] = choicelist1[findmin(tmpcost)]
liata = np.sort(statere)
print(liata)
for t11 in range(0,n):
state[t11,t1] = statere[t11]
for b in range(0, int(len(findsame)/2)):
for b1 in range(0,len(findsame[b])):
point = int(statere[int(findsame[b][b1])])
stop[point] = 0
destina[0, findsame[b][b1]] = finalx[point]
destina[1, findsame[b][b1]] = finaly[point]
destina[2, findsame[b][b1]] = finalz[point]
tostop = 1
for cnt in range(0, n):
tostop = tostop * stop[cnt]
if tostop == 1 or jishu == cntstep-1:
print(jishu)
break
else:
jishu = jishu + 1
#或许需要在第30步时再一次分配
np.savetxt('D:/wsf2x.csv', hisplacex, fmt="%f", delimiter=",")
np.savetxt('D:/wsf2y.csv', hisplacey, fmt="%f", delimiter=",")
np.savetxt('D:/wsf2z.csv', hisplacez, fmt="%f", delimiter=",")
np.savetxt('D:/speed1x.csv', speedx, fmt="%f", delimiter=",")
np.savetxt('D:/speed1y.csv', speedy, fmt="%f", delimiter=",")
np.savetxt('D:/speed1z.csv', speedz, fmt="%f", delimiter=",")
placex = []
placey = []
placez = []
for i in range(0, n):
for j in range(0, cntstep):
if (hisplacex[i, j]) != 0:
placex.append(hisplacex[i, j])
placey.append(hisplacey[i, j])
placez.append(hisplacez[i, j])
fig = plt.figure(1)
ax = plt.axes(projection='3d')
# new_tick = np.linspace(0, 115, 24)
# plt.xticks(new_tick)
# plt.yticks(new_tick)
# plt.title("无人机轨迹散点图")
# plt.xlabel('x方向 单位m')
# plt.ylabel("y方向 单位m")
# plt.plot([25,35],[45,50])
# # plt.plot([70,80],[35,55])
# plt.scatter(initx, inity, c='blue', s=10)
# plt.scatter(finalx, finaly, c='black', s=10) #蓝色点为起点,黑色点为终点
# plt.scatter(placex, placey, c='red', s=1) #画出散点图,但是不表示顺序
# theta = np.arange(0, 2 * np.pi, 0.01)
# x = 65 + 5 * np.cos(theta)
# y = 40 + 5 * np.sin(theta)
# plt.plot(x, y)
# #调用 ax.plot3D创建三维线图
# x = 50+7.5*np.cos(theta)
# y = 60+7.5*np.sin(theta)
# z = np.linspace(0, 80, 1000)
# theta = np.linspace(0,2*np.pi,30)
# z,theta = np.meshgrid(z,theta)
theta1 = np.linspace(0,2*np.pi,30)
fai = np.linspace(0,2*np.pi,30)
theta1,fai = np.meshgrid(theta1,fai)
xr = 55+6*np.cos(theta1)*np.sin(fai)
yr = 80+6*np.sin(theta1)*np.sin(fai)
zr = 65+6*np.cos(fai)
ax.plot_surface(xr, yr, zr,cmap='viridis', edgecolor='none')
# ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none')
# x1 = np.linspace(0,40,100)
# z1 = np.linspace(0,60,100)
# x1,z1 = np.meshgrid(x1,z1)
# y1 = -0.5*x1+40
# ax.plot_surface(x1, y1, z1,cmap='viridis', edgecolor='none')
# y2 = np.linspace(0,20,80)
# y2,z1 = np.meshgrid(y2,z1)
# x2 = 60-y2
# ax.plot_surface(x2, y2, z1,cmap='viridis', edgecolor='none')
# z3 = 60
# x3 = np.linspace(0,40,100)
# x3, z3 = np.meshgrid(x3,z3)
# y3 = 40-0.5*x3
# ax.plot_surface(x3, y3, z3,cmap='viridis', edgecolor='none')
# ax.set_title('3D line plot')
ax.plot3D(0,0,0)
ax.plot3D(100,100,0)
ax.scatter3D(placex,placey,placez,c='blue',s = 0.1)
ax.scatter3D(initx,inity,initz,c='red',s = 0.5)
ax.scatter3D(finalx,finaly,finalz,c='red',s = 0.5)
# xcnt = []
# for i in range(0,500):
# xcnt.append(i)
# plt.scatter(hisplacex)
plt.show()