实验三种算法的任务分配

This commit is contained in:
Robin Shaun 2020-07-28 15:54:43 +08:00
parent f29623b0b4
commit ed00504247
12 changed files with 645 additions and 549 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -1,243 +1,136 @@
import random
import numpy as np
import math
import time
import os
class Aco():
class ACO():
def __init__(self, vehicle_num, target_num,vehicle_speed, target, time_lim):
self.num_type_ant = vehicle_num
self.num_city = target_num+1 #number of cities
self.group = 200
self.num_ant = self.group*self.num_type_ant #number of ants
self.ant_vel = vehicle_speed
self.cut_time = time_lim
self.oneee = np.zeros((4,1))
self.target = target
self.alpha = 1 #pheromone
self.beta = 1 #qiwangyinzi
self.beta = 2 #qiwangyinzi
self.k1 = 0.03
self.iter_max = 300
#matrix of the distances between cities
self.iter_max = 150
#matrix of the distances between cities
def distance_matrix(self):
dis_mat = []
for i in range(self.num_city):
dis_mat_each = []
for j in range(self.num_city):
dis = math.sqrt(pow(self.target[i][0]-self.target[j][0],2)+pow(self.target[i][1]-self.target[j][1],2))
dis_mat_each.append(dis)
dis_mat.append(dis_mat_each)
return dis_mat
def get_assignment_aco(self):
def run(self):
print("ACO start, pid: %s" % os.getpid())
start_time = time.time()
#distances of nodes
dis_list = self.distance_matrix()
dis_mat = np.array(dis_list)
value_init = self.target[:,2].transpose()
delay_init = self.target[:,3].transpose()
pheromone_mat = np.ones((self.num_type_ant,self.num_city))
#velocity of ants
path_new = [[0]for i in range (self.num_type_ant)]
count_iter = 0
while count_iter < self.iter_max:
path_sum = np.zeros((self.num_ant,1))
time_sum = np.zeros((self.num_ant,1))
value_sum = np.zeros((self.num_ant,1))
path_mat=[[0]for i in range (self.num_ant)]
value = np.zeros((self.group,1))
atten = np.ones((self.num_type_ant,1)) * 0.2
for ant in range(self.num_ant):
ant_type = ant % self.num_type_ant
visit = 0
if ant_type == 0:
unvisit_list=list(range(1,self.num_city))#have not visit
for j in range(1,self.num_city):
#choice of next city
trans_list=[]
tran_sum=0
trans=0
#if len(unvisit_list)==0:
#print('len(unvisit_list)==0')
for k in range(len(unvisit_list)): # to decide which node to visit
#trans +=np.power(pheromone_mat[ant_type][visit][unvisit_list[k]],alpha)*np.power(k1*value_mat[visit][unvisit_list[k]],beta)
trans +=np.power(pheromone_mat[ant_type][unvisit_list[k]],self.alpha)*np.power(0.05*value_init[unvisit_list[k]],self.beta)
trans_list.append(trans)
tran_sum = trans
tran_sum = trans
rand = random.uniform(0,tran_sum)
for t in range(len(trans_list)):
if(rand <= trans_list[t]):
visit_next = unvisit_list[t]
break
else:
else:
continue
path_mat[ant].append(visit_next)
path_sum[ant] += dis_mat[path_mat[ant][j-1]][path_mat[ant][j]]
time_sum[ant] += path_sum[ant] / self.ant_vel[ant_type] + delay_init[visit_next]
if time_sum[ant] > self.cut_time:
time_sum[ant]-=path_sum[ant] / self.ant_vel[ant_type] + delay_init[visit_next]
path_mat[ant].pop()
time_sum[ant]-=path_sum[ant] / self.ant_vel[ant_type] + delay_init[visit_next]
path_mat[ant].pop()
break
value_sum[ant] += value_init[visit_next]
unvisit_list.remove(visit_next)#update
visit = visit_next
if (ant_type) == self.num_type_ant-1:
small_group = int(ant/self.num_type_ant)
for k in range (self.num_type_ant):
value[small_group]+= value_sum[ant-k]
#diedai
#iteration
print(max(value))
#print(max(value))
if count_iter == 0:
value_new = max(value)
value = value.tolist()
for k in range (0,self.num_type_ant):
path_new[k] = path_mat[value.index(value_new)*self.num_type_ant+k]
path_new[k].remove(0)
#time[k] = time_sum[value.index(value_new)*self.num_type_ant+k]
else:
if max(value) > value_new:
value_new = max(value)
value = value.tolist()
for k in range (0,self.num_type_ant):
path_new[k] = path_mat[value.index(value_new)*self.num_type_ant+k]
path_new[k].remove(0)
#time[k] = time_sum[value.index(value_new)*self.num_type_ant+k]
# update pheromone
pheromone_change=np.zeros((self.num_type_ant,self.num_city))
#update pheromone
pheromone_change = np.zeros((self.num_type_ant,self.num_city))
for i in range(self.num_ant):
length = len(path_mat[i])
m = i%self.num_type_ant
n = int(i/self.num_type_ant)
for j in range(length-1):
if value[n] == value_new:
atten = 0.1
else:
atten = 0.3
#a=value_sum[i]/(np.power((value[n]-value_new),2)+1)
#a=value_sum[i]/(np.power((value[n]-value_new),2)+1)
pheromone_change[m][path_mat[i][j+1]]+= self.k1*value_init[path_mat[i][j+1]]
for m in range (self.num_type_ant):
atten[m] += (value_sum[i]/(np.power((value_new-value[n]),4)+1))/self.group
#print(atten[m])
for k in range (self.num_type_ant):
#print('pheromone_change[m]:',pheromone_change[m])
pheromone_mat[m]=(1-atten)*pheromone_mat[m]+pheromone_change[m]
pheromone_mat[k]=(1-atten[k])*pheromone_mat[k]+pheromone_change[k]
count_iter += 1
print('count_iter:',count_iter)
#print('count_iter:',count_iter)
print('the largest value',value_new)
print('the best road',path_new)
#print('time_limit:',self.cut_time)
#print('time',time)
return path_new
#print('the largest value?',value_new)
#print('the best road?',path_new)
print("ACO result:", path_new)
#self.task_assignment = task_assignment
end_time = time.time()
#self.cal_time = end_time - start_time
print("ACO time:", end_time - start_time)
return path_new, end_time - start_time

View File

@ -3,6 +3,11 @@ import matplotlib.pyplot as plt
import random
import time
import pandas as pd
import copy
from multiprocessing import Pool
from ga import GA
from aco import ACO
from pso import PSO
class Env():
def __init__(self, vehicle_num, target_num, map_size, visualized=True, time_cost=None, repeat_cost=None):
@ -12,7 +17,7 @@ class Env():
self.map_size = map_size
self.speed_range = [10, 15, 30]
#self.time_lim = 1e6
self.time_lim = self.map_size / self.speed_range[1] * 2
self.time_lim = self.map_size / self.speed_range[1]
self.vehicles_lefttime = np.ones(vehicle_num,dtype=np.float32) * self.time_lim
self.distant_mat = np.zeros((target_num+1,target_num+1),dtype=np.float32)
self.total_reward = 0
@ -21,7 +26,7 @@ class Env():
self.time = 0
self.time_cost = time_cost
self.repeat_cost = repeat_cost
self.done = False
self.end = False
self.assignment = [[] for i in range(vehicle_num)]
self.task_generator()
@ -37,29 +42,30 @@ class Env():
for i in range(self.targets.shape[0]):
for j in range(self.targets.shape[0]):
self.distant_mat[i,j] = np.linalg.norm(self.targets[i,:2]-self.targets[j,:2])
self.targets_value = copy.deepcopy((self.targets[:,2]))
def step(self, action):
count = 0
for j in range(len(self.action)):
k = self.action[j]
for j in range(len(action)):
k = action[j]
delta_time = self.distant_mat[self.vehicles_position[j],k] / self.vehicles_speed[j] + self.targets[k,3]
self.vehicles_lefttime[j] = self.vehicles_lefttime[j] - delta_time
if self.vehicles_lefttime < 0:
if self.vehicles_lefttime[j] < 0:
count = count + 1
continue
else:
if k == 0:
self.reward = - self.repeat_cost
else:
self.reward = self.targets[k,2] - delta_time * self.time_cost
self.reward = self.targets[k,2] - delta_time * self.time_cost + self.targets[k,2]
if self.targets[k,2] == 0:
self.total_reward = self.total_reward - self.repeat_cost
self.reward = self.reward - self.repeat_cost
self.vehicles_position[j] = k
self.targets[k,2] = 0
self.total_reward = self.total_reward + self.rewards
self.total_reward = self.total_reward + self.reward
self.assignment[j].append(action)
if count == len(self.action):
self.done = True
if count == len(action):
self.end = True
def run(self, assignment, algorithm):
self.assignment = assignment
@ -67,20 +73,30 @@ class Env():
self.get_total_reward()
if self.visualized:
self.visualize()
def reset(self):
self.vehicles_position = np.zeros(self.vehicles_position.shape[0],dtype=np.int32)
self.vehicles_lefttime = np.ones(self.vehicles_position.shape[0],dtype=np.float32) * self.time_lim
self.targets[:,2] = self.targets_value
self.total_reward = 0
self.reward = 0
self.end = False
def get_total_reward(self):
for i in range(len(self.assignment)):
speed = self.vehicles_speed[i]
for j in range(len(self.assignment[i])):
k = self.assignment[i][j]
self.total_reward = self.total_reward + self.targets[k,2]
self.vehicles_lefttime[i] = self.vehicles_lefttime[i] - self.distant_mat[self.vehicles_position[i],k] / speed - self.targets[k,3]
if self.vehicles_lefttime[i] < 0:
self.done = True
position = self.targets[self.assignment[i][j],:4]
self.total_reward = self.total_reward + position[2]
if j == 0:
self.vehicles_lefttime[i] = self.vehicles_lefttime[i] - np.linalg.norm(position[:2]) / speed - position[3]
else:
self.vehicles_lefttime[i] = self.vehicles_lefttime[i] - np.linalg.norm(position[:2]-position_last[:2]) / speed - position[3]
position_last = position
if self.vehicles_lefttime[i] > self.time_lim:
self.end = True
break
self.vehicles_position[i] = k
if self.done:
if self.end:
self.total_reward = 0
break
@ -104,6 +120,76 @@ class Env():
plt.show()
if __name__=='__main__':
# Test 1
p = Pool(2)
vehicle_num = 5
target_num = 30
map_size = 5e3
env = Env(vehicle_num,target_num,map_size,visualized=True)
ga = GA(vehicle_num,env.vehicles_speed,target_num,env.targets,env.time_lim)
aco = ACO(vehicle_num,target_num,env.vehicles_speed,env.targets,env.time_lim)
pso = PSO(vehicle_num,target_num ,env.targets,env.vehicles_speed,env.time_lim)
ga_result = p.apply_async(ga.run)
#aco_result = p.apply_async(aco.run)
pso_result = p.apply_async(pso.run)
p.close()
p.join()
ga_task_assignmet = ga_result.get()[0]
env.run(ga_task_assignmet,'GA')
#env.reset()
#aco_task_assignmet = aco_result.get()[0]
#env.run(aco_task_assignmet,'ACO')
env.reset()
pso_task_assignmet = pso_result.get()[0]
env.run(pso_task_assignmet,'PSO')
# Test 2
p = Pool(2)
vehicle_num = 10
target_num = 60
map_size = 1e4
env = Env(vehicle_num,target_num,map_size,visualized=True)
ga = GA(vehicle_num,env.vehicles_speed,target_num,env.targets,env.time_lim)
#aco = ACO(vehicle_num,target_num,env.vehicles_speed,env.targets,env.time_lim)
pso = PSO(vehicle_num,target_num ,env.targets,env.vehicles_speed,env.time_lim)
ga_result = p.apply_async(ga.run)
#aco_result = p.apply_async(aco.run)
pso_result = p.apply_async(pso.run)
p.close()
p.join()
ga_task_assignmet = ga_result.get()[0]
env.run(ga_task_assignmet,'GA')
#env.reset()
#aco_task_assignmet = ga_result.get()[0]
#env.run(aco_task_assignmet,'ACO')
env.reset()
pso_task_assignmet = pso_result.get()[0]
env.run(pso_task_assignmet,'PSO')
# Test 3
p = Pool(2)
vehicle_num = 15
target_num = 90
map_size = 1.5e4
env = Env(vehicle_num,target_num,map_size,visualized=True)
ga = GA(vehicle_num,env.vehicles_speed,target_num,env.targets,env.time_lim)
#aco = ACO(vehicle_num,target_num,env.vehicles_speed,env.targets,env.time_lim)
pso = PSO(vehicle_num,target_num ,env.targets,env.vehicles_speed,env.time_lim)
ga_result = p.apply_async(ga.run)
#aco_result = p.apply_async(aco.run)
pso_result = p.apply_async(pso.run)
p.close()
p.join()
ga_task_assignmet = ga_result.get()[0]
env.run(ga_task_assignmet,'GA')
#env.reset()
#aco_task_assignmet = ga_result.get()[0]
#env.run(aco_task_assignmet,'ACO')
env.reset()
pso_task_assignmet = pso_result.get()[0]
env.run(pso_task_assignmet,'PSO')
'''
time_record = []
reward_record = []
for i in range(100):
@ -119,4 +205,5 @@ if __name__=='__main__':
env.run(task_assignment,algorithm)
reward_record.append(env.total_reward)
dataframe = pd.DataFrame({'time':time_record,'reward':reward_record})
dataframe.to_csv(algorithm+'.csv',sep=',')
dataframe.to_csv(algorithm+'.csv',sep=',')
'''

View File

@ -1,161 +1,179 @@
import numpy as np
import random
import time
import os
class ga():
def __init__(self,vehicle_num,vehicles_speed,target_num,targets,time_lim):
#vehicles_speed,targets in the type of narray
self.vehicle_num=vehicle_num
self.vehicles_speed=vehicles_speed
self.target_num=target_num
self.targets=targets
self.time_lim=time_lim
self.map=np.zeros(shape=(target_num+1,target_num+1),dtype=float)
self.pop_size=100
self.p_cross=0.6
self.p_mutate=0.005
for i in range(target_num+1):
self.map[i,i]=0
for j in range(i):
self.map[j,i]=self.map[i,j]=np.linalg.norm(targets[i,:2]-targets[j,:2])
self.pop=np.zeros(shape=(self.pop_size,vehicle_num-1+target_num-1),dtype=np.int32)
self.ff=np.zeros(self.pop_size,dtype=float)
for i in range(self.pop_size):
for j in range(vehicle_num-1):
self.pop[i,j]=random.randint(0,target_num)
for j in range(target_num-1):
self.pop[i,vehicle_num+j-1]=random.randint(0,target_num-j-1)
self.ff[i]=self.fitness(self.pop[i,:])
self.tmp_pop=np.array([])
self.tmp_ff=np.array([])
self.tmp_size=0
def fitness(self,gene):
ins=np.zeros(self.target_num+1,dtype=np.int32)
seq=np.zeros(self.target_num,dtype=np.int32)
ins[self.target_num]=1
for i in range(self.vehicle_num-1):
ins[gene[i]]+=1
rest=np.array(range(1,self.target_num+1))
for i in range(self.target_num-1):
seq[i]=rest[gene[i+self.vehicle_num-1]]
rest=np.delete(rest,gene[i+self.vehicle_num-1])
seq[self.target_num-1]=rest[0]
i=0 #index of vehicle
pre=0 #index of last target
post=0 #index of ins/seq
t=0
reward=0
while i<self.vehicle_num:
if ins[post]>0:
i+=1
ins[post]-=1
pre=0
t=0
else:
t+=self.targets[pre,3]
past=self.map[pre,seq[post]]/self.vehicles_speed[i]
t+=past
if t<self.time_lim:
reward+=self.targets[seq[post],2]
pre=seq[post]
post+=1
return reward
def selection(self):
roll=np.zeros(self.tmp_size,dtype=float)
roll[0]=self.tmp_ff[0]
for i in range(1,self.tmp_size):
roll[i]=roll[i-1]+self.tmp_ff[i]
for i in range(self.pop_size):
xx=random.uniform(0,roll[self.tmp_size-1])
j=0
while xx>roll[j]:
j+=1
self.pop[i,:]=self.tmp_pop[j,:]
self.ff[i]=self.tmp_ff[j]
def mutation(self):
for i in range(self.tmp_size):
flag=False
for j in range(self.vehicle_num-1):
if random.random()<self.p_mutate:
self.tmp_pop[i,j]=random.randint(0,self.target_num)
flag=True
for j in range(self.target_num-1):
if random.random()<self.p_mutate:
self.tmp_pop[i,self.vehicle_num+j-1]=random.randint(0,self.target_num-j-1)
flag=True
if flag:
self.tmp_ff[i]=self.fitness(self.tmp_pop[i,:])
def crossover(self):
new_pop=[]
new_ff=[]
new_size=0
for i in range(0,self.pop_size,2):
if random.random()<self.p_cross:
x1=random.randint(0,self.vehicle_num-2)
x2=random.randint(0,self.target_num-2)+self.vehicle_num
g1=self.pop[i,:]
g2=self.pop[i+1,:]
g1[x1:x2]=self.pop[i+1,x1:x2]
g2[x1:x2]=self.pop[i,x1:x2]
new_pop.append(g1)
new_pop.append(g2)
new_ff.append(self.fitness(g1))
new_ff.append(self.fitness(g2))
new_size+=2
self.tmp_size=self.pop_size+new_size
self.tmp_pop=np.zeros(shape=(self.tmp_size,self.vehicle_num-1+self.target_num-1),dtype=np.int32)
self.tmp_pop[0:self.pop_size,:]=self.pop
self.tmp_pop[self.pop_size:self.tmp_size,:]=np.array(new_pop)
self.tmp_ff=np.zeros(self.tmp_size,dtype=float)
self.tmp_ff[0:self.pop_size]=self.ff
self.tmp_ff[self.pop_size:self.tmp_size]=np.array(new_ff)
def run(self):
cut=0
e=self.tmp_ff>cut
while e.sum()<=self.tmp_size*0.5:
self.crossover()
self.mutation()
self.selection()
cut=self.tmp_ff.max()*0.9
e=self.tmp_ff>cut
i=0
for j in range(self.tmp_size):
if self.tmp_ff[i]<self.tmp_ff[j]:
i=j
gene=self.tmp_pop[i]
ins=np.zeros(self.target_num+1,dtype=np.int32)
seq=np.zeros(self.target_num,dtype=np.int32)
ins[self.target_num]=1
for i in range(self.vehicle_num-1):
ins[gene[i]]+=1
rest=np.array(range(1,self.target_num+1))
for i in range(self.target_num-1):
seq[i]=rest[gene[i+self.vehicle_num-1]]
rest=np.delete(rest,gene[i+self.vehicle_num-1])
seq[self.target_num-1]=rest[0]
task_assignment=[[] for i in range(self.vehicle_num)]
i=0 #index of vehicle
pre=0 #index of last target
post=0 #index of ins/seq
t=0
while i<self.vehicle_num:
if ins[post]>0:
i+=1
ins[post]-=1
pre=0
t=0
else:
t+=self.targets[pre,3]
past=self.map[pre,seq[post]]/self.vehicles_speed[i]
t+=past
if t<self.time_lim:
task_assignment[i].append(seq[post])
pre=seq[post]
post+=1
return task_assignment
class GA():
def __init__(self, vehicle_num, vehicles_speed, target_num, targets, time_lim):
# vehicles_speed,targets in the type of narray
self.vehicle_num = vehicle_num
self.vehicles_speed = vehicles_speed
self.target_num = target_num
self.targets = targets
self.time_lim = time_lim
self.map = np.zeros(shape=(target_num+1, target_num+1), dtype=float)
self.pop_size = 50
self.p_cross = 0.6
self.p_mutate = 0.005
for i in range(target_num+1):
self.map[i, i] = 0
for j in range(i):
self.map[j, i] = self.map[i, j] = np.linalg.norm(
targets[i, :2]-targets[j, :2])
self.pop = np.zeros(
shape=(self.pop_size, vehicle_num-1+target_num-1), dtype=np.int32)
self.ff = np.zeros(self.pop_size, dtype=float)
for i in range(self.pop_size):
for j in range(vehicle_num-1):
self.pop[i, j] = random.randint(0, target_num)
for j in range(target_num-1):
self.pop[i, vehicle_num+j -
1] = random.randint(0, target_num-j-1)
self.ff[i] = self.fitness(self.pop[i, :])
self.tmp_pop = np.array([])
self.tmp_ff = np.array([])
self.tmp_size = 0
def fitness(self, gene):
ins = np.zeros(self.target_num+1, dtype=np.int32)
seq = np.zeros(self.target_num, dtype=np.int32)
ins[self.target_num] = 1
for i in range(self.vehicle_num-1):
ins[gene[i]] += 1
rest = np.array(range(1, self.target_num+1))
for i in range(self.target_num-1):
seq[i] = rest[gene[i+self.vehicle_num-1]]
rest = np.delete(rest, gene[i+self.vehicle_num-1])
seq[self.target_num-1] = rest[0]
i = 0 # index of vehicle
pre = 0 # index of last target
post = 0 # index of ins/seq
t = 0
reward = 0
while i < self.vehicle_num:
if ins[post] > 0:
i += 1
ins[post] -= 1
pre = 0
t = 0
else:
t += self.targets[pre, 3]
past = self.map[pre, seq[post]]/self.vehicles_speed[i]
t += past
if t < self.time_lim:
reward += self.targets[seq[post], 2]
pre = seq[post]
post += 1
return reward
def selection(self):
roll = np.zeros(self.tmp_size, dtype=float)
roll[0] = self.tmp_ff[0]
for i in range(1, self.tmp_size):
roll[i] = roll[i-1]+self.tmp_ff[i]
for i in range(self.pop_size):
xx = random.uniform(0, roll[self.tmp_size-1])
j = 0
while xx > roll[j]:
j += 1
self.pop[i, :] = self.tmp_pop[j, :]
self.ff[i] = self.tmp_ff[j]
def mutation(self):
for i in range(self.tmp_size):
flag = False
for j in range(self.vehicle_num-1):
if random.random() < self.p_mutate:
self.tmp_pop[i, j] = random.randint(0, self.target_num)
flag = True
for j in range(self.target_num-1):
if random.random() < self.p_mutate:
self.tmp_pop[i, self.vehicle_num+j -
1] = random.randint(0, self.target_num-j-1)
flag = True
if flag:
self.tmp_ff[i] = self.fitness(self.tmp_pop[i, :])
def crossover(self):
new_pop = []
new_ff = []
new_size = 0
for i in range(0, self.pop_size, 2):
if random.random() < self.p_cross:
x1 = random.randint(0, self.vehicle_num-2)
x2 = random.randint(0, self.target_num-2)+self.vehicle_num
g1 = self.pop[i, :]
g2 = self.pop[i+1, :]
g1[x1:x2] = self.pop[i+1, x1:x2]
g2[x1:x2] = self.pop[i, x1:x2]
new_pop.append(g1)
new_pop.append(g2)
new_ff.append(self.fitness(g1))
new_ff.append(self.fitness(g2))
new_size += 2
self.tmp_size = self.pop_size+new_size
self.tmp_pop = np.zeros(
shape=(self.tmp_size, self.vehicle_num-1+self.target_num-1), dtype=np.int32)
self.tmp_pop[0:self.pop_size, :] = self.pop
self.tmp_pop[self.pop_size:self.tmp_size, :] = np.array(new_pop)
self.tmp_ff = np.zeros(self.tmp_size, dtype=float)
self.tmp_ff[0:self.pop_size] = self.ff
self.tmp_ff[self.pop_size:self.tmp_size] = np.array(new_ff)
def run(self):
print("GA start, pid: %s" % os.getpid())
start_time = time.time()
cut = 0
count = 0
while count < 500:
self.crossover()
self.mutation()
self.selection()
new_cut = self.tmp_ff.max()
if cut < new_cut:
cut = new_cut
count = 0
gene = self.tmp_pop[np.argmax(self.tmp_ff)]
else:
count += 1
#print(cut)
ins = np.zeros(self.target_num+1, dtype=np.int32)
seq = np.zeros(self.target_num, dtype=np.int32)
ins[self.target_num] = 1
for i in range(self.vehicle_num-1):
ins[gene[i]] += 1
rest = np.array(range(1, self.target_num+1))
for i in range(self.target_num-1):
seq[i] = rest[gene[i+self.vehicle_num-1]]
rest = np.delete(rest, gene[i+self.vehicle_num-1])
seq[self.target_num-1] = rest[0]
task_assignment = [[] for i in range(self.vehicle_num)]
i = 0 # index of vehicle
pre = 0 # index of last target
post = 0 # index of ins/seq
t = 0
reward = 0
while i < self.vehicle_num:
if ins[post] > 0:
i += 1
ins[post] -= 1
pre = 0
t = 0
else:
t += self.targets[pre, 3]
past = self.map[pre, seq[post]]/self.vehicles_speed[i]
t += past
if t < self.time_lim:
task_assignment[i].append(seq[post])
reward += self.targets[seq[post], 2]
pre = seq[post]
post += 1
#print(reward)
print("GA result:", task_assignment)
#self.task_assignment = task_assignment
end_time = time.time()
#self.cal_time = end_time - start_time
print("GA time:", end_time - start_time)
return task_assignment, end_time - start_time

View File

@ -1,289 +1,387 @@
# coding: utf-8
import numpy as np
import random
import matplotlib.pyplot as plt
import math
import cmath
from environment import Env
# ----------------------优化方案----------------------------------
# 发现粒子群算法优化结果不好,收敛没有到全局最优
# 优化思路1. 增加收敛因子k2. 动态改变惯性因子w
import time
import os
# ----------------------Optimization scheme----------------------------------
# Optimization ideas
# 1. Increase the convergence factor k
# 2. Dynamic change of inertia factor W
# 3. Using PSO local search algorithm(Ring method)
# 4. The probability of position variation is added
# ----------------------Set PSO Parameter---------------------------------
# ----------------------PSO参数设置---------------------------------
class PSO():
def __init__(self, pN, dim, max_iter,uav_num,Distance,
v,Value,test_num,time_all):
def __init__(self, uav_num, target_num, targets, vehicles_speed, time_lim):
self.uav_num = uav_num
self.dim = target_num
self.targets = targets
self.vehicles_speed = vehicles_speed
self.time_all = time_lim
self.pN = 2*(self.uav_num+self.dim) # Number of particles
self.max_iter = 0 # Number of iterations
# Target distance list (dim+1*dim+1)
self.Distance = np.zeros((target_num+1, target_num+1))
self.Value = np.zeros(target_num+1) # Value list of targets 1*dim+1
self.Stay_time = []
# UAV flight speed matrix
self.w = 0.8
self.c1 = 2
self.c2 = 2
self.r1 = 0.6
self.r2 = 0.3
self.pN = pN # 方案数量
self.dim = dim # 方案维度
self.max_iter = max_iter # 迭代次数
self.X = np.zeros((self.pN, self.dim)) # 所有粒子的位置
self.V = np.zeros((self.pN, self.dim)) # 所有粒子的速度
self.pbest = np.zeros((self.pN, self.dim)) # 个体经历的最佳位置
self.gbest = np.zeros((1, self.dim)) # 个体经历的全局最佳位置
self.p_fit = np.zeros(self.pN) # 每个个体的历史最佳适应值
self.fit = 0 # 全局最佳适应值
self.uav_num=uav_num
self.time_all=time_all
self.Distance=Distance # Distance是(dim+1*dim+1)的对称矩阵
self.v=v # 无人机真正飞行速度 m/s
self.Value=Value # 目标位置的价值数组 1*dim
self.TEST=[]
self.test_num=test_num
self.dim1=dim
self.add_num=0
self.time_all=time_all
self.k=0 # 收敛因子
self.wini=0.9
self.wend=0.4
# --------------------取整---------------------------------
def fun_Ceil(self):
num1=self.dim/self.uav_num
num1=math.ceil(num1)
dim1=num1*self.uav_num
num1=dim1-self.dim
self.add_num=num1
self.dim1=dim1
# -------------------排序式转排列式--------------------------
def position(self,X):
Position_All=list(range(1,self.dim+1))
X2=[]
self.k = 0 # Convergence factor
self.wini = 0.9
self.wend = 0.4
self.X = np.zeros((self.pN, self.dim+self.uav_num-1)
) # Position of all particles
self.V = np.zeros((self.pN, self.dim+self.uav_num-1)
) # Velocity of all particles
# The historical optimal position of each individual
self.pbest = np.zeros((self.pN, self.dim+self.uav_num-1))
self.gbest = np.zeros((1, self.dim+self.uav_num-1))
# Global optimal position
self.gbest_ring = np.zeros((self.pN, self.dim+self.uav_num-1))
# Historical optimal fitness of each individual
self.p_fit = np.zeros(self.pN)
self.fit = 0 # Global optimal fitness
self.ring = []
self.ring_fit = np.zeros(self.pN)
# variation parameter
self.p1 = 0.4 # Probability of mutation
self.p2 = 0.5 # Proportion of individuals with variation in population
self.p3 = 0.5 # Proportion of locations where variation occurs
self.TEST = []
self.test_num = 0
self.uav_best = []
self.time_out = np.zeros(self.uav_num)
self.cal_time = 0
# ------------------Get Initial parameter------------------
def fun_get_initial_parameter(self):
# self.max_iter=1000
self.max_iter = 40*(self.uav_num+self.dim)
if self.max_iter > 4100:
self.max_iter = 4100
# self.test_num=10000
# Get Stay_time Arrary & Distance Arrary & Value Arrary
Targets = self.targets
self.Stay_time = Targets[:, 3]
self.Distance = np.zeros((self.dim+1, self.dim+1))
self.Value = np.zeros(self.dim+1)
for i in range(self.dim+1):
self.Value[i] = Targets[i, 2]
for j in range(i):
self.Distance[i][j] = (
Targets[i, 0]-Targets[j, 0])*(Targets[i, 0]-Targets[j, 0])
self.Distance[i][j] = self.Distance[i][j] + \
(Targets[i, 1]-Targets[j, 1])*(Targets[i, 1]-Targets[j, 1])
self.Distance[i][j] = math.sqrt(self.Distance[i][j])
self.Distance[j][i] = self.Distance[i][j]
# ------------------Transfer_Function---------------------
def fun_Transfer(self, X):
# Converting continuous sequence X into discrete sequence X_path
X1 = X[0:self.dim]
X_path = []
l1 = len(X1)
for i in range(l1):
m = X1[i]*(self.dim-i)
m = math.floor(m)
X_path.append(m)
# Converting the continuous interpolation sequence X into discrete interpolation sequence X_rank
X2 = X[self.dim:]
l1 = len(X2)
X_rank = []
for i in range(l1):
m = X2[i]*(self.dim+1)
m1 = math.floor(m)
X_rank.append(m1)
# Rank and Complement
c = sorted(X_rank)
l1 = len(c)
Rank = []
Rank.append(0)
for i in range(l1):
Rank.append(c[i])
Rank.append(self.dim)
# Get Separate_Arrary
Sep = []
for i in range(l1+1):
sep = Rank[i+1]-Rank[i]
Sep.append(sep)
return X_path, Sep
# -------------------Obtain the Real Flight Path Sequence of Particles--------------------------
def position(self, X):
Position_All = list(range(1, self.dim+1))
X2 = []
for i in range(self.dim):
m1=X[i]
m1=int(m1)
X2.append(Position_All[m1-1])
del Position_All[m1-1]
m1 = X[i]
m1 = int(m1)
X2.append(Position_All[m1])
del Position_All[m1]
return X2
# ---------------------Fitness_Computing Function-----------------------------
# ---------------------目标函数-----------------------------
def function(self, X):
# X 是一个方案x[i]
# 由无人机排序式转为排列式
X=self.position(X)
# 把X扩充到可以整除的数组
for i in range(self.add_num):
X.append(i+self.dim+1)
# 由方案导出五个无人机各自搜索路径
UAV=[]
k=0
X_path, Sep = self.fun_Transfer(X)
# Obtain the Real Flight Path Sequence of Particles
X = self.position(X_path)
# Get the search sequence of each UAV
UAV = []
l = 0
for i in range(self.uav_num):
UAV.append([])
for j in range(self.dim1//self.uav_num):
UAV[i].append(X[k])
k=k+1
# 计算某一个方案的目标函数值
l1=len(UAV[0])
value=0
k = Sep[i]
for j in range(k):
UAV[i].append(X[l])
l = l+1
# Calculate Fitness
fitness = 0
for i in range(self.uav_num):
t=self.Distance[0][UAV[i][0]]/self.v
for j in range(l1-1):
if t<=self.time_all:
d1=UAV[i][j]
d2=UAV[i][j+1]
if d2<=self.dim:
distance=self.Distance[d1][d2]
t=t+distance/self.v
value=value+self.Value[UAV[i][j]-1]
return value
k = Sep[i]
t = 0
for j in range(k):
m1 = UAV[i][j]
if j == 0:
t = t+self.Distance[0, m1] / \
self.vehicles_speed[i]+self.Stay_time[m1]
else:
m1 = UAV[i][j]
m2 = UAV[i][j-1]
t = t+self.Distance[m1][m2] / \
self.vehicles_speed[i]+self.Stay_time[m1]
if t <= self.time_all:
fitness = fitness+self.Value[m1]
return fitness
# ----------------------------variation-------------------------------------------
def variation_fun(self):
p1 = np.random.uniform(0, 1) # Probability of mutation
if p1 < self.p1:
for i in range(self.pN):
# Proportion of individuals with variation in population
p2 = np.random.uniform(0, 1)
if p2 < self.p2:
# Numbers of locations where variation occurs
m = int(self.p3*(self.dim+self.uav_num-1))
for j in range(m):
replace_position = math.floor(
np.random.uniform(0, 1)*(self.dim+self.uav_num-1))
replace_value = np.random.uniform(0, 1)
self.X[i][replace_position] = replace_value
# Update pbest & gbest
for i in range(self.pN):
temp = self.function(self.X[i])
self.ring_fit[i] = temp
if temp > self.p_fit[i]:
self.p_fit[i] = temp
self.pbest[i] = self.X[i]
# Update gbest
if self.p_fit[i] > self.fit:
self.gbest = self.X[i]
self.fit = self.p_fit[i]
# ---------------------Population Initialization----------------------------------
# ---------------------初始化种群----------------------------------
def init_Population(self):
# 取整
self.fun_Ceil()
# 初始化位置和历史最优、全局最优
# Initialization of position(X), speed(V), history optimal(pbest) and global optimal(gbest)
for i in range(self.pN):
for j in range(self.dim):
self.X[i][j] = int(random.randint(1,self.dim-j))
#self.V[i][j] = random.uniform(0, 1)
x = np.random.uniform(0, 1, self.dim+self.uav_num-1)
self.X[i, :] = x
v = np.random.uniform(0, 0.4, self.dim+self.uav_num-1)
self.V[i, :] = v
self.pbest[i] = self.X[i]
tmp = self.function(self.X[i])
self.p_fit[i] = tmp
if tmp > self.fit:
self.fit = tmp
self.gbest = self.X[i]
# 初始化速度
# Calculate the convergence factor k
phi = self.c1+self.c2
k = abs(phi*phi-4*phi)
k = cmath.sqrt(k)
k = abs(2-phi-k)
k = 2/k
self.k = k
# Initialize ring_matrix
for i in range(self.pN):
for j in range(self.dim):
self.V[i][j] =random.uniform(-0.3*(self.dim-j),0.3*(self.dim-j))
self.V[i][j]=int(self.V[i][j])
# 计算收敛因子k
phi=self.c1+self.c2
k=abs(phi*phi-4*phi)
k=cmath.sqrt(k)
k=abs(2-phi-k)
k=2/k
self.k=k
# 初始化测试集
self.ring.append([])
self.ring[i].append(i)
# Initialize test_set
self.TEST = np.zeros((self.test_num, self.dim+self.uav_num-1))
for i in range(self.test_num):
self.TEST.append([])
for j in range(self.dim):
self.TEST[i].append(int(random.randint(1,self.dim-j)))
test = np.random.uniform(0, 1, self.dim+self.uav_num-1)
self.TEST[i, :] = test
#self.V[i][j] = random.uniform(0, 1)
# ----------------------更新粒子位置----------------------------------
# ----------------------Update Particle Position----------------------------------
def iterator(self):
fitness = []
fitness_old = 0
k = 0
for t in range(self.max_iter):
# 更新惯性因子w
w=(self.wini-self.wend)*(self.max_iter-t)/self.max_iter+self.wend # w的变化规律是线性递减的
self.w=w # 用计算出的w更新属性
for i in range(self.pN): # 更新gbest\pbest
w = (self.wini-self.wend)*(self.max_iter-t)/self.max_iter+self.wend
self.w = w
# Variation
self.variation_fun()
l1 = len(self.ring[0])
# Local PSO algorithm
# Update ring_arrary
if l1 < self.pN:
if not(t % 2):
k = k+1
for i in range(self.pN):
m1 = i-k
if m1 < 0:
m1 = self.pN+m1
m2 = i+k
if m2 > self.pN-1:
m2 = m2-self.pN
self.ring[i].append(m1)
self.ring[i].append(m2)
# Update gbest_ring
l_ring = len(self.ring[0])
for i in range(self.pN):
fitness1 = 0
for j in range(l_ring):
m1 = self.ring[i][j]
fitness2 = self.ring_fit[m1]
if fitness2 > fitness1:
self.gbest_ring[i] = self.X[m1]
fitness1 = fitness2
# Update velocity
for i in range(self.pN):
self.V[i] = self.k*(self.w * self.V[i] + self.c1 * self.r1 * (self.pbest[i] - self.X[i])) + \
self.c2 * self.r2 * (self.gbest_ring[i] - self.X[i])
# Update position
self.X[i] = self.X[i] + self.V[i]
# Global PSO algorithm
else:
# Update velocity
for i in range(self.pN):
self.V[i] = self.k*(self.w * self.V[i] + self.c1 * self.r1 * (self.pbest[i] - self.X[i])) + \
self.c2 * self.r2 * (self.gbest - self.X[i])
# Update position
self.X[i] = self.X[i] + self.V[i]
# Set position boundary
for i in range(self.pN):
for j in range(self.dim+self.uav_num-1):
if self.X[i][j] >= 1:
self.X[i][j] = 0.999
if self.X[i][j] < 0:
self.X[i][j] = 0
# Update pbest & gbest
for i in range(self.pN):
temp = self.function(self.X[i])
if temp > self.p_fit[i]: # 更新个体最优
self.ring_fit[i] = temp
if temp > self.p_fit[i]:
self.p_fit[i] = temp
self.pbest[i] = self.X[i]
if self.p_fit[i] > self.fit: # 更新全局最优
# Update gbest
if self.p_fit[i] > self.fit:
self.gbest = self.X[i]
self.fit = self.p_fit[i]
for i in range(self.pN):
# 速度更新
self.V[i] = self.k*(self.w * self.V[i] + self.c1 * self.r1 * (self.pbest[i] - self.X[i])) + \
self.c2 * self.r2 * (self.gbest - self.X[i])
# 设置速度边界
for j in range(self.dim):
v_max=int(0.3*(self.dim-j))
v_min=-v_max
self.V[i][j]=int(self.V[i][j])
if self.V[i][j] > v_max:
self.V[i][j] = v_max
if self.V[i][j] < v_min:
self.V[i][j] = v_min
# 位置更新
self.X[i] = self.X[i] + self.V[i]
# 设置位置边界
for j in range(self.dim):
self.X[i][j]=int(self.X[i][j])
if self.X[i][j] > self.dim-j:
self.X[i][j] = self.dim-j
if self.X[i][j] < 1:
self.X[i][j] = 1
self.uav_best = self.fun_Data()
# print
fitness.append(self.fit)
'''
print(self.X[0], end=" ")
print(self.fit) # 输出最优值
'''
self.gbest=self.position(self.gbest)
if self.fit == fitness_old:
continue
else:
fitness_old = self.fit
return fitness
# ---------------------数据处理---------------------------
# ---------------------Data_Processing Function---------------------------
def fun_Data(self):
for i in range(self.add_num):
self.gbest.append(i+self.dim+1)
UAV=[]
k=0
X_path, Sep = self.fun_Transfer(self.gbest)
# Obtain the Real Flight Path Sequence of Particles
X = self.position(X_path)
# Get the search sequence of each UAV
UAV = []
l = 0
for i in range(self.uav_num):
UAV.append([])
for j in range(self.dim1//self.uav_num):
UAV[i].append(self.gbest[k])
k=k+1
l1=len(UAV[0])
best=[]
k = Sep[i]
for j in range(k):
UAV[i].append(X[l])
l = l+1
# Calculate UAV_Out
UAV_Out = []
for i in range(self.uav_num):
t=self.Distance[0][UAV[i][0]]/self.v
best.append([])
for j in range(l1-1):
if t<=self.time_all:
best[i].append(UAV[i][j])
d1=UAV[i][j]
d2=UAV[i][j+1]
if d2<=self.dim:
distance=self.Distance[d1][d2]
t=t+distance/self.v
for i in range(self.uav_num):
l1=len(best[i])
k=0
for j in range(l1):
if best[i][k]>self.dim:
del best[i][k]
k=k-1
k=k+1
return best
# ---------------------测试------------------------------
k = Sep[i]
t = 0
UAV_Out.append([])
for j in range(k):
m1 = UAV[i][j]
if j == 0:
t = t+self.Distance[0, m1] / \
self.vehicles_speed[i]+self.Stay_time[m1]
else:
m2 = UAV[i][j-1]
t = t+self.Distance[m2][m1] / \
self.vehicles_speed[i]+self.Stay_time[m1]
if t <= self.time_all:
UAV_Out[i].append(m1)
self.time_out[i] = t
return UAV_Out
# ---------------------TEST Function------------------------------
def fun_TEST(self):
Test_Value=[]
Test_Value = []
for i in range(self.test_num):
Test_Value.append(self.function(self.TEST[i]))
return Test_Value
# ----------------------程序执行-----------------------
# --------------------定义初始参数---------------------
uav_num = 10
target_num = 45
env = Env(uav_num,target_num,100,1000)
env.targets
env.vehicles_speed
# 定义总搜索时间
time_all=np.random.randint(0.6*10*dim,0.8*10*dim)
Value=[]
for i in range(dim):
Value.append(np.random.randint(0,200))
Distance=np.zeros((dim+1,dim+1))
for i in range(dim+1):
for j in range(i+1,dim+1):
Distance[i][j]=np.random.uniform(200,400)
Distance[j][i]=Distance[i][j]
# -----------------------PSO优化----------------------
my_pso = PSO(pN, dim, max_iter,uav_num,Distance,
v,Value,test_num,time_all)
my_pso.init_Population()
fitness = my_pso.iterator()
best=my_pso.fun_Data()
# --------------------------测试---------------------
# ---------------------Main----------------------------------------
print("fitness is",fitness)
for i in range(uav_num):
print("",i+1,"架无人机的搜索路径为:",best[i])
Test_Value=my_pso.fun_TEST()
l1=len(fitness)
k=0
Test_Value_out=[]
for i in range(test_num):
if Test_Value[i]>fitness[l1-1]:
k=k+1
Test_Value_out.append(Test_Value[i])
print("测试结果超过优化后的目标值的个数是:",k,"")
if k > 0:
print("这些测试结果分别是:",Test_Value_out)
#print("测试的适应值是",Test_Value)
# ------------------测试---------------------
def run(self):
print("PSO start, pid: %s" % os.getpid())
start_time = time.time()
self.fun_get_initial_parameter()
self.init_Population()
fitness = self.iterator()
end_time = time.time()
#self.cal_time = end_time - start_time
#self.task_assignment = self.uav_best
print("PSO result:", self.uav_best)
print("PSO time:", end_time - start_time)
return self.uav_best, end_time - start_time
# -------------------画图--------------------
'''
plt.figure(1)
plt.title("Figure1")
plt.xlabel("iterators", size=14)
plt.ylabel("fitness", size=14)
t = np.array([t for t in range(0, 100)])
fitness = np.array(fitness)
plt.plot(t, fitness, color='b', linewidth=3)
plt.show()
'''
# -------------Result-------------------------
if __name__ == '__main__':
# ----------------------------------TEST--------------------------------
'''
Test_Value=my_pso.fun_TEST()
l1=len(fitness)
k=0
Test_Value_out=[]
for i in range(test_num):
if Test_Value[i]>fitness[l1-1]:
k=k+1
Test_Value_out.append(Test_Value[i])
print("测试结果超过优化后的目标值的个数是:",k,"")
if k > 0:
print("这些测试结果分别是:",Test_Value_out)
#print("测试的适应值是",Test_Value)
env.run(my_pso.uav_best,'pso')
print(env.vehicles_time)
print('time_limit:',env.time_lim)
'''