更新task_assignment
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 84 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 82 KiB |
|
@ -1,136 +0,0 @@
|
|||
import random
|
||||
import numpy as np
|
||||
import math
|
||||
import time
|
||||
import os
|
||||
|
||||
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 = 2 #qiwangyinzi
|
||||
self.k1 = 0.03
|
||||
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 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
|
||||
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:
|
||||
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()
|
||||
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]
|
||||
#iteration
|
||||
|
||||
#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))
|
||||
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):
|
||||
#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]]
|
||||
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[k]=(1-atten[k])*pheromone_mat[k]+pheromone_change[k]
|
||||
count_iter += 1
|
||||
|
||||
#print('count_iter:',count_iter)
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
,time,reward
|
||||
0,3.337860107421875e-06,0
|
||||
1,2.86102294921875e-06,0
|
||||
2,2.86102294921875e-06,0
|
||||
3,2.6226043701171875e-06,0
|
||||
4,2.6226043701171875e-06,0
|
||||
5,2.384185791015625e-06,0
|
||||
6,2.1457672119140625e-06,0
|
||||
7,2.1457672119140625e-06,0
|
||||
8,2.1457672119140625e-06,0
|
||||
9,2.1457672119140625e-06,0
|
||||
10,2.384185791015625e-06,0
|
||||
11,2.1457672119140625e-06,0
|
||||
12,2.384185791015625e-06,0
|
||||
13,2.6226043701171875e-06,0
|
||||
14,2.384185791015625e-06,0
|
||||
15,2.384185791015625e-06,0
|
||||
16,2.384185791015625e-06,0
|
||||
17,2.384185791015625e-06,0
|
||||
18,2.1457672119140625e-06,0
|
||||
19,2.6226043701171875e-06,0
|
||||
20,2.1457672119140625e-06,0
|
||||
21,2.1457672119140625e-06,0
|
||||
22,1.9073486328125e-06,0
|
||||
23,2.1457672119140625e-06,0
|
||||
24,2.384185791015625e-06,0
|
||||
25,2.384185791015625e-06,0
|
||||
26,1.9073486328125e-06,0
|
||||
27,1.9073486328125e-06,0
|
||||
28,1.9073486328125e-06,0
|
||||
29,2.1457672119140625e-06,0
|
||||
30,2.384185791015625e-06,0
|
||||
31,2.384185791015625e-06,0
|
||||
32,2.384185791015625e-06,0
|
||||
33,2.1457672119140625e-06,0
|
||||
34,2.1457672119140625e-06,0
|
||||
35,2.384185791015625e-06,0
|
||||
36,2.1457672119140625e-06,0
|
||||
37,1.9073486328125e-06,0
|
||||
38,1.9073486328125e-06,0
|
||||
39,2.1457672119140625e-06,0
|
||||
40,1.9073486328125e-06,0
|
||||
41,2.1457672119140625e-06,0
|
||||
42,2.1457672119140625e-06,0
|
||||
43,1.9073486328125e-06,0
|
||||
44,2.1457672119140625e-06,0
|
||||
45,2.384185791015625e-06,0
|
||||
46,1.9073486328125e-06,0
|
||||
47,1.9073486328125e-06,0
|
||||
48,2.1457672119140625e-06,0
|
||||
49,2.384185791015625e-06,0
|
||||
50,1.9073486328125e-06,0
|
||||
51,1.9073486328125e-06,0
|
||||
52,1.9073486328125e-06,0
|
||||
53,1.9073486328125e-06,0
|
||||
54,2.384185791015625e-06,0
|
||||
55,2.1457672119140625e-06,0
|
||||
56,2.1457672119140625e-06,0
|
||||
57,2.384185791015625e-06,0
|
||||
58,2.384185791015625e-06,0
|
||||
59,2.1457672119140625e-06,0
|
||||
60,2.1457672119140625e-06,0
|
||||
61,2.1457672119140625e-06,0
|
||||
62,2.384185791015625e-06,0
|
||||
63,2.1457672119140625e-06,0
|
||||
64,1.9073486328125e-06,0
|
||||
65,2.1457672119140625e-06,0
|
||||
66,1.9073486328125e-06,0
|
||||
67,2.1457672119140625e-06,0
|
||||
68,2.1457672119140625e-06,0
|
||||
69,2.1457672119140625e-06,0
|
||||
70,2.1457672119140625e-06,0
|
||||
71,2.1457672119140625e-06,0
|
||||
72,2.384185791015625e-06,0
|
||||
73,2.1457672119140625e-06,0
|
||||
74,2.1457672119140625e-06,0
|
||||
75,2.1457672119140625e-06,0
|
||||
76,2.1457672119140625e-06,0
|
||||
77,1.9073486328125e-06,0
|
||||
78,2.1457672119140625e-06,0
|
||||
79,2.1457672119140625e-06,0
|
||||
80,2.1457672119140625e-06,0
|
||||
81,2.1457672119140625e-06,0
|
||||
82,2.384185791015625e-06,0
|
||||
83,2.1457672119140625e-06,0
|
||||
84,2.1457672119140625e-06,0
|
||||
85,1.9073486328125e-06,0
|
||||
86,2.1457672119140625e-06,0
|
||||
87,2.1457672119140625e-06,0
|
||||
88,2.1457672119140625e-06,0
|
||||
89,1.9073486328125e-06,0
|
||||
90,2.384185791015625e-06,0
|
||||
91,2.1457672119140625e-06,0
|
||||
92,2.384185791015625e-06,0
|
||||
93,2.384185791015625e-06,0
|
||||
94,2.384185791015625e-06,0
|
||||
95,2.384185791015625e-06,0
|
||||
96,2.384185791015625e-06,0
|
||||
97,2.384185791015625e-06,0
|
||||
98,1.9073486328125e-06,0
|
||||
99,2.1457672119140625e-06,0
|
|
|
@ -1,209 +0,0 @@
|
|||
import numpy as np
|
||||
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):
|
||||
self.vehicles_position = np.zeros(vehicle_num,dtype=np.int32)
|
||||
self.vehicles_speed = np.zeros(vehicle_num,dtype=np.int32)
|
||||
self.targets = np.zeros(shape=(target_num+1,4),dtype=np.int32)
|
||||
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]
|
||||
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
|
||||
self.reward = 0
|
||||
self.visualized = visualized
|
||||
self.time = 0
|
||||
self.time_cost = time_cost
|
||||
self.repeat_cost = repeat_cost
|
||||
self.end = False
|
||||
self.assignment = [[] for i in range(vehicle_num)]
|
||||
self.task_generator()
|
||||
|
||||
def task_generator(self):
|
||||
for i in range(self.vehicles_speed.shape[0]):
|
||||
choose = random.randint(0,2)
|
||||
self.vehicles_speed[i] = self.speed_range[choose]
|
||||
for i in range(self.targets.shape[0]-1):
|
||||
self.targets[i+1,0] = random.randint(1,self.map_size) - 0.5*self.map_size # x position
|
||||
self.targets[i+1,1] = random.randint(1,self.map_size) - 0.5*self.map_size # y position
|
||||
self.targets[i+1,2] = random.randint(1,10) # value
|
||||
self.targets[i+1,3] = random.randint(5,30) # time to stay
|
||||
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(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[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.targets[k,2]
|
||||
if self.targets[k,2] == 0:
|
||||
self.reward = self.reward - self.repeat_cost
|
||||
self.vehicles_position[j] = k
|
||||
self.targets[k,2] = 0
|
||||
self.total_reward = self.total_reward + self.reward
|
||||
self.assignment[j].append(action)
|
||||
if count == len(action):
|
||||
self.end = True
|
||||
|
||||
def run(self, assignment, algorithm):
|
||||
self.assignment = assignment
|
||||
self.algorithm = algorithm
|
||||
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])):
|
||||
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
|
||||
if self.end:
|
||||
self.total_reward = 0
|
||||
break
|
||||
|
||||
def visualize(self):
|
||||
if self.assignment == None:
|
||||
plt.scatter(x=0,y=0,s=200,c='k')
|
||||
plt.scatter(x=self.targets[1:,0],y=self.targets[1:,1],s=self.targets[1:,2]*10,c='r')
|
||||
plt.title('Target distribution')
|
||||
plt.show()
|
||||
else:
|
||||
plt.title('Task assignment by '+self.algorithm +', total reward : '+str(self.total_reward))
|
||||
plt.scatter(x=0,y=0,s=200,c='k')
|
||||
plt.scatter(x=self.targets[1:,0],y=self.targets[1:,1],s=self.targets[1:,2]*10,c='r')
|
||||
for i in range(len(self.assignment)):
|
||||
trajectory = np.array([[0,0,20]])
|
||||
for j in range(len(self.assignment[i])):
|
||||
position = self.targets[self.assignment[i][j],:3]
|
||||
trajectory = np.insert(trajectory,j+1,values=position,axis=0)
|
||||
plt.scatter(x=trajectory[1:,0],y=trajectory[1:,1],s=trajectory[1:,2]*10,c='b')
|
||||
plt.plot(trajectory[:,0], trajectory[:,1])
|
||||
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):
|
||||
vehicle_num = random.randint(5,15)
|
||||
target_num = random.randint(30,100)
|
||||
map_size = random.randint(5e3,2e4) # meter
|
||||
env = Env(vehicle_num,target_num,map_size,visualized=True)
|
||||
time_start = time.time()
|
||||
task_assignment = [[i+1 for i in range(0,5)],[i+1 for i in range(5,20)],[i+1 for i in range(20,30)]]
|
||||
time_end = time.time()
|
||||
time_record.append(time_end-time_start)
|
||||
algorithm = 'customized'
|
||||
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=',')
|
||||
'''
|
|
@ -1,179 +0,0 @@
|
|||
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 = 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
|
|
@ -1,387 +0,0 @@
|
|||
# coding: utf-8
|
||||
import numpy as np
|
||||
import random
|
||||
import math
|
||||
import cmath
|
||||
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---------------------------------
|
||||
|
||||
|
||||
class PSO():
|
||||
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.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])
|
||||
del Position_All[m1]
|
||||
return X2
|
||||
# ---------------------Fitness_Computing Function-----------------------------
|
||||
|
||||
def function(self, X):
|
||||
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([])
|
||||
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):
|
||||
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):
|
||||
# Initialization of position(X), speed(V), history optimal(pbest) and global optimal(gbest)
|
||||
for i in range(self.pN):
|
||||
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):
|
||||
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):
|
||||
test = np.random.uniform(0, 1, self.dim+self.uav_num-1)
|
||||
self.TEST[i, :] = test
|
||||
|
||||
# ----------------------Update Particle Position----------------------------------
|
||||
|
||||
def iterator(self):
|
||||
fitness = []
|
||||
fitness_old = 0
|
||||
k = 0
|
||||
for t in range(self.max_iter):
|
||||
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])
|
||||
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]
|
||||
self.uav_best = self.fun_Data()
|
||||
|
||||
# print
|
||||
fitness.append(self.fit)
|
||||
if self.fit == fitness_old:
|
||||
continue
|
||||
else:
|
||||
fitness_old = self.fit
|
||||
return fitness
|
||||
|
||||
# ---------------------Data_Processing Function---------------------------
|
||||
def fun_Data(self):
|
||||
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([])
|
||||
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):
|
||||
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 = []
|
||||
for i in range(self.test_num):
|
||||
Test_Value.append(self.function(self.TEST[i]))
|
||||
return Test_Value
|
||||
# ---------------------Main----------------------------------------
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
# -------------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)
|
||||
'''
|