├── .gitattributes
├── LICENSE
├── README.md
├── pic
├── model.png
└── simulation.png
└── src
├── Auction1_Loadlimit.py
├── Auction1_Loadlimitdraw.py
├── Auction2_Grouplimit.py
├── Auction2_Grouplimit2.py
├── Auction2_Grouplimitdraw.py
├── Auction3_Distributed.py
├── Auction3_Distributeddraw.py
├── Auction3_Distributeddraw_n.py
├── Auction3_Distributeddraw_time.py
├── Auction4_Federated.py
├── Compared2.py
├── Compared3.py
├── graph.py
├── graphdraw.py
├── graphsetup.py
├── num.py
├── ortooltest1.py
├── ortooltest2.py
└── test.py
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Bo Wang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ### Distribution-Auction-Algorithm-based-UAV-Swarm-Task-Assignment 基于分布式拍卖算法的无人机集群任务分配
3 |
4 | ``src`` file is the source file, which contains the code on Distribution-Auction-Algorithm under different network topologies.
5 |
6 | #### Problem Formulation
7 |
8 | 
9 |
10 | $x_{ij} =1 $ means the task $i$ is assigned to uav $j$ with $a_{ij}$ is the return, $N_{i} $ is the maximum number of tasks that $i$ is assigned, $N_{ki} $ denotes the maximum number of tasks belongint to task set $T_k$ for uav $i$.
11 |
12 | #### Simulation
13 |
14 | 
15 |
16 |
17 |
--------------------------------------------------------------------------------
/pic/model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wennboo/Distribution-Auction-Algorithm-based-UAV-Swarm-Task-Assignment/1a1ffd18a0a4307c6be3fd3c36909f8e85808360/pic/model.png
--------------------------------------------------------------------------------
/pic/simulation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wennboo/Distribution-Auction-Algorithm-based-UAV-Swarm-Task-Assignment/1a1ffd18a0a4307c6be3fd3c36909f8e85808360/pic/simulation.png
--------------------------------------------------------------------------------
/src/Auction1_Loadlimit.py:
--------------------------------------------------------------------------------
1 | import random
2 | import time
3 | from num import A_2060
4 | from num import A_40200
5 | from num import A_50500
6 |
7 | #设置全局变量并初始化
8 | nu=20 #无人机数量
9 | nt=60 #任务量
10 | minadd=0.1 #定义最小增量
11 |
12 | ni=[3]*nu #每个无人机最大可执行的任务,这里统一规定为3
13 | #nki=[([2]*nu) for i in range(K)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为2
14 | #K=3 #根据任务分成几组
15 |
16 | all_set=set([x for x in range(nt)]) #定义全集
17 | #K_old=[([0]*nt) for i in range(K)] #初始化原有多少已经中标
18 |
19 |
20 |
21 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
22 | A=A_2060
23 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
24 | #A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
25 | #A=[[4,2,0],[1,3,1],[3,3,2]]
26 | #A=[[90, 80, 75, 70],[35, 85, 55, 65],[125, 95, 90, 95],[45, 110, 95, 115],[50, 100, 90, 100],]
27 | # for i in range(nu):
28 | # for j in range(nt):
29 | # A[i][j]=random.randint(0,20) #生成0-20内的随机数作为收益
30 | # print(A)
31 | #print(A[0])
32 | P=[0]*nt #初始化价格向量P
33 | #print(P)
34 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
35 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
36 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
37 |
38 | # L=[1,2,3]
39 | # S=set(L)
40 | # S1=S.copy()
41 | # for s in S.copy():
42 | # if s==1:
43 | # S.remove(s)
44 | # print(S)
45 | # print(S1)
46 |
47 |
48 |
49 | # 程序主函数
50 | def BidingFirst(i):
51 | V={}
52 | for j in range(nt):
53 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
54 | #print(V)
55 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
56 | #print(V_order)
57 | re_J=set([])
58 | for j in range(nt):
59 | if ni[i]<=0:
60 | break
61 | if V_order[j][1]>0:
62 | ni[i]-=1
63 | re_J.add(V_order[j][0])
64 | #print(re_J)
65 | #储存次优价格
66 | if V_order[j][1]>0:
67 | secondprice=V_order[j][1]
68 | else:
69 | secondprice=0
70 | #print(secondprice)
71 | #更新任务分配信息
72 | for j in re_J:
73 | J[i][j]=1
74 | #print(J[i])
75 | #更新价格
76 | for j in re_J:
77 | P_all[i][j]=P_all[i][j]+V[j]-secondprice+minadd
78 | #print(P_all[i])
79 |
80 |
81 |
82 |
83 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
84 | re=0 #需要重新投标数
85 | J_old=set()
86 | #print(J[i])
87 | for j in range(nt): #将列表转化为集合
88 | if J[i][j]==1:
89 | J_old.add(j)
90 | #print(J_old)
91 | for j in J_old.copy():
92 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
93 | if P_all[i][j]
0:
113 | re-=1
114 | re_J.add(V_order[j][0])
115 | #print(re_J)
116 | #储存次优价格
117 | if V_order[j][1]>0:
118 | secondprice=V_order[j][1]
119 | else:
120 | secondprice=0
121 | #print(secondprice)
122 | #更新任务分配信息
123 | for j in re_J:
124 | J[i][j]=1
125 | #print(J[i])
126 | #更新价格
127 | if re_J==set():
128 | Pchange[i]=0
129 | else:
130 | for j in re_J:
131 | P_all[i][j]=round(P_all[i][j]+V[j]-secondprice+minadd,4)
132 | Pchange[i]=1
133 | #print(Pchange[i])
134 | #print(P_all[i])
135 |
136 | start=time.time()
137 |
138 | for i in range(nu): #第一轮价格初始化
139 | BidingFirst(i)
140 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
141 | for j in range(nt): #第一轮价格一致阶段
142 | l=-1
143 | m=-1
144 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
145 | if P_all[i][j]==0 and P[j]==0:
146 | continue
147 | elif P_all[i][j]>=P[j] :
148 | P[j]=P_all[i][j]
149 | l=i
150 | m=j
151 | if l!=-1 and m!=-1:
152 | pri[l][m]=1
153 | # print(0)
154 | # print(P_all)
155 | # print(P)
156 | # print(J)
157 |
158 |
159 | n=0
160 | while(1):
161 | for i in range(nu):
162 | BidingPhase(i)
163 | #print(pri)
164 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
165 | for j in range(nt):
166 | l=-1
167 | m=-1
168 | for i in range(nu):
169 | if P_all[i][j]==0 and P[j]==0:
170 | continue
171 | elif P_all[i][j]>=P[j] :
172 | P[j]=P_all[i][j]
173 | l=i
174 | m=j
175 | if l!=-1 and m!=-1:
176 | pri[l][m]=1
177 | n+=1
178 | # print(n)
179 | # print(P_all)
180 | # print(P)
181 | # print(J)
182 | if Pchange==[0]*nu:
183 | break
184 |
185 | end=time.time()
186 |
187 | print("迭代次数%d"%n)
188 | sum=0
189 | for i in range(nu):
190 | print("无人机%d选择了目标"%i,end='')
191 | for j in range(nt):
192 | if J[i][j]==1:
193 | sum+=A[i][j]
194 | print("%d,"%j,end='')
195 | print('')
196 | print("总收益值为%d"%sum)
197 | print(end-start)
198 |
199 |
200 |
--------------------------------------------------------------------------------
/src/Auction1_Loadlimitdraw.py:
--------------------------------------------------------------------------------
1 | import random
2 | from num import A_2060
3 | from num import A_40200
4 | from num import A_50500
5 | import matplotlib.pyplot as plt
6 | plt.rcParams['font.sans-serif'] = ['SimHei']
7 |
8 | minadd=0.01 #定义最小增量
9 | x_minadd=[]
10 | y_sum=[]
11 | while(minadd<1):
12 | #设置全局变量并初始化
13 | nu=20 #无人机数量
14 | nt=60 #任务量
15 |
16 |
17 | ni=[3]*nu #每个无人机最大可执行的任务,这里统一规定为3
18 | #nki=[([2]*nu) for i in range(K)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为2
19 | #K=3 #根据任务分成几组
20 |
21 | all_set=set([x for x in range(nt)]) #定义全集
22 | #K_old=[([0]*nt) for i in range(K)] #初始化原有多少已经中标
23 |
24 |
25 |
26 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
27 | A=A_2060
28 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
29 | #A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
30 | #A=[[4,2,0],[1,3,1],[3,3,2]]
31 | #A=[[90, 80, 75, 70],[35, 85, 55, 65],[125, 95, 90, 95],[45, 110, 95, 115],[50, 100, 90, 100],]
32 | # for i in range(nu):
33 | # for j in range(nt):
34 | # A[i][j]=random.randint(0,20) #生成0-20内的随机数作为收益
35 | # print(A)
36 | #print(A[0])
37 | P=[0]*nt #初始化价格向量P
38 | #print(P)
39 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
40 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
41 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
42 |
43 | # L=[1,2,3]
44 | # S=set(L)
45 | # S1=S.copy()
46 | # for s in S.copy():
47 | # if s==1:
48 | # S.remove(s)
49 | # print(S)
50 | # print(S1)
51 |
52 |
53 |
54 | # 程序主函数
55 | def BidingFirst(i):
56 | V={}
57 | for j in range(nt):
58 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
59 | #print(V)
60 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
61 | #print(V_order)
62 | re_J=set([])
63 | for j in range(nt):
64 | if ni[i]<=0:
65 | break
66 | if V_order[j][1]>0:
67 | ni[i]-=1
68 | re_J.add(V_order[j][0])
69 | #print(re_J)
70 | #储存次优价格
71 | if V_order[j][1]>0:
72 | secondprice=V_order[j][1]
73 | else:
74 | secondprice=0
75 | #print(secondprice)
76 | #更新任务分配信息
77 | for j in re_J:
78 | J[i][j]=1
79 | #print(J[i])
80 | #更新价格
81 | for j in re_J:
82 | P_all[i][j]=P_all[i][j]+V[j]-secondprice+minadd
83 | #print(P_all[i])
84 |
85 |
86 |
87 |
88 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
89 | re=0 #需要重新投标数
90 | J_old=set()
91 | #print(J[i])
92 | for j in range(nt): #将列表转化为集合
93 | if J[i][j]==1:
94 | J_old.add(j)
95 | #print(J_old)
96 | for j in J_old.copy():
97 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
98 | if P_all[i][j]
0:
118 | re-=1
119 | re_J.add(V_order[j][0])
120 | #print(re_J)
121 | #储存次优价格
122 | if V_order[j][1]>0:
123 | secondprice=V_order[j][1]
124 | else:
125 | secondprice=0
126 | #print(secondprice)
127 | #更新任务分配信息
128 | for j in re_J:
129 | J[i][j]=1
130 | #print(J[i])
131 | #更新价格
132 | if re_J==set():
133 | Pchange[i]=0
134 | else:
135 | for j in re_J:
136 | P_all[i][j]=round(P_all[i][j]+V[j]-secondprice+minadd,4)
137 | Pchange[i]=1
138 | #print(Pchange[i])
139 | #print(P_all[i])
140 |
141 | for i in range(nu): #第一轮价格初始化
142 | BidingFirst(i)
143 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
144 | for j in range(nt): #第一轮价格一致阶段
145 | l=-1
146 | m=-1
147 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
148 | if P_all[i][j]==0 and P[j]==0:
149 | continue
150 | elif P_all[i][j]>=P[j] :
151 | P[j]=P_all[i][j]
152 | l=i
153 | m=j
154 | if l!=-1 and m!=-1:
155 | pri[l][m]=1
156 | # print(0)
157 | # print(P_all)
158 | # print(P)
159 | # print(J)
160 |
161 |
162 | n=0
163 | while(1):
164 | for i in range(nu):
165 | BidingPhase(i)
166 | #print(pri)
167 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
168 | for j in range(nt):
169 | l=-1
170 | m=-1
171 | for i in range(nu):
172 | if P_all[i][j]==0 and P[j]==0:
173 | continue
174 | elif P_all[i][j]>=P[j] :
175 | P[j]=P_all[i][j]
176 | l=i
177 | m=j
178 | if l!=-1 and m!=-1:
179 | pri[l][m]=1
180 | n+=1
181 | # print(n)
182 | # print(P_all)
183 | # print(P)
184 | # print(J)
185 | if Pchange==[0]*nu:
186 | break
187 |
188 | #print("迭代次数%d"%n)
189 | sum=0
190 | for i in range(nu):
191 | ##print("无人机%d选择了目标"%i,end='')
192 | for j in range(nt):
193 | if J[i][j]==1:
194 | sum+=A[i][j]
195 | ##print("%d,"%j,end='')
196 | #print('')
197 | #print("总收益值为%d"%sum)
198 | x_minadd.append(minadd)
199 | y_sum.append(sum)
200 | minadd+=0.01
201 |
202 | plt.plot(x_minadd, y_sum, linewidth=1)
203 | plt.show()
204 |
205 |
206 |
--------------------------------------------------------------------------------
/src/Auction2_Grouplimit.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import time
5 | from num import A_2060
6 | from num import A_40200
7 | from num import A_50500
8 |
9 |
10 | #设置全局变量并初始化
11 | nu=20 #无人机数量
12 | nt=60#任务量
13 | minadd=1 #定义最小增量
14 | ns=4 #根据任务分成几组
15 | ni=[3]*nu #每个无人机最大可执行的任务,这里统一规定为3
16 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
17 | #print(nki)
18 | K_dic={}
19 | ave=int(nt/ns) #每个分组有多少个成员
20 | for i in range(nt):#建立任务和任务分组关系的字典
21 | K_dic[i]=int(i/ave)
22 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
23 | all_set=set([x for x in range(nt)]) #定义全集
24 | Kall_set=[] #定义分组的全集
25 | for i in range(ns):
26 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
27 |
28 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
29 | A=A_2060
30 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
31 | # A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
32 | #A=[[4,2,0],[1,3,1],[3,3,2]]
33 |
34 | # for i in range(nu):
35 | # for j in range(nt):
36 | # A[i][j]=random.randint(0,20) #生成0-20内的随机数作为收益
37 | # print(A)
38 | #print(A[0])
39 | P=[0]*nt #初始化价格向量P
40 | #print(P)
41 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
42 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
43 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
44 |
45 | # L=[1,2,3]
46 | # S=set(L)
47 | # S1=S.copy()
48 | # for s in S.copy():
49 | # if s==1:
50 | # S.remove(s)
51 | # print(S)
52 | # print(S1)
53 |
54 |
55 |
56 | # 程序主函数
57 | def BidingFirst(i):
58 | V={}
59 | nil=ni[i]
60 | nkicopy=deepcopy(nki)
61 | for j in range(nt):
62 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
63 | #print(V)
64 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
65 | #print(V_order)
66 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
67 | #print(re_K)
68 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
69 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
70 |
71 | for j in range(nt):
72 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
73 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
74 | break
75 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
76 | #ni[i]-=1
77 | nkicopy[i][k_ord]-=1
78 | #re_J.add(V_order[j][0])
79 | re_K[k_ord].add(V_order[j][0])
80 | else:
81 | if V_order[j][1]>0 and k_flag[k_ord]==0:
82 | k_secondprice[k_ord]=V_order[j][1]
83 | k_flag[k_ord]=1
84 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
85 | k_secondprice[k_ord]=0
86 | k_flag[k_ord]=1
87 | # print(nki[i])
88 | # print(k_flag)
89 | #print(k_secondprice)
90 | # print(re_K)
91 | #print(re_J)
92 | kchose_set=set() #用于记录投标全集
93 | for k in range(ns):
94 | kchose_set=kchose_set|re_K[k]
95 | C={}
96 | cnt=0
97 | for j in kchose_set:
98 | C[j]=V[j]
99 | cnt+=1
100 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
101 | #print(C_order)
102 | #print(cnt)
103 | #print(kchose_set)
104 |
105 | re_J=set([])
106 | for j in range(cnt):
107 | if nil<=0: #若超过载核限制则退出
108 | break
109 | nil-=1
110 | re_J.add(C_order[j][0])
111 | #print(j,nil)
112 | #print(re_J)
113 | #储存载核的次优价格
114 | if ni[i]>=cnt:
115 | secondprice=0
116 | else:
117 | secondprice=C_order[j][1]
118 | # for k in range(ns):
119 | # print(Kall_set[k]-re_K[k])
120 | #print(secondprice)
121 | #更新任务分配信息
122 | for j in re_J:
123 | J[i][j]=1
124 | #print(J[i])
125 | #更新价格
126 | for j in re_J:
127 | k_ord=K_dic[j]
128 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
129 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
130 | #print(P_all[i])
131 |
132 |
133 |
134 |
135 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
136 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
137 | re=0 #需要重新投标数
138 | J_old=set()
139 | #print(J[i])
140 | for j in range(nt): #将列表转化为集合
141 | if J[i][j]==1:
142 | J_old.add(j)
143 | #print(J_old)
144 | for j in J_old.copy():
145 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
146 | if P_all[i][j]
P[j] or P_all[i][j]==P[j] and pri[i][j]==1 :
152 | k_ord=K_dic[j]
153 | re_Knum[k_ord]+=1
154 | #print(re_Knum)
155 | #print(J_old)
156 | new_Knum={} #每个分组需要补充的数量,使用字典表示
157 | secondnum=0 #记录有多少个组需要重新补充任务
158 | for k in range(ns):
159 | if nki[i][k]-re_Knum[k]!=0:
160 | new_Knum[k]=nki[i][k]-re_Knum[k]
161 | secondnum+=1
162 | #print(new_Knum)
163 | #print(secondnum)
164 | V={}
165 | #print(re)
166 | #print(J_old)
167 | #print(A[i])
168 | for j in range(nt):
169 | V[j]=round(A[i][j]-P[j],4) #计算每个商品的当前收益,小数点保留四位
170 | #print(V)
171 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
172 | #print(V_order)
173 | leftset=all_set-J_old #再余下的集合中将投标补至ni
174 | #print(leftset)
175 |
176 |
177 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
178 | #print(re_K)
179 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
180 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
181 | flagnum=0
182 | for j in range(nt):
183 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
184 | if new_Knum=={}:
185 | break
186 | jud = all(x == 0 for x in new_Knum.values())
187 | if jud and flagnum==secondnum: #
188 | break
189 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
190 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
191 | new_Knum[k_ord]-=1
192 | re_K[k_ord].add(V_order[j][0])
193 | else:
194 | if V_order[j][1]>0 and k_flag[k_ord]==0:
195 | k_secondprice[k_ord]=V_order[j][1]
196 | k_flag[k_ord]=1
197 | flagnum+=1
198 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
199 | k_secondprice[k_ord]=0
200 | k_flag[k_ord]=1
201 | flagnum+=1
202 | #print(re_K)
203 | #print(k_secondprice)
204 | # print()
205 |
206 | kchose_set=set() #用于记录投标全集
207 | for k in range(ns):
208 | kchose_set=kchose_set|re_K[k]
209 | C={}
210 | cnt=0
211 | for j in kchose_set:
212 | C[j]=V[j]
213 | cnt+=1
214 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
215 | #print(C_order)
216 | #print(cnt)
217 | #print(kchose_set)
218 |
219 | re_J=set([])
220 | for j in range(cnt):
221 | if re<=0: #若超过载核限制则退出
222 | break
223 | re-=1
224 | re_J.add(C_order[j][0])
225 | #print(re_J)
226 | #储存载核的次优价格
227 | if ni[i]>=cnt:
228 | secondprice=0
229 | else:
230 | secondprice=C_order[j][1]
231 | # for k in range(ns):
232 | # print(Kall_set[k]-re_K[k])
233 | #print(secondprice)
234 | #print()
235 | #更新任务分配信息
236 | for j in re_J:
237 | J[i][j]=1
238 | #print(J[i])
239 | #更新价格
240 | if re_J==set():
241 | Pchange[i]=0
242 | else:
243 | for j in re_J:
244 | k_ord=K_dic[j]
245 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
246 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
247 | Pchange[i]=1
248 |
249 | #print(P_all[i])
250 |
251 | start=time.time()
252 |
253 | for i in range(nu): #第一轮价格初始化
254 | BidingFirst(i)
255 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
256 | for j in range(nt): #第一轮价格一致阶段
257 | l=-1
258 | m=-1
259 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
260 | if P_all[i][j]==0 and P[j]==0:
261 | continue
262 | elif P_all[i][j]>=P[j] :
263 | P[j]=P_all[i][j]
264 | l=i
265 | m=j
266 | if l!=-1 and m!=-1:
267 | pri[l][m]=1
268 | # print(0)
269 | # print(P_all)
270 | # print(P)
271 | # print(J)
272 |
273 | # BidingPhase(0)
274 | # BidingPhase(1)
275 | # BidingPhase(2)
276 | n=0
277 | while(1):
278 | for i in range(nu):
279 | BidingPhase(i)
280 | #print(pri)
281 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
282 | # maxpos=[-1]*nt #用于记录当前最大价格的下标
283 | # #print(maxpos)
284 | # for u in range(nu):
285 | # for j in range(nt):
286 | # if P_all[u][j]==0 and P[j]==0: #都没有投标
287 | # continue
288 | # elif P_all[u][j]>P[j]:
289 | # P[j]=P_all[u][j]
290 | # maxpos[j]=u
291 | # elif P_all[u][j]==P[j] and u>maxpos[j]:#如果优先级更高,那么更新最大下标集
292 | # maxpos[j]=u
293 | # for j in range(nt):
294 | # if maxpos[j]==-1:
295 | # continue
296 | # else:
297 | # pri[maxpos[j]][j]=1
298 | for j in range(nt):
299 | l=-1
300 | m=-1
301 | for i in range(nu):
302 | if P_all[i][j]==0 and P[j]==0:
303 | continue
304 | elif P_all[i][j]>=P[j] :
305 | P[j]=P_all[i][j]
306 | l=i
307 | m=j
308 | if l!=-1 and m!=-1:
309 | pri[l][m]=1
310 | n+=1
311 | # print(n)
312 | # print(P_all)
313 | #print(P)
314 | # print(J)
315 | if Pchange==[0]*nu:
316 | break
317 |
318 | end=time.time()
319 |
320 | print("迭代次数%d"%n)
321 | sum=0
322 | for i in range(nu):
323 | print("无人机%d选择了目标"%i,end='')
324 | for j in range(nt):
325 | if J[i][j]==1:
326 | sum+=A[i][j]
327 | print("%d(%d),"%(j,K_dic[j]),end='')
328 | print('')
329 | print("总收益值为%d"%sum)
330 | print(end-start)
331 |
--------------------------------------------------------------------------------
/src/Auction2_Grouplimit2.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import time
5 | from num import A_2060
6 | from num import A_40200
7 | from num import A_50500
8 |
9 |
10 | #设置全局变量并初始化
11 | nu=50 #无人机数量
12 | nt=500#任务量
13 | minadd=1 #定义最小增量
14 | ns=20 #根据任务分成几组
15 | ni=[10]*nu #每个无人机最大可执行的任务,这里统一规定为3
16 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
17 | #print(nki)
18 | K_dic={}
19 | ave=int(nt/ns) #每个分组有多少个成员
20 | for i in range(nt):#建立任务和任务分组关系的字典
21 | K_dic[i]=int(i/ave)
22 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
23 | all_set=set([x for x in range(nt)]) #定义全集
24 | Kall_set=[] #定义分组的全集
25 | for i in range(ns):
26 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
27 |
28 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
29 | A=A_50500
30 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
31 | # A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
32 | #A=[[4,2,0],[1,3,1],[3,3,2]]
33 |
34 | # for i in range(nu):
35 | # for j in range(nt):
36 | # A[i][j]=random.randint(0,20) #生成0-20内的随机数作为收益
37 | # print(A)
38 | #print(A[0])
39 | P=[0]*nt #初始化价格向量P
40 | #print(P)
41 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
42 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
43 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
44 | B=[-1]*nt
45 | # L=[1,2,3]
46 | # S=set(L)
47 | # S1=S.copy()
48 | # for s in S.copy():
49 | # if s==1:
50 | # S.remove(s)
51 | # print(S)
52 | # print(S1)
53 |
54 |
55 |
56 | # 程序主函数
57 | def BidingFirst(i):
58 | V={}
59 | nil=ni[i]
60 | nkicopy=deepcopy(nki)
61 | for j in range(nt):
62 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
63 | #print(V)
64 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
65 | #print(V_order)
66 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
67 | #print(re_K)
68 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
69 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
70 |
71 | for j in range(nt):
72 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
73 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
74 | break
75 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
76 | #ni[i]-=1
77 | nkicopy[i][k_ord]-=1
78 | #re_J.add(V_order[j][0])
79 | re_K[k_ord].add(V_order[j][0])
80 | else:
81 | if V_order[j][1]>0 and k_flag[k_ord]==0:
82 | k_secondprice[k_ord]=V_order[j][1]
83 | k_flag[k_ord]=1
84 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
85 | k_secondprice[k_ord]=0
86 | k_flag[k_ord]=1
87 | # print(nki[i])
88 | # print(k_flag)
89 | #print(k_secondprice)
90 | # print(re_K)
91 | #print(re_J)
92 | kchose_set=set() #用于记录投标全集
93 | for k in range(ns):
94 | kchose_set=kchose_set|re_K[k]
95 | C={}
96 | cnt=0
97 | for j in kchose_set:
98 | C[j]=V[j]
99 | cnt+=1
100 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
101 | #print(C_order)
102 | #print(cnt)
103 | #print(kchose_set)
104 |
105 | re_J=set([])
106 | for j in range(cnt):
107 | if nil<=0: #若超过载核限制则退出
108 | break
109 | nil-=1
110 | re_J.add(C_order[j][0])
111 | #print(j,nil)
112 | #print(re_J)
113 | #储存载核的次优价格
114 | if ni[i]>=cnt:
115 | secondprice=0
116 | else:
117 | secondprice=C_order[j][1]
118 | # for k in range(ns):
119 | # print(Kall_set[k]-re_K[k])
120 | #print(secondprice)
121 | #更新任务分配信息
122 | for j in re_J:
123 | J[i][j]=1
124 | #print(J[i])
125 | #更新价格
126 | for j in re_J:
127 | k_ord=K_dic[j]
128 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
129 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
130 | #print(P_all[i])
131 |
132 |
133 |
134 |
135 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
136 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
137 | re=0 #需要重新投标数
138 | J_old=set()
139 | #print(J[i])
140 | for j in range(nt): #将列表转化为集合
141 | if J[i][j]==1:
142 | J_old.add(j)
143 | #print(J_old)
144 | for j in J_old.copy():
145 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
146 | if P_all[i][j]
P[j] or P_all[i][j]==P[j] and B[j]==i :
152 | k_ord=K_dic[j]
153 | re_Knum[k_ord]+=1
154 | #print(re_Knum)
155 | #print(J_old)
156 | new_Knum={} #每个分组需要补充的数量,使用字典表示
157 | secondnum=0 #记录有多少个组需要重新补充任务
158 | for k in range(ns):
159 | if nki[i][k]-re_Knum[k]!=0:
160 | new_Knum[k]=nki[i][k]-re_Knum[k]
161 | secondnum+=1
162 | #print(new_Knum)
163 | #print(secondnum)
164 | V={}
165 | #print(re)
166 | #print(J_old)
167 | #print(A[i])
168 | for j in range(nt):
169 | V[j]=round(A[i][j]-P[j],4) #计算每个商品的当前收益,小数点保留四位
170 | #print(V)
171 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
172 | #print(V_order)
173 | leftset=all_set-J_old #再余下的集合中将投标补至ni
174 | #print(leftset)
175 |
176 |
177 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
178 | #print(re_K)
179 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
180 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
181 | flagnum=0
182 | for j in range(nt):
183 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
184 | if new_Knum=={}:
185 | break
186 | jud = all(x == 0 for x in new_Knum.values())
187 | if jud and flagnum==secondnum: #
188 | break
189 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
190 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
191 | new_Knum[k_ord]-=1
192 | re_K[k_ord].add(V_order[j][0])
193 | else:
194 | if V_order[j][1]>0 and k_flag[k_ord]==0:
195 | k_secondprice[k_ord]=V_order[j][1]
196 | k_flag[k_ord]=1
197 | flagnum+=1
198 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
199 | k_secondprice[k_ord]=0
200 | k_flag[k_ord]=1
201 | flagnum+=1
202 | #print(re_K)
203 | #print(k_secondprice)
204 | # print()
205 |
206 | kchose_set=set() #用于记录投标全集
207 | for k in range(ns):
208 | kchose_set=kchose_set|re_K[k]
209 | C={}
210 | cnt=0
211 | for j in kchose_set:
212 | C[j]=V[j]
213 | cnt+=1
214 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
215 | #print(C_order)
216 | #print(cnt)
217 | #print(kchose_set)
218 |
219 | re_J=set([])
220 | for j in range(cnt):
221 | if re<=0: #若超过载核限制则退出
222 | break
223 | re-=1
224 | re_J.add(C_order[j][0])
225 | #print(re_J)
226 | #储存载核的次优价格
227 | if ni[i]>=cnt:
228 | secondprice=0
229 | else:
230 | secondprice=C_order[j][1]
231 | # for k in range(ns):
232 | # print(Kall_set[k]-re_K[k])
233 | #print(secondprice)
234 | #print()
235 | #更新任务分配信息
236 | for j in re_J:
237 | J[i][j]=1
238 | #print(J[i])
239 | #更新价格
240 | if re_J==set():
241 | Pchange[i]=0
242 | else:
243 | for j in re_J:
244 | k_ord=K_dic[j]
245 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
246 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
247 | Pchange[i]=1
248 |
249 | #print(P_all[i])
250 |
251 | start=time.time()
252 |
253 | for i in range(nu): #第一轮价格初始化
254 | BidingFirst(i)
255 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
256 | B=[-1]*nt
257 | for j in range(nt): #第一轮价格一致阶段
258 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
259 | if P_all[i][j]==0 and P[j]==0:
260 | continue
261 | elif P_all[i][j]>P[j] :
262 | P[j]=P_all[i][j]
263 | B[j]=i
264 | elif P_all[i][j]==P[j] and i>B[j]:
265 | B[j]=i
266 |
267 |
268 | n=0
269 | while(1):
270 | for i in range(nu):
271 | BidingPhase(i)
272 | #print(pri)
273 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
274 | for j in range(nt):
275 | for i in range(nu):
276 | if P_all[i][j]==0 and P[j]==0:
277 | continue
278 | elif P_all[i][j]>P[j] :
279 | P[j]=P_all[i][j]
280 | B[j]=i
281 | elif P_all[i][j]==P[j] and i>B[j]:
282 | B[j]=i
283 | n+=1
284 | # print(n)
285 | # print(P_all)
286 | #print(P)
287 | # print(J)
288 | if Pchange==[0]*nu:
289 | break
290 |
291 | end=time.time()
292 |
293 | print("迭代次数%d"%n)
294 | sum=0
295 | for i in range(nu):
296 | print("无人机%d选择了目标"%i,end='')
297 | for j in range(nt):
298 | if J[i][j]==1:
299 | sum+=A[i][j]
300 | print("%d(%d),"%(j,K_dic[j]),end='')
301 | print('')
302 | print("总收益值为%d"%sum)
303 | print(end-start)
304 |
--------------------------------------------------------------------------------
/src/Auction2_Grouplimitdraw.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | from num import A_2060
6 | from num import A_40200
7 | from num import A_50500
8 |
9 | minadd=1 #定义最小增量
10 | x_minadd=[]
11 | y_sum=[]
12 | y_count=[]
13 | while(minadd<5):
14 | #设置全局变量并初始化
15 | nu=20 #无人机数量
16 | nt=60 #任务量
17 |
18 | ns=4 #根据任务分成几组
19 | ni=[3]*nu #每个无人机最大可执行的任务,这里统一规定为3
20 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
21 | #print(nki)
22 | K_dic={}
23 | ave=int(nt/ns) #每个分组有多少个成员
24 | for i in range(nt):#建立任务和任务分组关系的字典
25 | K_dic[i]=int(i/ave)
26 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
27 | all_set=set([x for x in range(nt)]) #定义全集
28 | Kall_set=[] #定义分组的全集
29 | for i in range(ns):
30 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
31 |
32 |
33 |
34 |
35 |
36 |
37 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
38 | A=A_2060
39 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
40 | # A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
41 | #A=[[4,2,0],[1,3,1],[3,3,2]]
42 |
43 | # for i in range(nu):
44 | # for j in range(nt):
45 | # A[i][j]=random.randint(0,20) #生成0-20内的随机数作为收益
46 | # print(A)
47 | #print(A[0])
48 | P=[0]*nt #初始化价格向量P
49 | #print(P)
50 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
51 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
52 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
53 |
54 | # L=[1,2,3]
55 | # S=set(L)
56 | # S1=S.copy()
57 | # for s in S.copy():
58 | # if s==1:
59 | # S.remove(s)
60 | # print(S)
61 | # print(S1)
62 |
63 |
64 |
65 | # 程序主函数
66 | def BidingFirst(i):
67 | V={}
68 | nil=ni[i]
69 | nkicopy=deepcopy(nki)
70 | for j in range(nt):
71 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
72 | #print(V)
73 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
74 | #print(V_order)
75 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
76 | #print(re_K)
77 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
78 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
79 |
80 | for j in range(nt):
81 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
82 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
83 | break
84 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
85 | #ni[i]-=1
86 | nkicopy[i][k_ord]-=1
87 | #re_J.add(V_order[j][0])
88 | re_K[k_ord].add(V_order[j][0])
89 | else:
90 | if V_order[j][1]>0 and k_flag[k_ord]==0:
91 | k_secondprice[k_ord]=V_order[j][1]
92 | k_flag[k_ord]=1
93 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
94 | k_secondprice[k_ord]=0
95 | k_flag[k_ord]=1
96 | # print(nki[i])
97 | # print(k_flag)
98 | #print(k_secondprice)
99 | # print(re_K)
100 | #print(re_J)
101 | kchose_set=set() #用于记录投标全集
102 | for k in range(ns):
103 | kchose_set=kchose_set|re_K[k]
104 | C={}
105 | cnt=0
106 | for j in kchose_set:
107 | C[j]=V[j]
108 | cnt+=1
109 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
110 | #print(C_order)
111 | #print(cnt)
112 | #print(kchose_set)
113 |
114 | re_J=set([])
115 | for j in range(cnt):
116 | if nil<=0: #若超过载核限制则退出
117 | break
118 | nil-=1
119 | re_J.add(C_order[j][0])
120 | #print(j,nil)
121 | #print(re_J)
122 | #储存载核的次优价格
123 | if ni[i]>=cnt:
124 | secondprice=0
125 | else:
126 | secondprice=C_order[j][1]
127 | # for k in range(ns):
128 | # print(Kall_set[k]-re_K[k])
129 | #print(secondprice)
130 | #更新任务分配信息
131 | for j in re_J:
132 | J[i][j]=1
133 | #print(J[i])
134 | #更新价格
135 | for j in re_J:
136 | k_ord=K_dic[j]
137 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
138 | P_all[i][j]=P_all[i][j]+V[j]-maxsecondprice+minadd
139 | #print(P_all[i])
140 |
141 |
142 |
143 |
144 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
145 | nkicopy=deepcopy(nki)
146 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
147 | re=0 #需要重新投标数
148 | J_old=set()
149 | #print(J[i])
150 | for j in range(nt): #将列表转化为集合
151 | if J[i][j]==1:
152 | J_old.add(j)
153 | #print(J_old)
154 | for j in J_old.copy():
155 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
156 | if P_all[i][j]
P[j] or P_all[i][j]==P[j] and pri[i][j]==1 :
162 | k_ord=K_dic[j]
163 | re_Knum[k_ord]+=1
164 | #print(re_Knum)
165 | #print(J_old)
166 | new_Knum={} #每个分组需要补充的数量,使用字典表示
167 | secondnum=0 #记录有多少个组需要重新补充任务
168 | for k in range(ns):
169 | if nki[i][k]-re_Knum[k]!=0:
170 | new_Knum[k]=nki[i][k]-re_Knum[k]
171 | secondnum+=1
172 | #print(new_Knum)
173 | #print(secondnum)
174 | V={}
175 | #print(re)
176 | #print(J_old)
177 | #print(A[i])
178 | for j in range(nt):
179 | V[j]=round(A[i][j]-P[j],4) #计算每个商品的当前收益,小数点保留四位
180 | #print(V)
181 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
182 | #print(V_order)
183 | leftset=all_set-J_old #再余下的集合中将投标补至ni
184 | #print(leftset)
185 |
186 |
187 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
188 | #print(re_K)
189 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
190 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
191 | flagnum=0
192 | for j in range(nt):
193 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
194 | if new_Knum=={}:
195 | break
196 | jud = all(x == 0 for x in new_Knum.values())
197 | if jud and flagnum==secondnum: #
198 | break
199 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
200 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
201 | new_Knum[k_ord]-=1
202 | re_K[k_ord].add(V_order[j][0])
203 | else:
204 | if V_order[j][1]>0 and k_flag[k_ord]==0:
205 | k_secondprice[k_ord]=V_order[j][1]
206 | k_flag[k_ord]=1
207 | flagnum+=1
208 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
209 | k_secondprice[k_ord]=0
210 | k_flag[k_ord]=1
211 | flagnum+=1
212 | #print(re_K)
213 | #print(k_secondprice)
214 | # print()
215 |
216 | kchose_set=set() #用于记录投标全集
217 | for k in range(ns):
218 | kchose_set=kchose_set|re_K[k]
219 | C={}
220 | cnt=0
221 | for j in kchose_set:
222 | C[j]=V[j]
223 | cnt+=1
224 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
225 | #print(C_order)
226 | #print(cnt)
227 | #print(kchose_set)
228 |
229 | re_J=set([])
230 | for j in range(cnt):
231 | if re<=0: #若超过载核限制则退出
232 | break
233 | re-=1
234 | re_J.add(C_order[j][0])
235 | #print(re_J)
236 | #储存载核的次优价格
237 | if ni[i]>=cnt:
238 | secondprice=0
239 | else:
240 | secondprice=C_order[j][1]
241 | # for k in range(ns):
242 | # print(Kall_set[k]-re_K[k])
243 | #print(secondprice)
244 | #print()
245 | #更新任务分配信息
246 | for j in re_J:
247 | J[i][j]=1
248 | #print(J[i])
249 | #更新价格
250 | if re_J==set():
251 | Pchange[i]=0
252 | else:
253 | for j in re_J:
254 | k_ord=K_dic[j]
255 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
256 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
257 | Pchange[i]=1
258 |
259 | #print(P_all[i])
260 |
261 |
262 |
263 | for i in range(nu): #第一轮价格初始化
264 | BidingFirst(i)
265 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
266 | for j in range(nt): #第一轮价格一致阶段
267 | l=-1
268 | m=-1
269 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
270 | if P_all[i][j]==0 and P[j]==0:
271 | continue
272 | elif P_all[i][j]>=P[j] :
273 | P[j]=P_all[i][j]
274 | l=i
275 | m=j
276 | if l!=-1 and m!=-1:
277 | pri[l][m]=1
278 | # print(0)
279 | # print(P_all)
280 | # print(P)
281 | # print(J)
282 |
283 | # BidingPhase(0)
284 | # BidingPhase(1)
285 | # BidingPhase(2)
286 | n=0
287 | while(1):
288 | for i in range(nu):
289 | BidingPhase(i)
290 | #print(pri)
291 | pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
292 | for j in range(nt):
293 | l=-1
294 | m=-1
295 | for i in range(nu):
296 | if P_all[i][j]==0 and P[j]==0:
297 | continue
298 | elif P_all[i][j]>=P[j] :
299 | P[j]=P_all[i][j]
300 | l=i
301 | m=j
302 | if l!=-1 and m!=-1:
303 | pri[l][m]=1
304 | n+=1
305 | # print(n)
306 | # print(P_all)
307 | # print(P)
308 | # print(J)
309 | if Pchange==[0]*nu:
310 | break
311 |
312 | #print("迭代次数%d"%n)
313 | sum=0
314 | for i in range(nu):
315 | #print("无人机%d选择了目标"%i,end='')
316 | for j in range(nt):
317 | if J[i][j]==1:
318 | sum+=A[i][j]
319 | #print("%d(%d),"%(j,K_dic[j]),end='')
320 | #print('')
321 | #print("总收益值为%d"%sum)
322 | x_minadd.append(minadd)
323 | y_sum.append(sum)
324 | y_count.append(n)
325 | minadd+=0.01
326 |
327 | plt.plot(x_minadd,y_count, linewidth=1)
328 | plt.xlabel('Parameter ε')
329 | #plt.ylabel('Sum')
330 | plt.ylabel('Iterations')
331 | plt.show()
332 |
333 |
334 |
--------------------------------------------------------------------------------
/src/Auction3_Distributed.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | import time
4 | from copy import deepcopy
5 | import matplotlib.pyplot as plt
6 | import networkx as nx
7 | from num import A_2060
8 | from num import A_40200
9 | from num import A_50500
10 | from graph import arcs_20
11 | from graph import arcs_40
12 | from graph import arcs_50
13 | from graph import arcs_line20
14 | from graph import arcs_random20
15 |
16 |
17 |
18 |
19 | #设置全局变量并初始化
20 | arcs=arcs_50 #用邻接矩阵来表示当前的网络拓扑结构
21 | nu=50 #无人机数量
22 | nt=500 #任务量
23 | minadd=1 #定义最小增量
24 | ns=20 #根据任务分成几组
25 | ni=[10]*nu #每个无人机最大可执行的任务,这里统一规定为3
26 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
27 | #print(nki)
28 | K_dic={}
29 | ave=int(nt/ns) #每个分组有多少个成员
30 | for i in range(nt):#建立任务和任务分组关系的字典
31 | K_dic[i]=int(i/ave)
32 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
33 | all_set=set([x for x in range(nt)]) #定义全集
34 | Kall_set=[] #定义分组的全集
35 | for i in range(ns):
36 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
37 |
38 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
39 | A=A_50500
40 | G=nx.Graph() # 新建一个无向图
41 | nodes=[]
42 | edges=[]
43 | for i in range(nu):
44 | G.add_node(i)
45 | for i in range(nu):
46 | for j in range(nu):
47 | if arcs[i][j]==1:
48 | G.add_edge(i,j)
49 | netdiameter=nx.diameter(G)
50 |
51 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
52 | # A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
53 | #A=[[4,2,0],[1,3,1],[3,3,2]]
54 | P_all_old=[([0]*nt) for i in range(nu)]
55 | P_all_new=[([0]*nt) for i in range(nu)]
56 | B_old=[([i]*nt) for i in range(nu)]
57 | B_new=[([i]*nt) for i in range(nu)]
58 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
59 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
60 |
61 |
62 |
63 | # 程序主函数
64 | def BidingFirst(i):
65 | P=[0]*nt
66 | V={}
67 | nil=ni[i]
68 | nkicopy=deepcopy(nki)
69 | for j in range(nt):
70 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
71 | #print(V)
72 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
73 | #print(V_order)
74 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
75 | #print(re_K)
76 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
77 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
78 |
79 | for j in range(nt):
80 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
81 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
82 | break
83 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
84 | #ni[i]-=1
85 | nkicopy[i][k_ord]-=1
86 | #re_J.add(V_order[j][0])
87 | re_K[k_ord].add(V_order[j][0])
88 | else:
89 | if V_order[j][1]>0 and k_flag[k_ord]==0:
90 | k_secondprice[k_ord]=V_order[j][1]
91 | k_flag[k_ord]=1
92 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
93 | k_secondprice[k_ord]=0
94 | k_flag[k_ord]=1
95 | # print(nki[i])
96 | # print(k_flag)
97 | #print(k_secondprice)
98 | # print(re_K)
99 | #print(re_J)
100 | kchose_set=set() #用于记录投标全集
101 | for k in range(ns):
102 | kchose_set=kchose_set|re_K[k]
103 | C={}
104 | cnt=0
105 | for j in kchose_set:
106 | C[j]=V[j]
107 | cnt+=1
108 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
109 | #print(C_order)
110 | #print(cnt)
111 | #print(kchose_set)
112 |
113 | re_J=set([])
114 | for j in range(cnt):
115 | if nil<=0: #若超过载核限制则退出
116 | break
117 | nil-=1
118 | re_J.add(C_order[j][0])
119 | #print(j,nil)
120 | #print(re_J)
121 | #储存载核的次优价格
122 | if ni[i]>=cnt:
123 | secondprice=0
124 | else:
125 | secondprice=C_order[j][1]
126 | # for k in range(ns):
127 | # print(Kall_set[k]-re_K[k])
128 | #print(secondprice)
129 | #更新任务分配信息
130 | for j in re_J:
131 | J[i][j]=1
132 | B_new[i][j]=i
133 | #print(J[i])
134 | #更新价格
135 | for j in re_J:
136 | k_ord=K_dic[j]
137 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
138 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
139 | #print(P_all[i])
140 |
141 |
142 |
143 |
144 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
145 | for u in range(nu):
146 | if arcs[u][i]==1 or u==i:
147 | for j in range(nt):
148 | if P_all_old[u][j]>P_all_new[i][j]:
149 | P_all_new[i][j]=P_all_old[u][j]
150 | B_new[i][j]=B_old[u][j]
151 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
152 | B_new[i][j]=B_old[u][j]
153 | #nkicopy=deepcopy(nki)
154 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
155 | re=0 #需要重新投标数
156 | J_old=set()
157 | #print(J[i])
158 | for j in range(nt): #将列表转化为集合
159 | if J[i][j]==1:
160 | J_old.add(j)
161 | #print(J_old)
162 | for j in J_old.copy():
163 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
164 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
170 | k_ord=K_dic[j]
171 | re_Knum[k_ord]+=1
172 | #print(re_Knum)
173 | #print(J_old)
174 | new_Knum={} #每个分组需要补充的数量,使用字典表示
175 | secondnum=0 #记录有多少个组需要重新补充任务
176 | for k in range(ns):
177 | if nki[i][k]-re_Knum[k]!=0:
178 | new_Knum[k]=nki[i][k]-re_Knum[k]
179 | secondnum+=1
180 | #print(new_Knum)
181 | #print(secondnum)
182 | V={}
183 | #print(re)
184 | #print(J_old)
185 | #print(A[i])
186 | for j in range(nt):
187 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
188 | #print(V)
189 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
190 | #print(V_order)
191 | leftset=all_set-J_old #再余下的集合中将投标补至ni
192 | #print(leftset)
193 |
194 |
195 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
196 | #print(re_K)
197 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
198 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
199 | flagnum=0
200 | for j in range(nt):
201 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
202 | if new_Knum=={}:
203 | break
204 | jud = all(x == 0 for x in new_Knum.values())
205 | if jud and flagnum==secondnum: #
206 | break
207 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
208 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
209 | new_Knum[k_ord]-=1
210 | re_K[k_ord].add(V_order[j][0])
211 | else:
212 | if V_order[j][1]>0 and k_flag[k_ord]==0:
213 | k_secondprice[k_ord]=V_order[j][1]
214 | k_flag[k_ord]=1
215 | flagnum+=1
216 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
217 | k_secondprice[k_ord]=0
218 | k_flag[k_ord]=1
219 | flagnum+=1
220 | #print(re_K)
221 | #print(k_secondprice)
222 | # print()
223 |
224 | kchose_set=set() #用于记录投标全集
225 | for k in range(ns):
226 | kchose_set=kchose_set|re_K[k]
227 | C={}
228 | cnt=0
229 | for j in kchose_set:
230 | C[j]=V[j]
231 | cnt+=1
232 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
233 | #print(C_order)
234 | #print(cnt)
235 | #print(kchose_set)
236 |
237 | re_J=set([])
238 | for j in range(cnt):
239 | if re<=0: #若超过载核限制则退出
240 | break
241 | re-=1
242 | re_J.add(C_order[j][0])
243 | #print(re_J)
244 | #储存载核的次优价格
245 | if ni[i]>=cnt:
246 | secondprice=0
247 | else:
248 | secondprice=C_order[j][1]
249 | # for k in range(ns):
250 | # print(Kall_set[k]-re_K[k])
251 | #print(secondprice)
252 | #print()
253 | #更新任务分配信息
254 | for j in re_J:
255 | J[i][j]=1
256 | B_new[i][j]=i
257 | #print(J[i])
258 | #更新价格
259 | if re_J==set():
260 | Pchange[i]=0
261 | else:
262 | for j in re_J:
263 | k_ord=K_dic[j]
264 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
265 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
266 | Pchange[i]=1
267 |
268 | # print(P_all_new[i])
269 |
270 |
271 | start=time.time()
272 | for i in range(nu): #第一轮价格初始化
273 | BidingFirst(i)
274 | # for j in range(nt): #第一轮价格一致阶段
275 | # l=-1
276 | # m=-1
277 | # for i in range(nu):#在此方法中序号越高的无人机优先级越高
278 | # if P_all[i][j]==0 and P[j]==0:
279 | # continue
280 | # elif P_all[i][j]>=P[j] :
281 | # P[j]=P_all[i][j]
282 | # l=i
283 | # m=j
284 | # if l!=-1 and m!=-1:
285 | # pri[l][m]=1
286 | # print(0)
287 | # print(P_all_old)
288 | # print(P)
289 | # print(J)
290 |
291 | # BidingPhase(0)
292 | # BidingPhase(1)
293 | # BidingPhase(2)
294 |
295 |
296 | n=0
297 | lcr=0 #least communication rounds停止需要的最少轮次
298 | while(1):
299 | for i in range(nu):
300 | BidingPhase(i)
301 | B_old=deepcopy(B_new)
302 | P_all_old=deepcopy(P_all_new)
303 | # for i in range(nu):
304 | # for j in range(nt):
305 | # P_all_old[i][j]=P_all_new[i][j]
306 | # print(P_all_old)
307 | # print(P_all_new)
308 | #print(pri)
309 | # pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
310 | # for j in range(nt):
311 | # l=-1
312 | # m=-1
313 | # for i in range(nu):
314 | # if P_all[i][j]==0 and P[j]==0:
315 | # continue
316 | # elif P_all[i][j]>=P[j] :
317 | # P[j]=P_all[i][j]
318 | # l=i
319 | # m=j
320 | # if l!=-1 and m!=-1:
321 | # pri[l][m]=1
322 | n+=1
323 | # print(n)
324 | # print(P_all)
325 | # print(P)
326 | # print(J)
327 | if Pchange==[0]*nu:
328 | lcr+=1
329 | if lcr==netdiameter:
330 | break
331 | else:
332 | lcr=0
333 |
334 | end=time.time()
335 |
336 | # af=[i for i in range(nt)]
337 | # print(af)
338 | print("迭代次数%d"%n)
339 | sum=0
340 | for i in range(nu):
341 | print("无人机%d选择了目标"%i,end='')
342 | for j in range(nt):
343 | if J[i][j]==1:
344 | # af.remove(j)
345 | sum+=A[i][j]
346 | print("%d(%d),"%(j,K_dic[j]),end='')
347 | print('')
348 | print("总收益值为%d"%sum)
349 | # print(af)
350 | print(end-start)
351 |
--------------------------------------------------------------------------------
/src/Auction3_Distributeddraw.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | import networkx as nx
6 | import time
7 | from num import A_2060
8 | from num import A_40200
9 | from num import A_50500
10 | from graph import arcs_20
11 | from graph import arcs_40
12 | from graph import arcs_50
13 | from graph import arcs_line20
14 | from graph import arcs_random20
15 |
16 | x_minaddall=[]
17 | y_sumall=[]
18 | y_timeall=[]
19 | x_minaddline=[]
20 | y_sumline=[]
21 | y_timeline=[]
22 | x_minaddrandom=[]
23 | y_sumrandom=[]
24 | y_timerandom=[]
25 |
26 | cnt=0
27 | while(cnt<3):
28 | minadd=0.1 #定义最小增量
29 | while(minadd<20):
30 | #设置全局变量并初始化
31 | if cnt==0:
32 | arcs=arcs_20
33 | elif cnt==1:
34 | arcs=arcs_line20
35 | elif cnt==2:
36 | arcs=arcs_random20
37 | nu=20 #无人机数量
38 | nt=60 #任务量
39 |
40 | ns=4 #根据任务分成几组
41 | ni=[3]*nu #每个无人机最大可执行的任务,这里统一规定为3
42 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
43 | #print(nki)
44 | K_dic={}
45 | ave=int(nt/ns) #每个分组有多少个成员
46 | for i in range(nt):#建立任务和任务分组关系的字典
47 | K_dic[i]=int(i/ave)
48 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
49 | all_set=set([x for x in range(nt)]) #定义全集
50 | Kall_set=[] #定义分组的全集
51 | for i in range(ns):
52 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
53 |
54 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
55 | A=A_2060
56 | G=nx.Graph() # 新建一个无向图
57 | nodes=[]
58 | edges=[]
59 | for i in range(nu):
60 | G.add_node(i)
61 | for i in range(nu):
62 | for j in range(nu):
63 | if arcs[i][j]==1:
64 | G.add_edge(i,j)
65 | netdiameter=nx.diameter(G)
66 |
67 | #A=[[3, 17, 1, 19, 18, 17, 13, 20, 3], [5, 8, 5, 3, 8, 14, 16, 1, 6], [17, 17, 10, 9, 2, 13, 0, 2, 20]]
68 | # A=[[11,18,11,18,33,4],[4,34 ,33 ,32 ,26 ,23],[3 ,0 ,27 ,24 ,14 ,9],[25 ,15 ,25 ,23 ,7 ,26],[30 ,18 ,34 ,20 ,17 ,29],[5 ,35 ,34 ,4 ,17 ,28]]
69 | #A=[[4,2,0],[1,3,1],[3,3,2]]
70 | P_all_old=[([0]*nt) for i in range(nu)]
71 | P_all_new=[([0]*nt) for i in range(nu)]
72 | B_old=[([i]*nt) for i in range(nu)]
73 | B_new=[([i]*nt) for i in range(nu)]
74 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
75 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
76 |
77 |
78 |
79 | # 程序主函数
80 | def BidingFirst(i):
81 | P=[0]*nt
82 | V={}
83 | nil=ni[i]
84 | nkicopy=deepcopy(nki)
85 | for j in range(nt):
86 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
87 | #print(V)
88 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
89 | #print(V_order)
90 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
91 | #print(re_K)
92 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
93 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
94 |
95 | for j in range(nt):
96 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
97 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
98 | break
99 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
100 | #ni[i]-=1
101 | nkicopy[i][k_ord]-=1
102 | #re_J.add(V_order[j][0])
103 | re_K[k_ord].add(V_order[j][0])
104 | else:
105 | if V_order[j][1]>0 and k_flag[k_ord]==0:
106 | k_secondprice[k_ord]=V_order[j][1]
107 | k_flag[k_ord]=1
108 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
109 | k_secondprice[k_ord]=0
110 | k_flag[k_ord]=1
111 | # print(nki[i])
112 | # print(k_flag)
113 | #print(k_secondprice)
114 | # print(re_K)
115 | #print(re_J)
116 | kchose_set=set() #用于记录投标全集
117 | for k in range(ns):
118 | kchose_set=kchose_set|re_K[k]
119 | C={}
120 | cnt=0
121 | for j in kchose_set:
122 | C[j]=V[j]
123 | cnt+=1
124 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
125 | #print(C_order)
126 | #print(cnt)
127 | #print(kchose_set)
128 |
129 | re_J=set([])
130 | for j in range(cnt):
131 | if nil<=0: #若超过载核限制则退出
132 | break
133 | nil-=1
134 | re_J.add(C_order[j][0])
135 | #print(j,nil)
136 | #print(re_J)
137 | #储存载核的次优价格
138 | if ni[i]>=cnt:
139 | secondprice=0
140 | else:
141 | secondprice=C_order[j][1]
142 | # for k in range(ns):
143 | # print(Kall_set[k]-re_K[k])
144 | #print(secondprice)
145 | #更新任务分配信息
146 | for j in re_J:
147 | J[i][j]=1
148 | B_new[i][j]=i
149 | #print(J[i])
150 | #更新价格
151 | for j in re_J:
152 | k_ord=K_dic[j]
153 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
154 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
155 | #print(P_all[i])
156 |
157 |
158 |
159 |
160 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
161 | for u in range(nu):
162 | if arcs[u][i]==1 or u==i:
163 | for j in range(nt):
164 | if P_all_old[u][j]>P_all_new[i][j]:
165 | P_all_new[i][j]=P_all_old[u][j]
166 | B_new[i][j]=B_old[u][j]
167 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
168 | B_new[i][j]=B_old[u][j]
169 | #nkicopy=deepcopy(nki)
170 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
171 | re=0 #需要重新投标数
172 | J_old=set()
173 | #print(J[i])
174 | for j in range(nt): #将列表转化为集合
175 | if J[i][j]==1:
176 | J_old.add(j)
177 | #print(J_old)
178 | for j in J_old.copy():
179 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
180 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
186 | k_ord=K_dic[j]
187 | re_Knum[k_ord]+=1
188 | #print(re_Knum)
189 | #print(J_old)
190 | new_Knum={} #每个分组需要补充的数量,使用字典表示
191 | secondnum=0 #记录有多少个组需要重新补充任务
192 | for k in range(ns):
193 | if nki[i][k]-re_Knum[k]!=0:
194 | new_Knum[k]=nki[i][k]-re_Knum[k]
195 | secondnum+=1
196 | #print(new_Knum)
197 | #print(secondnum)
198 | V={}
199 | #print(re)
200 | #print(J_old)
201 | #print(A[i])
202 | for j in range(nt):
203 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
204 | #print(V)
205 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
206 | #print(V_order)
207 | leftset=all_set-J_old #再余下的集合中将投标补至ni
208 | #print(leftset)
209 |
210 |
211 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
212 | #print(re_K)
213 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
214 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
215 | flagnum=0
216 | for j in range(nt):
217 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
218 | if new_Knum=={}:
219 | break
220 | jud = all(x == 0 for x in new_Knum.values())
221 | if jud and flagnum==secondnum: #
222 | break
223 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
224 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
225 | new_Knum[k_ord]-=1
226 | re_K[k_ord].add(V_order[j][0])
227 | else:
228 | if V_order[j][1]>0 and k_flag[k_ord]==0:
229 | k_secondprice[k_ord]=V_order[j][1]
230 | k_flag[k_ord]=1
231 | flagnum+=1
232 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
233 | k_secondprice[k_ord]=0
234 | k_flag[k_ord]=1
235 | flagnum+=1
236 | #print(re_K)
237 | #print(k_secondprice)
238 | # print()
239 |
240 | kchose_set=set() #用于记录投标全集
241 | for k in range(ns):
242 | kchose_set=kchose_set|re_K[k]
243 | C={}
244 | cnt=0
245 | for j in kchose_set:
246 | C[j]=V[j]
247 | cnt+=1
248 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
249 | #print(C_order)
250 | #print(cnt)
251 | #print(kchose_set)
252 |
253 | re_J=set([])
254 | for j in range(cnt):
255 | if re<=0: #若超过载核限制则退出
256 | break
257 | re-=1
258 | re_J.add(C_order[j][0])
259 | #print(re_J)
260 | #储存载核的次优价格
261 | if ni[i]>=cnt:
262 | secondprice=0
263 | else:
264 | secondprice=C_order[j][1]
265 | # for k in range(ns):
266 | # print(Kall_set[k]-re_K[k])
267 | #print(secondprice)
268 | #print()
269 | #更新任务分配信息
270 | for j in re_J:
271 | J[i][j]=1
272 | B_new[i][j]=i
273 | #print(J[i])
274 | #更新价格
275 | if re_J==set():
276 | Pchange[i]=0
277 | else:
278 | for j in re_J:
279 | k_ord=K_dic[j]
280 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
281 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
282 | Pchange[i]=1
283 |
284 | # print(P_all_new[i])
285 |
286 | start=time.time()
287 |
288 | for i in range(nu): #第一轮价格初始化
289 | BidingFirst(i)
290 | # for j in range(nt): #第一轮价格一致阶段
291 | # l=-1
292 | # m=-1
293 | # for i in range(nu):#在此方法中序号越高的无人机优先级越高
294 | # if P_all[i][j]==0 and P[j]==0:
295 | # continue
296 | # elif P_all[i][j]>=P[j] :
297 | # P[j]=P_all[i][j]
298 | # l=i
299 | # m=j
300 | # if l!=-1 and m!=-1:
301 | # pri[l][m]=1
302 | # print(0)
303 | # print(P_all_old)
304 | # print(P)
305 | # print(J)
306 |
307 | # BidingPhase(0)
308 | # BidingPhase(1)
309 | # BidingPhase(2)
310 |
311 |
312 | n=0
313 | lcr=0 #least communication rounds停止需要的最少轮次
314 | while(1):
315 | for i in range(nu):
316 | BidingPhase(i)
317 | B_old=deepcopy(B_new)
318 | P_all_old=deepcopy(P_all_new)
319 | # for i in range(nu):
320 | # for j in range(nt):
321 | # P_all_old[i][j]=P_all_new[i][j]
322 | # print(P_all_old)
323 | # print(P_all_new)
324 | #print(pri)
325 | # pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
326 | # for j in range(nt):
327 | # l=-1
328 | # m=-1
329 | # for i in range(nu):
330 | # if P_all[i][j]==0 and P[j]==0:
331 | # continue
332 | # elif P_all[i][j]>=P[j] :
333 | # P[j]=P_all[i][j]
334 | # l=i
335 | # m=j
336 | # if l!=-1 and m!=-1:
337 | # pri[l][m]=1
338 | n+=1
339 | # print(n)
340 | # print(P_all)
341 | # print(P)
342 | # print(J)
343 | if Pchange==[0]*nu:
344 | lcr+=1
345 | if lcr==netdiameter:
346 | break
347 | else:
348 | lcr=0
349 |
350 | end=time.time()
351 |
352 | # af=[i for i in range(nt)]
353 | # print(af)
354 | # print("迭代次数%d"%n)
355 | sum=0
356 | for i in range(nu):
357 | # print("无人机%d选择了目标"%i,end='')
358 | for j in range(nt):
359 | if J[i][j]==1:
360 | # af.remove(j)
361 | sum+=A[i][j]
362 | #print("%d(%d),"%(j,K_dic[j]),end='')
363 | # print('')
364 | # print("总收益值为%d"%sum)
365 | # print(af)
366 | if cnt==0:
367 | x_minaddall.append(minadd)
368 | y_sumall.append(sum)
369 | y_timeall.append(end-start)
370 | elif cnt==1:
371 | x_minaddline.append(minadd)
372 | y_sumline.append(sum)
373 | y_timeline.append(end-start)
374 | elif cnt==2:
375 | x_minaddrandom.append(minadd)
376 | y_sumrandom.append(sum)
377 | y_timerandom.append(end-start)
378 | minadd+=0.1
379 | cnt+=1
380 |
381 |
382 | plt.plot(x_minaddall,y_timeall, linewidth=1,c='red',label="all")
383 | plt.plot(x_minaddline,y_timeline, linewidth=1,c='yellow',label='line')
384 | plt.plot(x_minaddrandom,y_timerandom, linewidth=1,c='blue',label='random')
385 | plt.legend()
386 | plt.show()
--------------------------------------------------------------------------------
/src/Auction3_Distributeddraw_n.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | from ortools.linear_solver import pywraplp
6 | import networkx as nx
7 | import time
8 | import numpy as np
9 | from num import A_2060
10 | from num import A_40200
11 | from num import A_50500
12 | from graph import arcs_20
13 | from graph import arcs_40
14 | from graph import arcs_50
15 | from graph import arcs_line20
16 | from graph import arcs_random20
17 |
18 | x_scaleall=[]
19 | y_sumall=[]
20 | y_timeall=[]
21 | x_scaleline=[]
22 | y_sumline=[]
23 | y_timeline=[]
24 | x_scalerandom=[]
25 | y_sumrandom=[]
26 | y_timerandom=[]
27 |
28 | x_n=[]
29 | y_sum=[]
30 |
31 | scale_n=10
32 | minadd=0.1#定义最小增量
33 | while(scale_n<=100):
34 | cnt=0
35 | nu=scale_n #无人机数量
36 | nt=scale_n #任务量
37 |
38 | ns=scale_n #根据任务分成几组
39 | ni=[1]*nu #每个无人机最大可执行的任务,这里统一规定为3
40 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
41 |
42 |
43 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
44 | for i in range(nu):
45 | for j in range(nt):
46 | A[i][j]=random.uniform(0,20) #生成0-20内的随机数作为收益 randint(0,20)
47 | #A=A_2060
48 |
49 | def main(nu):
50 | # Data
51 | # costs = [
52 | # [90, 80, 75, 70],
53 | # [35, 85, 55, 65],
54 | # [125, 95, 90, 95],
55 | # [45, 110, 95, 115],
56 | # [50, 100, 90, 100],
57 | # ]
58 | costs=A
59 | num_workers = len(costs)
60 | num_tasks = len(costs[0])
61 |
62 | # Solver
63 | # Create the mip solver with the SCIP backend.
64 | solver = pywraplp.Solver.CreateSolver('SCIP')
65 |
66 | if not solver:
67 | return
68 |
69 | # Variables
70 | # x[i, j] is an array of 0-1 variables, which will be 1
71 | # if worker i is assigned to task j.
72 | x = {}
73 | for i in range(num_workers):
74 | for j in range(num_tasks):
75 | x[i, j] = solver.IntVar(0, 1, '')
76 |
77 | # Constraints
78 | # Each worker is assigned to at most 1 task.
79 | for i in range(num_workers):
80 | solver.Add(solver.Sum([x[i, j] for j in range(num_tasks)]) <= 1)
81 |
82 | # Each task is assigned to exactly one worker.
83 | for j in range(num_tasks):
84 | solver.Add(solver.Sum([x[i, j] for i in range(num_workers)]) == 1)
85 |
86 | # Objective
87 | objective_terms = []
88 | for i in range(num_workers):
89 | for j in range(num_tasks):
90 | objective_terms.append(costs[i][j] * x[i, j])
91 | solver.Maximize(solver.Sum(objective_terms))
92 |
93 | # Solve
94 | status = solver.Solve()
95 |
96 | # # Print solution.
97 | # if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE:
98 | # print(f'Total cost = {solver.Objective().Value()}\n')
99 | # for i in range(num_workers):
100 | # for j in range(num_tasks):
101 | # # Test if x[i,j] is 1 (with tolerance for floating point arithmetic).
102 | # if x[i, j].solution_value() > 0.5:
103 | # print(f'Worker {i} assigned to task {j}.' +
104 | # f' Cost: {costs[i][j]}')
105 | # else:
106 | # print('No solution found.')
107 | x_n.append(scale_n)
108 | y_sum.append(solver.Objective().Value())
109 | main(scale_n)
110 | while(cnt<3):
111 | #设置全局变量并初始化
112 | if cnt==0:#完全图
113 | arcs=[([0]*nu) for i in range(nu)]
114 | for i in range(nu):
115 | for j in range(nu):
116 | if i0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
185 | #ni[i]-=1
186 | nkicopy[i][k_ord]-=1
187 | #re_J.add(V_order[j][0])
188 | re_K[k_ord].add(V_order[j][0])
189 | else:
190 | if V_order[j][1]>0 and k_flag[k_ord]==0:
191 | k_secondprice[k_ord]=V_order[j][1]
192 | k_flag[k_ord]=1
193 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
194 | k_secondprice[k_ord]=0
195 | k_flag[k_ord]=1
196 | # print(nki[i])
197 | # print(k_flag)
198 | #print(k_secondprice)
199 | # print(re_K)
200 | #print(re_J)
201 | kchose_set=set() #用于记录投标全集
202 | for k in range(ns):
203 | kchose_set=kchose_set|re_K[k]
204 | C={}
205 | cnt=0
206 | for j in kchose_set:
207 | C[j]=V[j]
208 | cnt+=1
209 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
210 | #print(C_order)
211 | #print(cnt)
212 | #print(kchose_set)
213 |
214 | re_J=set([])
215 | for j in range(cnt):
216 | if nil<=0: #若超过载核限制则退出
217 | break
218 | nil-=1
219 | re_J.add(C_order[j][0])
220 | #print(j,nil)
221 | #print(re_J)
222 | #储存载核的次优价格
223 | if ni[i]>=cnt:
224 | secondprice=0
225 | else:
226 | secondprice=C_order[j][1]
227 | # for k in range(ns):
228 | # print(Kall_set[k]-re_K[k])
229 | #print(secondprice)
230 | #更新任务分配信息
231 | for j in re_J:
232 | J[i][j]=1
233 | B_new[i][j]=i
234 | #print(J[i])
235 | #更新价格
236 | for j in re_J:
237 | k_ord=K_dic[j]
238 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
239 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
240 | #print(P_all[i])
241 |
242 |
243 |
244 |
245 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
246 | for u in range(nu):
247 | if arcs[u][i]==1 or u==i:
248 | for j in range(nt):
249 | if P_all_old[u][j]>P_all_new[i][j]:
250 | P_all_new[i][j]=P_all_old[u][j]
251 | B_new[i][j]=B_old[u][j]
252 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
253 | B_new[i][j]=B_old[u][j]
254 | #nkicopy=deepcopy(nki)
255 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
256 | re=0 #需要重新投标数
257 | J_old=set()
258 | #print(J[i])
259 | for j in range(nt): #将列表转化为集合
260 | if J[i][j]==1:
261 | J_old.add(j)
262 | #print(J_old)
263 | for j in J_old.copy():
264 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
265 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
271 | k_ord=K_dic[j]
272 | re_Knum[k_ord]+=1
273 | #print(re_Knum)
274 | #print(J_old)
275 | new_Knum={} #每个分组需要补充的数量,使用字典表示
276 | secondnum=0 #记录有多少个组需要重新补充任务
277 | for k in range(ns):
278 | if nki[i][k]-re_Knum[k]!=0:
279 | new_Knum[k]=nki[i][k]-re_Knum[k]
280 | secondnum+=1
281 | #print(new_Knum)
282 | #print(secondnum)
283 | V={}
284 | #print(re)
285 | #print(J_old)
286 | #print(A[i])
287 | for j in range(nt):
288 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
289 | #print(V)
290 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
291 | #print(V_order)
292 | leftset=all_set-J_old #再余下的集合中将投标补至ni
293 | #print(leftset)
294 |
295 |
296 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
297 | #print(re_K)
298 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
299 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
300 | flagnum=0
301 | for j in range(nt):
302 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
303 | if new_Knum=={}:
304 | break
305 | jud = all(x == 0 for x in new_Knum.values())
306 | if jud and flagnum==secondnum: #
307 | break
308 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
309 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
310 | new_Knum[k_ord]-=1
311 | re_K[k_ord].add(V_order[j][0])
312 | else:
313 | if V_order[j][1]>0 and k_flag[k_ord]==0:
314 | k_secondprice[k_ord]=V_order[j][1]
315 | k_flag[k_ord]=1
316 | flagnum+=1
317 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
318 | k_secondprice[k_ord]=0
319 | k_flag[k_ord]=1
320 | flagnum+=1
321 | #print(re_K)
322 | #print(k_secondprice)
323 | # print()
324 |
325 | kchose_set=set() #用于记录投标全集
326 | for k in range(ns):
327 | kchose_set=kchose_set|re_K[k]
328 | C={}
329 | cnt=0
330 | for j in kchose_set:
331 | C[j]=V[j]
332 | cnt+=1
333 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
334 | #print(C_order)
335 | #print(cnt)
336 | #print(kchose_set)
337 |
338 | re_J=set([])
339 | for j in range(cnt):
340 | if re<=0: #若超过载核限制则退出
341 | break
342 | re-=1
343 | re_J.add(C_order[j][0])
344 | #print(re_J)
345 | #储存载核的次优价格
346 | if ni[i]>=cnt:
347 | secondprice=0
348 | else:
349 | secondprice=C_order[j][1]
350 | # for k in range(ns):
351 | # print(Kall_set[k]-re_K[k])
352 | #print(secondprice)
353 | #print()
354 | #更新任务分配信息
355 | for j in re_J:
356 | J[i][j]=1
357 | B_new[i][j]=i
358 | #print(J[i])
359 | #更新价格
360 | if re_J==set():
361 | Pchange[i]=0
362 | else:
363 | for j in re_J:
364 | k_ord=K_dic[j]
365 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
366 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
367 | Pchange[i]=1
368 |
369 | # print(P_all_new[i])
370 |
371 |
372 |
373 | for i in range(nu): #第一轮价格初始化
374 | BidingFirst(i)
375 |
376 |
377 | n=0
378 | lcr=0 #least communication rounds停止需要的最少轮次
379 | while(1):
380 | for i in range(nu):
381 | BidingPhase(i)
382 | B_old=deepcopy(B_new)
383 | P_all_old=deepcopy(P_all_new)
384 |
385 | n+=1
386 | # print(n)
387 | # print(P_all)
388 | # print(P)
389 | # print(J)
390 | if Pchange==[0]*nu:
391 | lcr+=1
392 | if lcr==netdiameter:
393 | break
394 | else:
395 | lcr=0
396 |
397 |
398 | # af=[i for i in range(nt)]
399 | # print(af)
400 | # print("迭代次数%d"%n)
401 | sum=0
402 | for i in range(nu):
403 | # print("无人机%d选择了目标"%i,end='')
404 | for j in range(nt):
405 | if J[i][j]==1:
406 | # af.remove(j)
407 | sum+=A[i][j]
408 | #print("%d(%d),"%(j,K_dic[j]),end='')
409 | # print('')
410 | print("总收益值为%d"%sum)
411 | # print(af)
412 | if cnt==0:
413 | x_scaleall.append(scale_n)
414 | y_sumall.append(sum)
415 | #y_timeall.append(end-start)
416 | elif cnt==1:
417 | x_scaleline.append(scale_n)
418 | y_sumline.append(sum)
419 | #y_timeline.append(end-start)
420 | elif cnt==2:
421 | x_scalerandom.append(scale_n)
422 | y_sumrandom.append(sum)
423 | #y_timerandom.append(end-start)
424 | cnt+=1
425 | scale_n+=10
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 | y_sumall=list(np.array(y_sum)-np.array(y_sumall))
436 | y_sumline=list(np.array(y_sum)-np.array(y_sumline))
437 | y_sumrandom=list(np.array(y_sum)-np.array(y_sumrandom))
438 |
439 | plt.plot(x_scaleall,y_sumall, linewidth=1,c='red',label="all")
440 | plt.plot(x_scaleline,y_sumline, linewidth=1,c='black',label='line')
441 | plt.plot(x_scalerandom,y_sumrandom, linewidth=1,c='blue',label='random')
442 | plt.legend()
443 | plt.xlabel('Number of drones')
444 | plt.ylabel('Sum(subtracted)')
445 | plt.show()
--------------------------------------------------------------------------------
/src/Auction3_Distributeddraw_time.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | from ortools.linear_solver import pywraplp
6 | import networkx as nx
7 | import time
8 | import numpy as np
9 | from num import A_2060
10 | from num import A_40200
11 | from num import A_50500
12 | from graph import arcs_20
13 | from graph import arcs_40
14 | from graph import arcs_50
15 | from graph import arcs_line20
16 | from graph import arcs_random20
17 |
18 | x_scaleall=[]
19 | y_sumall=[]
20 | y_timeall=[]
21 | x_scaleline=[]
22 | y_sumline=[]
23 | y_timeline=[]
24 | x_scalerandom=[]
25 | y_sumrandom=[]
26 | y_timerandom=[]
27 |
28 |
29 |
30 | scale_n=10
31 | minadd=1 #定义最小增量
32 | while(scale_n<=100):
33 | cnt=0
34 | nu=scale_n #无人机数量
35 | nt=scale_n #任务量
36 |
37 | ns=scale_n #根据任务分成几组
38 | ni=[1]*nu #每个无人机最大可执行的任务,这里统一规定为3
39 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
40 |
41 |
42 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
43 | for i in range(nu):
44 | for j in range(nt):
45 | A[i][j]=random.uniform(0,20) #生成0-20内的随机数作为收益randint(0,20)
46 | #A=A_2060
47 |
48 |
49 | while(cnt<3):
50 | #设置全局变量并初始化
51 | if cnt==0:#完全图
52 | arcs=[([0]*nu) for i in range(nu)]
53 | for i in range(nu):
54 | for j in range(nu):
55 | if i0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
124 | #ni[i]-=1
125 | nkicopy[i][k_ord]-=1
126 | #re_J.add(V_order[j][0])
127 | re_K[k_ord].add(V_order[j][0])
128 | else:
129 | if V_order[j][1]>0 and k_flag[k_ord]==0:
130 | k_secondprice[k_ord]=V_order[j][1]
131 | k_flag[k_ord]=1
132 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
133 | k_secondprice[k_ord]=0
134 | k_flag[k_ord]=1
135 | # print(nki[i])
136 | # print(k_flag)
137 | #print(k_secondprice)
138 | # print(re_K)
139 | #print(re_J)
140 | kchose_set=set() #用于记录投标全集
141 | for k in range(ns):
142 | kchose_set=kchose_set|re_K[k]
143 | C={}
144 | cnt=0
145 | for j in kchose_set:
146 | C[j]=V[j]
147 | cnt+=1
148 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
149 | #print(C_order)
150 | #print(cnt)
151 | #print(kchose_set)
152 |
153 | re_J=set([])
154 | for j in range(cnt):
155 | if nil<=0: #若超过载核限制则退出
156 | break
157 | nil-=1
158 | re_J.add(C_order[j][0])
159 | #print(j,nil)
160 | #print(re_J)
161 | #储存载核的次优价格
162 | if ni[i]>=cnt:
163 | secondprice=0
164 | else:
165 | secondprice=C_order[j][1]
166 | # for k in range(ns):
167 | # print(Kall_set[k]-re_K[k])
168 | #print(secondprice)
169 | #更新任务分配信息
170 | for j in re_J:
171 | J[i][j]=1
172 | B_new[i][j]=i
173 | #print(J[i])
174 | #更新价格
175 | for j in re_J:
176 | k_ord=K_dic[j]
177 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
178 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
179 | #print(P_all[i])
180 |
181 |
182 |
183 |
184 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
185 | for u in range(nu):
186 | if arcs[u][i]==1 or u==i:
187 | for j in range(nt):
188 | if P_all_old[u][j]>P_all_new[i][j]:
189 | P_all_new[i][j]=P_all_old[u][j]
190 | B_new[i][j]=B_old[u][j]
191 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
192 | B_new[i][j]=B_old[u][j]
193 | #nkicopy=deepcopy(nki)
194 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
195 | re=0 #需要重新投标数
196 | J_old=set()
197 | #print(J[i])
198 | for j in range(nt): #将列表转化为集合
199 | if J[i][j]==1:
200 | J_old.add(j)
201 | #print(J_old)
202 | for j in J_old.copy():
203 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
204 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
210 | k_ord=K_dic[j]
211 | re_Knum[k_ord]+=1
212 | #print(re_Knum)
213 | #print(J_old)
214 | new_Knum={} #每个分组需要补充的数量,使用字典表示
215 | secondnum=0 #记录有多少个组需要重新补充任务
216 | for k in range(ns):
217 | if nki[i][k]-re_Knum[k]!=0:
218 | new_Knum[k]=nki[i][k]-re_Knum[k]
219 | secondnum+=1
220 | #print(new_Knum)
221 | #print(secondnum)
222 | V={}
223 | #print(re)
224 | #print(J_old)
225 | #print(A[i])
226 | for j in range(nt):
227 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
228 | #print(V)
229 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
230 | #print(V_order)
231 | leftset=all_set-J_old #再余下的集合中将投标补至ni
232 | #print(leftset)
233 |
234 |
235 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
236 | #print(re_K)
237 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
238 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
239 | flagnum=0
240 | for j in range(nt):
241 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
242 | if new_Knum=={}:
243 | break
244 | jud = all(x == 0 for x in new_Knum.values())
245 | if jud and flagnum==secondnum: #
246 | break
247 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
248 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
249 | new_Knum[k_ord]-=1
250 | re_K[k_ord].add(V_order[j][0])
251 | else:
252 | if V_order[j][1]>0 and k_flag[k_ord]==0:
253 | k_secondprice[k_ord]=V_order[j][1]
254 | k_flag[k_ord]=1
255 | flagnum+=1
256 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
257 | k_secondprice[k_ord]=0
258 | k_flag[k_ord]=1
259 | flagnum+=1
260 | #print(re_K)
261 | #print(k_secondprice)
262 | # print()
263 |
264 | kchose_set=set() #用于记录投标全集
265 | for k in range(ns):
266 | kchose_set=kchose_set|re_K[k]
267 | C={}
268 | cnt=0
269 | for j in kchose_set:
270 | C[j]=V[j]
271 | cnt+=1
272 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
273 | #print(C_order)
274 | #print(cnt)
275 | #print(kchose_set)
276 |
277 | re_J=set([])
278 | for j in range(cnt):
279 | if re<=0: #若超过载核限制则退出
280 | break
281 | re-=1
282 | re_J.add(C_order[j][0])
283 | #print(re_J)
284 | #储存载核的次优价格
285 | if ni[i]>=cnt:
286 | secondprice=0
287 | else:
288 | secondprice=C_order[j][1]
289 | # for k in range(ns):
290 | # print(Kall_set[k]-re_K[k])
291 | #print(secondprice)
292 | #print()
293 | #更新任务分配信息
294 | for j in re_J:
295 | J[i][j]=1
296 | B_new[i][j]=i
297 | #print(J[i])
298 | #更新价格
299 | if re_J==set():
300 | Pchange[i]=0
301 | else:
302 | for j in re_J:
303 | k_ord=K_dic[j]
304 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
305 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
306 | Pchange[i]=1
307 |
308 | # print(P_all_new[i])
309 |
310 |
311 | start=time.time()
312 |
313 | for i in range(nu): #第一轮价格初始化
314 | BidingFirst(i)
315 | # for j in range(nt): #第一轮价格一致阶段
316 | # l=-1
317 | # m=-1
318 | # for i in range(nu):#在此方法中序号越高的无人机优先级越高
319 | # if P_all[i][j]==0 and P[j]==0:
320 | # continue
321 | # elif P_all[i][j]>=P[j] :
322 | # P[j]=P_all[i][j]
323 | # l=i
324 | # m=j
325 | # if l!=-1 and m!=-1:
326 | # pri[l][m]=1
327 | # print(0)
328 | # print(P_all_old)
329 | # print(P)
330 | # print(J)
331 |
332 | # BidingPhase(0)
333 | # BidingPhase(1)
334 | # BidingPhase(2)
335 |
336 |
337 | n=0
338 | lcr=0 #least communication rounds停止需要的最少轮次
339 | while(1):
340 | for i in range(nu):
341 | BidingPhase(i)
342 | B_old=deepcopy(B_new)
343 | P_all_old=deepcopy(P_all_new)
344 | # for i in range(nu):
345 | # for j in range(nt):
346 | # P_all_old[i][j]=P_all_new[i][j]
347 | # print(P_all_old)
348 | # print(P_all_new)
349 | #print(pri)
350 | # pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
351 | # for j in range(nt):
352 | # l=-1
353 | # m=-1
354 | # for i in range(nu):
355 | # if P_all[i][j]==0 and P[j]==0:
356 | # continue
357 | # elif P_all[i][j]>=P[j] :
358 | # P[j]=P_all[i][j]
359 | # l=i
360 | # m=j
361 | # if l!=-1 and m!=-1:
362 | # pri[l][m]=1
363 | n+=1
364 | # print(n)
365 | # print(P_all)
366 | # print(P)
367 | # print(J)
368 | if Pchange==[0]*nu:
369 | lcr+=1
370 | if lcr==netdiameter:
371 | break
372 | else:
373 | lcr=0
374 |
375 | end=time.time()
376 |
377 | # af=[i for i in range(nt)]
378 | # print(af)
379 | # print("迭代次数%d"%n)
380 | sum=0
381 | for i in range(nu):
382 | # print("无人机%d选择了目标"%i,end='')
383 | for j in range(nt):
384 | if J[i][j]==1:
385 | # af.remove(j)
386 | sum+=A[i][j]
387 | #print("%d(%d),"%(j,K_dic[j]),end='')
388 | # print('')
389 | print("总收益值为%d"%sum)
390 | # print(af)
391 | if cnt==0:
392 | x_scaleall.append(scale_n)
393 | y_sumall.append(sum)
394 | y_timeall.append(end-start)
395 | elif cnt==1:
396 | x_scaleline.append(scale_n)
397 | y_sumline.append(sum)
398 | y_timeline.append(end-start)
399 | elif cnt==2:
400 | x_scalerandom.append(scale_n)
401 | y_sumrandom.append(sum)
402 | y_timerandom.append(end-start)
403 | cnt+=1
404 | scale_n+=2
405 |
406 |
407 |
408 | plt.plot(x_scaleall,y_timeall, linewidth=1,c='red',label="all")
409 | plt.plot(x_scaleline,y_timeline, linewidth=1,c='black',label='line')
410 | plt.plot(x_scalerandom,y_timerandom, linewidth=1,c='blue',label='random')
411 | plt.legend()
412 | plt.xlabel('Number of drones')
413 | #plt.ylabel('Sum')
414 | plt.ylabel('Second')
415 | plt.show()
--------------------------------------------------------------------------------
/src/Auction4_Federated.py:
--------------------------------------------------------------------------------
1 | import random
2 | import matplotlib.pyplot as plt
3 | import networkx as nx
4 | import copy
5 | from copy import deepcopy
6 | import time
7 | from graph import arcs_5
8 | from num import A_2060
9 | from num import A_40200
10 | from num import A_50500
11 |
12 |
13 | #设置全局变量并初始化
14 |
15 | nu=50 #无人机数量
16 | nt=500#任务量
17 | nf=5 #联邦数量
18 | minadd=1 #定义最小增量
19 | ns=20 #根据任务分成几组
20 | ni=[10]*nu #每个无人机最大可执行的任务,这里统一规定为3
21 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
22 | #print(nki)
23 | K_dic={} #分组对应字典
24 | avek=int(nt/ns) #每个分组有多少个成员
25 | for i in range(nt):#建立任务和任务分组关系的字典
26 | K_dic[i]=int(i/avek)
27 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
28 | all_set=set([x for x in range(nt)]) #定义全集
29 | Kall_set=[] #定义分组的全集
30 | for i in range(ns):
31 | Kall_set.append(set([x for x in range(i*avek,(i+1)*avek)]))
32 |
33 | F_dic={}
34 | avef=int(nu/nf) #每个联邦有多少个成员
35 | for i in range(nu):#建立无人机和联邦号的对应字典
36 | F_dic[i]=int(i/avef)
37 |
38 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
39 | A=A_50500
40 | arcs_f=arcs_5
41 | # arcs_f=[([0]*nf) for i in range(nf)]
42 | # #cnt=0
43 | # for i in range(nf):
44 | # for j in range(nf):
45 | # if i0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
90 | #ni[i]-=1
91 | nkicopy[i][k_ord]-=1
92 | #re_J.add(V_order[j][0])
93 | re_K[k_ord].add(V_order[j][0])
94 | else:
95 | if V_order[j][1]>0 and k_flag[k_ord]==0:
96 | k_secondprice[k_ord]=V_order[j][1]
97 | k_flag[k_ord]=1
98 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
99 | k_secondprice[k_ord]=0
100 | k_flag[k_ord]=1
101 | # print(nki[i])
102 | # print(k_flag)
103 | #print(k_secondprice)
104 | # print(re_K)
105 | #print(re_J)
106 | kchose_set=set() #用于记录投标全集
107 | for k in range(ns):
108 | kchose_set=kchose_set|re_K[k]
109 | C={}
110 | cnt=0
111 | for j in kchose_set:
112 | C[j]=V[j]
113 | cnt+=1
114 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
115 | #print(C_order)
116 | #print(cnt)
117 | #print(kchose_set)
118 |
119 | re_J=set([])
120 | for j in range(cnt):
121 | if nil<=0: #若超过载核限制则退出
122 | break
123 | nil-=1
124 | re_J.add(C_order[j][0])
125 | #print(j,nil)
126 | #print(re_J)
127 | #储存载核的次优价格
128 | if ni[i]>=cnt:
129 | secondprice=0
130 | else:
131 | secondprice=C_order[j][1]
132 | # for k in range(ns):
133 | # print(Kall_set[k]-re_K[k])
134 | #print(secondprice)
135 | #更新任务分配信息
136 | for j in re_J:
137 | J[i][j]=1
138 | #print(J[i])
139 | #更新价格
140 | for j in re_J:
141 | k_ord=K_dic[j]
142 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
143 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
144 | #print(P_all[i])
145 |
146 |
147 |
148 |
149 | def BidingPhase_f(i): #定义投标阶段函数,参数i为第i个无人机投标
150 | f_order=F_dic[i]
151 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
152 | re=0 #需要重新投标数
153 | J_old=set()
154 | #print(J[i])
155 | for j in range(nt): #将列表转化为集合
156 | if J[i][j]==1:
157 | J_old.add(j)
158 | #print(J_old)
159 | for j in J_old.copy():
160 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
161 | if P_all[i][j]P_f[f_order][j] or P_all[i][j]==P_f[f_order][j] and B_f[f_order][j]==i :
167 | k_ord=K_dic[j]
168 | re_Knum[k_ord]+=1
169 | #print(re_Knum)
170 | #print(J_old)
171 | new_Knum={} #每个分组需要补充的数量,使用字典表示
172 | secondnum=0 #记录有多少个组需要重新补充任务
173 | for k in range(ns):
174 | if nki[i][k]-re_Knum[k]!=0:
175 | new_Knum[k]=nki[i][k]-re_Knum[k]
176 | secondnum+=1
177 | #print(new_Knum)
178 | #print(secondnum)
179 | V={}
180 | #print(re)
181 | #print(J_old)
182 | #print(A[i])
183 | for j in range(nt):
184 | V[j]=round(A[i][j]-P_f[f_order][j],4) #计算每个商品的当前收益,小数点保留四位
185 | #print(V)
186 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
187 | #print(V_order)
188 | leftset=all_set-J_old #再余下的集合中将投标补至ni
189 | #print(leftset)
190 |
191 |
192 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
193 | #print(re_K)
194 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
195 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
196 | flagnum=0
197 | for j in range(nt):
198 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
199 | if new_Knum=={}:
200 | break
201 | jud = all(x == 0 for x in new_Knum.values())
202 | if jud and flagnum==secondnum: #
203 | break
204 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
205 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
206 | new_Knum[k_ord]-=1
207 | re_K[k_ord].add(V_order[j][0])
208 | else:
209 | if V_order[j][1]>0 and k_flag[k_ord]==0:
210 | k_secondprice[k_ord]=V_order[j][1]
211 | k_flag[k_ord]=1
212 | flagnum+=1
213 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
214 | k_secondprice[k_ord]=0
215 | k_flag[k_ord]=1
216 | flagnum+=1
217 | #print(re_K)
218 | #print(k_secondprice)
219 | # print()
220 |
221 | kchose_set=set() #用于记录投标全集
222 | for k in range(ns):
223 | kchose_set=kchose_set|re_K[k]
224 | C={}
225 | cnt=0
226 | for j in kchose_set:
227 | C[j]=V[j]
228 | cnt+=1
229 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
230 | #print(C_order)
231 | #print(cnt)
232 | #print(kchose_set)
233 |
234 | re_J=set([])
235 | for j in range(cnt):
236 | if re<=0: #若超过载核限制则退出
237 | break
238 | re-=1
239 | re_J.add(C_order[j][0])
240 | #print(re_J)
241 | #储存载核的次优价格
242 | if ni[i]>=cnt:
243 | secondprice=0
244 | else:
245 | secondprice=C_order[j][1]
246 | # for k in range(ns):
247 | # print(Kall_set[k]-re_K[k])
248 | #print(secondprice)
249 | #print()
250 | #更新任务分配信息
251 | for j in re_J:
252 | J[i][j]=1
253 | #print(J[i])
254 | #更新价格
255 | if re_J==set():
256 | Pchange[i]=0
257 | else:
258 | for j in re_J:
259 | k_ord=K_dic[j]
260 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
261 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
262 | Pchange[i]=1
263 |
264 | #print(P_all[i])
265 |
266 | start=time.time()
267 |
268 | for i in range(nu): #第一轮价格初始化
269 | BidingFirst_f(i)
270 |
271 | for j in range(nt): #第一轮联邦内价格一致阶段
272 | for f in range(nf): #每一个联邦进行价格一致
273 | for i in range(f*avef,(f+1)*avef):
274 | if P_all[i][j]==0 and P_f[f][j]==0:
275 | continue
276 | elif P_all[i][j]>P_f[f][j]:
277 | P_f[f][j]=P_all[i][j]
278 | B_f[f][j]=i
279 | elif P_all[i][j]==P_f[f][j] and i>B_f[f][j]:
280 | B_f[f][j]=i
281 |
282 |
283 | n=0
284 | lcr=0 #least communication rounds停止需要的最少轮次
285 | while(1):
286 | for f in range(nf):
287 | for fb in range(nf):
288 | if arcs_f[f][fb]==1:
289 | for j in range(nt):
290 | if P_f[fb][j]>P_f[f][j]:
291 | P_f[f][j]=P_f[fb][j]
292 | B_f[f][j]=B_f[fb][j]
293 | if P_f[fb][j]==P_f[f][j] and B_f[fb][j]>B_f[f][j]:
294 | B_f[f][j]=B_f[fb][j]
295 |
296 | #每一轮竞标之前,代理通讯阶段
297 | for i in range(nu):
298 | BidingPhase_f(i)
299 | #print(pri)
300 | for j in range(nt): #第一轮联邦内价格一致阶段
301 | for f in range(nf): #每一个联邦进行价格一致
302 | for i in range(f*avef,(f+1)*avef):
303 | if P_all[i][j]==0 and P_f[f][j]==0:
304 | continue
305 | elif P_all[i][j]>P_f[f][j]:
306 | P_f[f][j]=P_all[i][j]
307 | B_f[f][j]=i
308 | elif P_all[i][j]==P_f[f][j] and i>B_f[f][j]:
309 | B_f[f][j]=i
310 | n+=1
311 | # print(n)
312 | # print(P_all)
313 | #print(P)
314 | # print(J)
315 | if Pchange==[0]*nu:
316 | lcr+=1
317 | if lcr==netdiameter_f:
318 | break
319 | else:
320 | lcr=0
321 |
322 | end=time.time()
323 |
324 | print("迭代次数%d"%n)
325 | sum=0
326 | for i in range(nu):
327 | print("无人机%d选择了目标"%i,end='')
328 | for j in range(nt):
329 | if J[i][j]==1:
330 | sum+=A[i][j]
331 | print("%d(%d),"%(j,K_dic[j]),end='')
332 | print('')
333 | print("总收益值为%d"%sum)
334 | print(end-start)
335 |
--------------------------------------------------------------------------------
/src/Compared2.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | from ortools.linear_solver import pywraplp
6 | import networkx as nx
7 | import time
8 | import numpy as np
9 | from num import A_2060
10 | from num import A_40200
11 | from num import A_50500
12 | from graph import arcs_20
13 | from graph import arcs_40
14 | from graph import arcs_50
15 | from graph import arcs_line20
16 | from graph import arcs_random20
17 |
18 | x_scaleall=[]
19 | y_sumall=[]
20 | y_timeall=[]
21 | x_scaleline=[]
22 | y_sumline=[]
23 | y_timeline=[]
24 | x_scalerandom=[]
25 | y_sumrandom=[]
26 | y_timerandom=[]
27 |
28 | y_timegrouplimit=[]
29 |
30 |
31 |
32 | scale_n=10
33 | minadd=10 #定义最小增量
34 | while(scale_n<=300):
35 | cnt=0
36 | nu=scale_n #无人机数量
37 | nt=scale_n #任务量
38 |
39 | ns=scale_n #根据任务分成几组
40 | ni=[1]*nu #每个无人机最大可执行的任务,这里统一规定为3
41 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
42 |
43 |
44 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
45 | for i in range(nu):
46 | for j in range(nt):
47 | A[i][j]=random.uniform(0,20) #生成0-20内的随机数作为收益randint(0,20)
48 | #A=A_2060
49 |
50 |
51 |
52 | #print(nki)
53 | K_dic={}
54 | ave=int(nt/ns) #每个分组有多少个成员
55 | for i in range(nt):#建立任务和任务分组关系的字典
56 | K_dic[i]=int(i/ave)
57 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
58 | all_set=set([x for x in range(nt)]) #定义全集
59 | Kall_set=[] #定义分组的全集
60 | for i in range(ns):
61 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
62 |
63 | P=[0]*nt #初始化价格向量P
64 | #print(P)
65 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
66 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
67 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
68 |
69 |
70 |
71 | # 程序主函数
72 | def BidingFirst(i):
73 | V={}
74 | nil=ni[i]
75 | nkicopy=deepcopy(nki)
76 | for j in range(nt):
77 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
78 | #print(V)
79 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
80 | #print(V_order)
81 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
82 | #print(re_K)
83 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
84 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
85 |
86 | for j in range(nt):
87 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
88 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
89 | break
90 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
91 | #ni[i]-=1
92 | nkicopy[i][k_ord]-=1
93 | #re_J.add(V_order[j][0])
94 | re_K[k_ord].add(V_order[j][0])
95 | else:
96 | if V_order[j][1]>0 and k_flag[k_ord]==0:
97 | k_secondprice[k_ord]=V_order[j][1]
98 | k_flag[k_ord]=1
99 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
100 | k_secondprice[k_ord]=0
101 | k_flag[k_ord]=1
102 | # print(nki[i])
103 | # print(k_flag)
104 | #print(k_secondprice)
105 | # print(re_K)
106 | #print(re_J)
107 | kchose_set=set() #用于记录投标全集
108 | for k in range(ns):
109 | kchose_set=kchose_set|re_K[k]
110 | C={}
111 | cnt=0
112 | for j in kchose_set:
113 | C[j]=V[j]
114 | cnt+=1
115 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
116 | #print(C_order)
117 | #print(cnt)
118 | #print(kchose_set)
119 |
120 | re_J=set([])
121 | for j in range(cnt):
122 | if nil<=0: #若超过载核限制则退出
123 | break
124 | nil-=1
125 | re_J.add(C_order[j][0])
126 | #print(j,nil)
127 | #print(re_J)
128 | #储存载核的次优价格
129 | if ni[i]>=cnt:
130 | secondprice=0
131 | else:
132 | secondprice=C_order[j][1]
133 | # for k in range(ns):
134 | # print(Kall_set[k]-re_K[k])
135 | #print(secondprice)
136 | #更新任务分配信息
137 | for j in re_J:
138 | J[i][j]=1
139 | #print(J[i])
140 | #更新价格
141 | for j in re_J:
142 | k_ord=K_dic[j]
143 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
144 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
145 | #print(P_all[i])
146 |
147 |
148 |
149 |
150 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
151 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
152 | re=0 #需要重新投标数
153 | J_old=set()
154 | #print(J[i])
155 | for j in range(nt): #将列表转化为集合
156 | if J[i][j]==1:
157 | J_old.add(j)
158 | #print(J_old)
159 | for j in J_old.copy():
160 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
161 | if P_all[i][j]P[j] or P_all[i][j]==P[j] and B[j]==i :
167 | k_ord=K_dic[j]
168 | re_Knum[k_ord]+=1
169 | #print(re_Knum)
170 | #print(J_old)
171 | new_Knum={} #每个分组需要补充的数量,使用字典表示
172 | secondnum=0 #记录有多少个组需要重新补充任务
173 | for k in range(ns):
174 | if nki[i][k]-re_Knum[k]!=0:
175 | new_Knum[k]=nki[i][k]-re_Knum[k]
176 | secondnum+=1
177 | #print(new_Knum)
178 | #print(secondnum)
179 | V={}
180 | #print(re)
181 | #print(J_old)
182 | #print(A[i])
183 | for j in range(nt):
184 | V[j]=round(A[i][j]-P[j],4) #计算每个商品的当前收益,小数点保留四位
185 | #print(V)
186 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
187 | #print(V_order)
188 | leftset=all_set-J_old #再余下的集合中将投标补至ni
189 | #print(leftset)
190 |
191 |
192 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
193 | #print(re_K)
194 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
195 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
196 | flagnum=0
197 | for j in range(nt):
198 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
199 | if new_Knum=={}:
200 | break
201 | jud = all(x == 0 for x in new_Knum.values())
202 | if jud and flagnum==secondnum: #
203 | break
204 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
205 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
206 | new_Knum[k_ord]-=1
207 | re_K[k_ord].add(V_order[j][0])
208 | else:
209 | if V_order[j][1]>0 and k_flag[k_ord]==0:
210 | k_secondprice[k_ord]=V_order[j][1]
211 | k_flag[k_ord]=1
212 | flagnum+=1
213 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
214 | k_secondprice[k_ord]=0
215 | k_flag[k_ord]=1
216 | flagnum+=1
217 | #print(re_K)
218 | #print(k_secondprice)
219 | # print()
220 |
221 | kchose_set=set() #用于记录投标全集
222 | for k in range(ns):
223 | kchose_set=kchose_set|re_K[k]
224 | C={}
225 | cnt=0
226 | for j in kchose_set:
227 | C[j]=V[j]
228 | cnt+=1
229 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
230 | #print(C_order)
231 | #print(cnt)
232 | #print(kchose_set)
233 |
234 | re_J=set([])
235 | for j in range(cnt):
236 | if re<=0: #若超过载核限制则退出
237 | break
238 | re-=1
239 | re_J.add(C_order[j][0])
240 | #print(re_J)
241 | #储存载核的次优价格
242 | if ni[i]>=cnt:
243 | secondprice=0
244 | else:
245 | secondprice=C_order[j][1]
246 | # for k in range(ns):
247 | # print(Kall_set[k]-re_K[k])
248 | #print(secondprice)
249 | #print()
250 | #更新任务分配信息
251 | for j in re_J:
252 | J[i][j]=1
253 | #print(J[i])
254 | #更新价格
255 | if re_J==set():
256 | Pchange[i]=0
257 | else:
258 | for j in re_J:
259 | k_ord=K_dic[j]
260 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
261 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
262 | Pchange[i]=1
263 |
264 | #print(P_all[i])
265 |
266 | start=time.time()
267 |
268 | for i in range(nu): #第一轮价格初始化
269 | BidingFirst(i)
270 | B=[-1]*nt
271 | for j in range(nt): #第一轮价格一致阶段
272 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
273 | if P_all[i][j]==0 and P[j]==0:
274 | continue
275 | elif P_all[i][j]>P[j] :
276 | P[j]=P_all[i][j]
277 | B[j]=i
278 | elif P_all[i][j]==P[j] and i>B[j]:
279 | B[j]=i
280 | n=0
281 | while(1):
282 | for i in range(nu):
283 | BidingPhase(i)
284 | #print(pri)
285 | for j in range(nt):
286 | for i in range(nu):
287 | if P_all[i][j]==0 and P[j]==0:
288 | continue
289 | elif P_all[i][j]>P[j] :
290 | P[j]=P_all[i][j]
291 | B[j]=i
292 | elif P_all[i][j]==P[j] and i>B[j]:
293 | B[j]=i
294 |
295 |
296 | n+=1
297 | # print(n)
298 | # print(P_all)
299 | #print(P)
300 | # print(J)
301 | if Pchange==[0]*nu:
302 | break
303 |
304 | end=time.time()
305 |
306 | #print("迭代次数%d"%n)
307 | sum=0
308 | for i in range(nu):
309 | #print("无人机%d选择了目标"%i,end='')
310 | for j in range(nt):
311 | if J[i][j]==1:
312 | sum+=A[i][j]
313 | #print("%d(%d),"%(j,K_dic[j]),end='')
314 | #print('')
315 | print("总收益值为%d"%sum)
316 | y_timegrouplimit.append(end-start)
317 |
318 |
319 |
320 | while(cnt<3):
321 | if cnt==1:
322 | cnt+=1
323 | continue
324 | #设置全局变量并初始化
325 | if cnt==0:#完全图
326 | arcs=[([0]*nu) for i in range(nu)]
327 | for i in range(nu):
328 | for j in range(nu):
329 | if i0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
398 | #ni[i]-=1
399 | nkicopy[i][k_ord]-=1
400 | #re_J.add(V_order[j][0])
401 | re_K[k_ord].add(V_order[j][0])
402 | else:
403 | if V_order[j][1]>0 and k_flag[k_ord]==0:
404 | k_secondprice[k_ord]=V_order[j][1]
405 | k_flag[k_ord]=1
406 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
407 | k_secondprice[k_ord]=0
408 | k_flag[k_ord]=1
409 | # print(nki[i])
410 | # print(k_flag)
411 | #print(k_secondprice)
412 | # print(re_K)
413 | #print(re_J)
414 | kchose_set=set() #用于记录投标全集
415 | for k in range(ns):
416 | kchose_set=kchose_set|re_K[k]
417 | C={}
418 | cnt=0
419 | for j in kchose_set:
420 | C[j]=V[j]
421 | cnt+=1
422 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
423 | #print(C_order)
424 | #print(cnt)
425 | #print(kchose_set)
426 |
427 | re_J=set([])
428 | for j in range(cnt):
429 | if nil<=0: #若超过载核限制则退出
430 | break
431 | nil-=1
432 | re_J.add(C_order[j][0])
433 | #print(j,nil)
434 | #print(re_J)
435 | #储存载核的次优价格
436 | if ni[i]>=cnt:
437 | secondprice=0
438 | else:
439 | secondprice=C_order[j][1]
440 | # for k in range(ns):
441 | # print(Kall_set[k]-re_K[k])
442 | #print(secondprice)
443 | #更新任务分配信息
444 | for j in re_J:
445 | J[i][j]=1
446 | B_new[i][j]=i
447 | #print(J[i])
448 | #更新价格
449 | for j in re_J:
450 | k_ord=K_dic[j]
451 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
452 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
453 | #print(P_all[i])
454 |
455 |
456 |
457 |
458 | def BidingPhase(i): #定义投标阶段函数,参数i为第i个无人机投标
459 | for u in range(nu):
460 | if arcs[u][i]==1 or u==i:
461 | for j in range(nt):
462 | if P_all_old[u][j]>P_all_new[i][j]:
463 | P_all_new[i][j]=P_all_old[u][j]
464 | B_new[i][j]=B_old[u][j]
465 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
466 | B_new[i][j]=B_old[u][j]
467 | #nkicopy=deepcopy(nki)
468 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
469 | re=0 #需要重新投标数
470 | J_old=set()
471 | #print(J[i])
472 | for j in range(nt): #将列表转化为集合
473 | if J[i][j]==1:
474 | J_old.add(j)
475 | #print(J_old)
476 | for j in J_old.copy():
477 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
478 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
484 | k_ord=K_dic[j]
485 | re_Knum[k_ord]+=1
486 | #print(re_Knum)
487 | #print(J_old)
488 | new_Knum={} #每个分组需要补充的数量,使用字典表示
489 | secondnum=0 #记录有多少个组需要重新补充任务
490 | for k in range(ns):
491 | if nki[i][k]-re_Knum[k]!=0:
492 | new_Knum[k]=nki[i][k]-re_Knum[k]
493 | secondnum+=1
494 | #print(new_Knum)
495 | #print(secondnum)
496 | V={}
497 | #print(re)
498 | #print(J_old)
499 | #print(A[i])
500 | for j in range(nt):
501 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
502 | #print(V)
503 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
504 | #print(V_order)
505 | leftset=all_set-J_old #再余下的集合中将投标补至ni
506 | #print(leftset)
507 |
508 |
509 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
510 | #print(re_K)
511 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
512 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
513 | flagnum=0
514 | for j in range(nt):
515 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
516 | if new_Knum=={}:
517 | break
518 | jud = all(x == 0 for x in new_Knum.values())
519 | if jud and flagnum==secondnum: #
520 | break
521 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
522 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
523 | new_Knum[k_ord]-=1
524 | re_K[k_ord].add(V_order[j][0])
525 | else:
526 | if V_order[j][1]>0 and k_flag[k_ord]==0:
527 | k_secondprice[k_ord]=V_order[j][1]
528 | k_flag[k_ord]=1
529 | flagnum+=1
530 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
531 | k_secondprice[k_ord]=0
532 | k_flag[k_ord]=1
533 | flagnum+=1
534 | #print(re_K)
535 | #print(k_secondprice)
536 | # print()
537 |
538 | kchose_set=set() #用于记录投标全集
539 | for k in range(ns):
540 | kchose_set=kchose_set|re_K[k]
541 | C={}
542 | cnt=0
543 | for j in kchose_set:
544 | C[j]=V[j]
545 | cnt+=1
546 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
547 | #print(C_order)
548 | #print(cnt)
549 | #print(kchose_set)
550 |
551 | re_J=set([])
552 | for j in range(cnt):
553 | if re<=0: #若超过载核限制则退出
554 | break
555 | re-=1
556 | re_J.add(C_order[j][0])
557 | #print(re_J)
558 | #储存载核的次优价格
559 | if ni[i]>=cnt:
560 | secondprice=0
561 | else:
562 | secondprice=C_order[j][1]
563 | # for k in range(ns):
564 | # print(Kall_set[k]-re_K[k])
565 | #print(secondprice)
566 | #print()
567 | #更新任务分配信息
568 | for j in re_J:
569 | J[i][j]=1
570 | B_new[i][j]=i
571 | #print(J[i])
572 | #更新价格
573 | if re_J==set():
574 | Pchange[i]=0
575 | else:
576 | for j in re_J:
577 | k_ord=K_dic[j]
578 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
579 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
580 | Pchange[i]=1
581 |
582 | # print(P_all_new[i])
583 |
584 |
585 | start=time.time()
586 |
587 | for i in range(nu): #第一轮价格初始化
588 | BidingFirst(i)
589 | # for j in range(nt): #第一轮价格一致阶段
590 | # l=-1
591 | # m=-1
592 | # for i in range(nu):#在此方法中序号越高的无人机优先级越高
593 | # if P_all[i][j]==0 and P[j]==0:
594 | # continue
595 | # elif P_all[i][j]>=P[j] :
596 | # P[j]=P_all[i][j]
597 | # l=i
598 | # m=j
599 | # if l!=-1 and m!=-1:
600 | # pri[l][m]=1
601 | # print(0)
602 | # print(P_all_old)
603 | # print(P)
604 | # print(J)
605 |
606 | # BidingPhase(0)
607 | # BidingPhase(1)
608 | # BidingPhase(2)
609 |
610 |
611 | n=0
612 | lcr=0 #least communication rounds停止需要的最少轮次
613 | while(1):
614 | for i in range(nu):
615 | BidingPhase(i)
616 | B_old=deepcopy(B_new)
617 | P_all_old=deepcopy(P_all_new)
618 | # for i in range(nu):
619 | # for j in range(nt):
620 | # P_all_old[i][j]=P_all_new[i][j]
621 | # print(P_all_old)
622 | # print(P_all_new)
623 | #print(pri)
624 | # pri=[([0]*nt) for i in range(nu)]#定义优先级,若投标值相等时,优先级为0则表示未中标,1表示中标,每一轮初始均为0
625 | # for j in range(nt):
626 | # l=-1
627 | # m=-1
628 | # for i in range(nu):
629 | # if P_all[i][j]==0 and P[j]==0:
630 | # continue
631 | # elif P_all[i][j]>=P[j] :
632 | # P[j]=P_all[i][j]
633 | # l=i
634 | # m=j
635 | # if l!=-1 and m!=-1:
636 | # pri[l][m]=1
637 | n+=1
638 | # print(n)
639 | # print(P_all)
640 | # print(P)
641 | # print(J)
642 | if Pchange==[0]*nu:
643 | lcr+=1
644 | if lcr==netdiameter:
645 | break
646 | else:
647 | lcr=0
648 |
649 | end=time.time()
650 |
651 | # af=[i for i in range(nt)]
652 | # print(af)
653 | # print("迭代次数%d"%n)
654 | sum=0
655 | for i in range(nu):
656 | # print("无人机%d选择了目标"%i,end='')
657 | for j in range(nt):
658 | if J[i][j]==1:
659 | # af.remove(j)
660 | sum+=A[i][j]
661 | #print("%d(%d),"%(j,K_dic[j]),end='')
662 | # print('')
663 | print("总收益值为%d"%sum)
664 | # print(af)
665 | if cnt==0:
666 | x_scaleall.append(scale_n)
667 | y_sumall.append(sum)
668 | y_timeall.append(end-start)
669 | elif cnt==1:
670 | x_scaleline.append(scale_n)
671 | y_sumline.append(sum)
672 | y_timeline.append(end-start)
673 | elif cnt==2:
674 | x_scalerandom.append(scale_n)
675 | y_sumrandom.append(sum)
676 | y_timerandom.append(end-start)
677 | cnt+=1
678 | scale_n+=3
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 | plt.plot(x_scaleall,y_timeall, linewidth=1,c='red',label="all")
687 | #plt.plot(x_scaleline,y_timeline, linewidth=1,c='yellow',label='line')
688 | plt.plot(x_scalerandom,y_timerandom, linewidth=1,c='blue',label='random')
689 | plt.plot(x_scaleall,y_timegrouplimit, linewidth=1,c='black',label="Shared Memory")
690 | plt.legend()
691 | plt.xlabel('Number of drones')
692 | #plt.ylabel('Sum')
693 | plt.ylabel('Second')
694 | plt.show()
--------------------------------------------------------------------------------
/src/Compared3.py:
--------------------------------------------------------------------------------
1 | import random
2 | import copy
3 | from copy import deepcopy
4 | import matplotlib.pyplot as plt
5 | from ortools.linear_solver import pywraplp
6 | import networkx as nx
7 | import time
8 | import numpy as np
9 | from graph import arcs_5
10 | from num import A_2060
11 | from num import A_40200
12 | from num import A_50500
13 | from graph import arcs_20
14 | from graph import arcs_40
15 | from graph import arcs_50
16 | from graph import arcs_line20
17 | from graph import arcs_random20
18 |
19 |
20 | y_sumall=[]
21 | y_timeall=[]
22 | y_sumline=[]
23 | y_timeline=[]
24 | y_sumrandom=[]
25 | y_timerandom=[]
26 |
27 | x_scale=[]
28 | y_timegrouplimit=[]
29 | y_timefederate=[]
30 |
31 |
32 | scale_n=10
33 | minadd=1 #定义最小增量
34 | while(scale_n<=200):
35 | cnt=0
36 | nu=scale_n #无人机数量
37 | nt=scale_n #任务量
38 | nf=5 #联邦数量
39 | ns=scale_n #根据任务分成几组
40 | ni=[1]*nu #每个无人机最大可执行的任务,这里统一规定为3
41 | nki=[([1]*ns) for i in range(nu)] #对于每一个分组,每一个无人机最多可执行的任务,这里统一规定为1
42 | arcs_f=arcs_5
43 |
44 | A=[([0]*nt) for i in range(nu)] #定义收益二维矩阵
45 | for i in range(nu):
46 | for j in range(nt):
47 | A[i][j]=random.uniform(0,20) #生成0-20内的随机数作为收益randint(0,20)
48 | #A=A_2060
49 | F_dic={}
50 | avef=int(nu/nf) #每个联邦有多少个成员
51 | for i in range(nu):#建立无人机和联邦号的对应字典
52 | F_dic[i]=int(i/avef)
53 | #print(nki)
54 | K_dic={}
55 | ave=int(nt/ns) #每个分组有多少个成员
56 | for i in range(nt):#建立任务和任务分组关系的字典
57 | K_dic[i]=int(i/ave)
58 | #K_old=[([0]*nt) for i in range(ns)] #初始化原有多少已经中标
59 | all_set=set([x for x in range(nt)]) #定义全集
60 | Kall_set=[] #定义分组的全集
61 | for i in range(ns):
62 | Kall_set.append(set([x for x in range(i*ave,(i+1)*ave)]))
63 | P_f=[[0]*nt for i in range(nf)] #初始化价格向量P
64 | B_f=[[-1]*nt for i in range(nf)]
65 | G=nx.Graph() # 新建一个无向图
66 | nodes=[]
67 | edges=[]
68 | for i in range(nf):
69 | G.add_node(i)
70 | for i in range(nf):
71 | for j in range(nf):
72 | if arcs_f[i][j]==1:
73 | G.add_edge(i,j)
74 | netdiameter_f=nx.diameter(G)
75 |
76 |
77 | P=[0]*nt #初始化价格向量P
78 | #print(P)
79 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
80 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
81 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
82 |
83 | # 程序主函数
84 | def BidingFirst_a(i):
85 | V={}
86 | nil=ni[i]
87 | nkicopy=deepcopy(nki)
88 | for j in range(nt):
89 | V[j]=A[i][j]-P[j] #计算每个商品的当前收益
90 | #print(V)
91 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
92 | #print(V_order)
93 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
94 | #print(re_K)
95 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
96 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
97 |
98 | for j in range(nt):
99 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
100 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
101 | break
102 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
103 | #ni[i]-=1
104 | nkicopy[i][k_ord]-=1
105 | #re_J.add(V_order[j][0])
106 | re_K[k_ord].add(V_order[j][0])
107 | else:
108 | if V_order[j][1]>0 and k_flag[k_ord]==0:
109 | k_secondprice[k_ord]=V_order[j][1]
110 | k_flag[k_ord]=1
111 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
112 | k_secondprice[k_ord]=0
113 | k_flag[k_ord]=1
114 | # print(nki[i])
115 | # print(k_flag)
116 | #print(k_secondprice)
117 | # print(re_K)
118 | #print(re_J)
119 | kchose_set=set() #用于记录投标全集
120 | for k in range(ns):
121 | kchose_set=kchose_set|re_K[k]
122 | C={}
123 | cnt=0
124 | for j in kchose_set:
125 | C[j]=V[j]
126 | cnt+=1
127 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
128 | #print(C_order)
129 | #print(cnt)
130 | #print(kchose_set)
131 |
132 | re_J=set([])
133 | for j in range(cnt):
134 | if nil<=0: #若超过载核限制则退出
135 | break
136 | nil-=1
137 | re_J.add(C_order[j][0])
138 | #print(j,nil)
139 | #print(re_J)
140 | #储存载核的次优价格
141 | if ni[i]>=cnt:
142 | secondprice=0
143 | else:
144 | secondprice=C_order[j][1]
145 | # for k in range(ns):
146 | # print(Kall_set[k]-re_K[k])
147 | #print(secondprice)
148 | #更新任务分配信息
149 | for j in re_J:
150 | J[i][j]=1
151 | #print(J[i])
152 | #更新价格
153 | for j in re_J:
154 | k_ord=K_dic[j]
155 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
156 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
157 | #print(P_all[i])
158 |
159 |
160 |
161 |
162 | def BidingPhase_a(i): #定义投标阶段函数,参数i为第i个无人机投标
163 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
164 | re=0 #需要重新投标数
165 | J_old=set()
166 | #print(J[i])
167 | for j in range(nt): #将列表转化为集合
168 | if J[i][j]==1:
169 | J_old.add(j)
170 | #print(J_old)
171 | for j in J_old.copy():
172 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
173 | if P_all[i][j]P[j] or P_all[i][j]==P[j] and B[j]==i :
179 | k_ord=K_dic[j]
180 | re_Knum[k_ord]+=1
181 | #print(re_Knum)
182 | #print(J_old)
183 | new_Knum={} #每个分组需要补充的数量,使用字典表示
184 | secondnum=0 #记录有多少个组需要重新补充任务
185 | for k in range(ns):
186 | if nki[i][k]-re_Knum[k]!=0:
187 | new_Knum[k]=nki[i][k]-re_Knum[k]
188 | secondnum+=1
189 | #print(new_Knum)
190 | #print(secondnum)
191 | V={}
192 | #print(re)
193 | #print(J_old)
194 | #print(A[i])
195 | for j in range(nt):
196 | V[j]=round(A[i][j]-P[j],4) #计算每个商品的当前收益,小数点保留四位
197 | #print(V)
198 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
199 | #print(V_order)
200 | leftset=all_set-J_old #再余下的集合中将投标补至ni
201 | #print(leftset)
202 |
203 |
204 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
205 | #print(re_K)
206 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
207 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
208 | flagnum=0
209 | for j in range(nt):
210 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
211 | if new_Knum=={}:
212 | break
213 | jud = all(x == 0 for x in new_Knum.values())
214 | if jud and flagnum==secondnum: #
215 | break
216 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
217 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
218 | new_Knum[k_ord]-=1
219 | re_K[k_ord].add(V_order[j][0])
220 | else:
221 | if V_order[j][1]>0 and k_flag[k_ord]==0:
222 | k_secondprice[k_ord]=V_order[j][1]
223 | k_flag[k_ord]=1
224 | flagnum+=1
225 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
226 | k_secondprice[k_ord]=0
227 | k_flag[k_ord]=1
228 | flagnum+=1
229 | #print(re_K)
230 | #print(k_secondprice)
231 | # print()
232 |
233 | kchose_set=set() #用于记录投标全集
234 | for k in range(ns):
235 | kchose_set=kchose_set|re_K[k]
236 | C={}
237 | cnt=0
238 | for j in kchose_set:
239 | C[j]=V[j]
240 | cnt+=1
241 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
242 | #print(C_order)
243 | #print(cnt)
244 | #print(kchose_set)
245 |
246 | re_J=set([])
247 | for j in range(cnt):
248 | if re<=0: #若超过载核限制则退出
249 | break
250 | re-=1
251 | re_J.add(C_order[j][0])
252 | #print(re_J)
253 | #储存载核的次优价格
254 | if ni[i]>=cnt:
255 | secondprice=0
256 | else:
257 | secondprice=C_order[j][1]
258 | # for k in range(ns):
259 | # print(Kall_set[k]-re_K[k])
260 | #print(secondprice)
261 | #print()
262 | #更新任务分配信息
263 | for j in re_J:
264 | J[i][j]=1
265 | #print(J[i])
266 | #更新价格
267 | if re_J==set():
268 | Pchange[i]=0
269 | else:
270 | for j in re_J:
271 | k_ord=K_dic[j]
272 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
273 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
274 | Pchange[i]=1
275 |
276 | #print(P_all[i])
277 |
278 | start=time.time()
279 |
280 | for i in range(nu): #第一轮价格初始化
281 | BidingFirst_a(i)
282 | B=[-1]*nt
283 | for j in range(nt): #第一轮价格一致阶段
284 | for i in range(nu):#在此方法中序号越高的无人机优先级越高
285 | if P_all[i][j]==0 and P[j]==0:
286 | continue
287 | elif P_all[i][j]>P[j] :
288 | P[j]=P_all[i][j]
289 | B[j]=i
290 | elif P_all[i][j]==P[j] and i>B[j]:
291 | B[j]=i
292 | n=0
293 | while(1):
294 | for i in range(nu):
295 | BidingPhase_a(i)
296 | #print(pri)
297 | for j in range(nt):
298 | for i in range(nu):
299 | if P_all[i][j]==0 and P[j]==0:
300 | continue
301 | elif P_all[i][j]>P[j] :
302 | P[j]=P_all[i][j]
303 | B[j]=i
304 | elif P_all[i][j]==P[j] and i>B[j]:
305 | B[j]=i
306 |
307 | n+=1
308 | # print(n)
309 | # print(P_all)
310 | #print(P)
311 | # print(J)
312 | if Pchange==[0]*nu:
313 | break
314 |
315 | end=time.time()
316 |
317 | #print("迭代次数%d"%n)
318 | sum=0
319 | for i in range(nu):
320 | #print("无人机%d选择了目标"%i,end='')
321 | for j in range(nt):
322 | if J[i][j]==1:
323 | sum+=A[i][j]
324 | #print("%d(%d),"%(j,K_dic[j]),end='')
325 | #print('')
326 | print("总收益值为%d"%sum)
327 | y_timegrouplimit.append(end-start)
328 |
329 | P=[0]*nt #初始化价格向量P
330 | #print(P)
331 | P_all=[([0]*nt) for i in range(nu)] #定义P_all为每次投标时各无人机的出价,初始化为0
332 | J=[([0]*nt) for i in range(nu)] #用于记录上一次每个无人机投标集合,0表示未投标,1表示投标
333 | Pchange=[1]*nu #记录价格是否修改过,0表示此轮未修改,1表示此轮修改过
334 |
335 | # 程序主函数
336 | def BidingFirst_f(i):
337 | f_order=F_dic[i]
338 | V={}
339 | nil=ni[i]
340 | nkicopy=deepcopy(nki)
341 | for j in range(nt):
342 | V[j]=A[i][j]-P_f[f_order][j] #计算每个商品的当前收益
343 | #print(V)
344 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
345 | #print(V_order)
346 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
347 | #print(re_K)
348 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
349 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
350 |
351 | for j in range(nt):
352 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
353 | if k_flag==[1]*ns: #当所有分组次优价格都记录后退出循环
354 | break
355 | if V_order[j][1]>0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
356 | #ni[i]-=1
357 | nkicopy[i][k_ord]-=1
358 | #re_J.add(V_order[j][0])
359 | re_K[k_ord].add(V_order[j][0])
360 | else:
361 | if V_order[j][1]>0 and k_flag[k_ord]==0:
362 | k_secondprice[k_ord]=V_order[j][1]
363 | k_flag[k_ord]=1
364 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
365 | k_secondprice[k_ord]=0
366 | k_flag[k_ord]=1
367 | # print(nki[i])
368 | # print(k_flag)
369 | #print(k_secondprice)
370 | # print(re_K)
371 | #print(re_J)
372 | kchose_set=set() #用于记录投标全集
373 | for k in range(ns):
374 | kchose_set=kchose_set|re_K[k]
375 | C={}
376 | cnt=0
377 | for j in kchose_set:
378 | C[j]=V[j]
379 | cnt+=1
380 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
381 | #print(C_order)
382 | #print(cnt)
383 | #print(kchose_set)
384 |
385 | re_J=set([])
386 | for j in range(cnt):
387 | if nil<=0: #若超过载核限制则退出
388 | break
389 | nil-=1
390 | re_J.add(C_order[j][0])
391 | #print(j,nil)
392 | #print(re_J)
393 | #储存载核的次优价格
394 | if ni[i]>=cnt:
395 | secondprice=0
396 | else:
397 | secondprice=C_order[j][1]
398 | # for k in range(ns):
399 | # print(Kall_set[k]-re_K[k])
400 | #print(secondprice)
401 | #更新任务分配信息
402 | for j in re_J:
403 | J[i][j]=1
404 | #print(J[i])
405 | #更新价格
406 | for j in re_J:
407 | k_ord=K_dic[j]
408 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
409 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
410 | #print(P_all[i])
411 |
412 |
413 |
414 |
415 | def BidingPhase_f(i): #定义投标阶段函数,参数i为第i个无人机投标
416 | f_order=F_dic[i]
417 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
418 | re=0 #需要重新投标数
419 | J_old=set()
420 | #print(J[i])
421 | for j in range(nt): #将列表转化为集合
422 | if J[i][j]==1:
423 | J_old.add(j)
424 | #print(J_old)
425 | for j in J_old.copy():
426 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
427 | if P_all[i][j]P_f[f_order][j] or P_all[i][j]==P_f[f_order][j] and B_f[f_order][j]==i :
433 | k_ord=K_dic[j]
434 | re_Knum[k_ord]+=1
435 | #print(re_Knum)
436 | #print(J_old)
437 | new_Knum={} #每个分组需要补充的数量,使用字典表示
438 | secondnum=0 #记录有多少个组需要重新补充任务
439 | for k in range(ns):
440 | if nki[i][k]-re_Knum[k]!=0:
441 | new_Knum[k]=nki[i][k]-re_Knum[k]
442 | secondnum+=1
443 | #print(new_Knum)
444 | #print(secondnum)
445 | V={}
446 | #print(re)
447 | #print(J_old)
448 | #print(A[i])
449 | for j in range(nt):
450 | V[j]=round(A[i][j]-P_f[f_order][j],4) #计算每个商品的当前收益,小数点保留四位
451 | #print(V)
452 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
453 | #print(V_order)
454 | leftset=all_set-J_old #再余下的集合中将投标补至ni
455 | #print(leftset)
456 |
457 |
458 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
459 | #print(re_K)
460 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
461 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
462 | flagnum=0
463 | for j in range(nt):
464 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
465 | if new_Knum=={}:
466 | break
467 | jud = all(x == 0 for x in new_Knum.values())
468 | if jud and flagnum==secondnum: #
469 | break
470 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
471 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
472 | new_Knum[k_ord]-=1
473 | re_K[k_ord].add(V_order[j][0])
474 | else:
475 | if V_order[j][1]>0 and k_flag[k_ord]==0:
476 | k_secondprice[k_ord]=V_order[j][1]
477 | k_flag[k_ord]=1
478 | flagnum+=1
479 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
480 | k_secondprice[k_ord]=0
481 | k_flag[k_ord]=1
482 | flagnum+=1
483 | #print(re_K)
484 | #print(k_secondprice)
485 | # print()
486 |
487 | kchose_set=set() #用于记录投标全集
488 | for k in range(ns):
489 | kchose_set=kchose_set|re_K[k]
490 | C={}
491 | cnt=0
492 | for j in kchose_set:
493 | C[j]=V[j]
494 | cnt+=1
495 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
496 | #print(C_order)
497 | #print(cnt)
498 | #print(kchose_set)
499 |
500 | re_J=set([])
501 | for j in range(cnt):
502 | if re<=0: #若超过载核限制则退出
503 | break
504 | re-=1
505 | re_J.add(C_order[j][0])
506 | #print(re_J)
507 | #储存载核的次优价格
508 | if ni[i]>=cnt:
509 | secondprice=0
510 | else:
511 | secondprice=C_order[j][1]
512 | # for k in range(ns):
513 | # print(Kall_set[k]-re_K[k])
514 | #print(secondprice)
515 | #print()
516 | #更新任务分配信息
517 | for j in re_J:
518 | J[i][j]=1
519 | #print(J[i])
520 | #更新价格
521 | if re_J==set():
522 | Pchange[i]=0
523 | else:
524 | for j in re_J:
525 | k_ord=K_dic[j]
526 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
527 | P_all[i][j]=round(P_all[i][j]+V[j]-maxsecondprice+minadd,4)
528 | Pchange[i]=1
529 |
530 | #print(P_all[i])
531 |
532 | start=time.time()
533 |
534 | for i in range(nu): #第一轮价格初始化
535 | BidingFirst_f(i)
536 |
537 | for j in range(nt): #第一轮联邦内价格一致阶段
538 | for f in range(nf): #每一个联邦进行价格一致
539 | for i in range(f*avef,(f+1)*avef):
540 | if P_all[i][j]==0 and P_f[f][j]==0:
541 | continue
542 | elif P_all[i][j]>P_f[f][j]:
543 | P_f[f][j]=P_all[i][j]
544 | B_f[f][j]=i
545 | elif P_all[i][j]==P_f[f][j] and i>B_f[f][j]:
546 | B_f[f][j]=i
547 |
548 |
549 | n=0
550 | lcr=0 #least communication rounds停止需要的最少轮次
551 | while(1):
552 | for f in range(nf):
553 | for fb in range(nf):
554 | if arcs_f[f][fb]==1:
555 | for j in range(nt):
556 | if P_f[fb][j]>P_f[f][j]:
557 | P_f[f][j]=P_f[fb][j]
558 | B_f[f][j]=B_f[fb][j]
559 | if P_f[fb][j]==P_f[f][j] and B_f[fb][j]>B_f[f][j]:
560 | B_f[f][j]=B_f[fb][j]
561 |
562 | #每一轮竞标之前,代理通讯阶段
563 | for i in range(nu):
564 | BidingPhase_f(i)
565 | #print(pri)
566 | for j in range(nt): #第一轮联邦内价格一致阶段
567 | for f in range(nf): #每一个联邦进行价格一致
568 | for i in range(f*avef,(f+1)*avef):
569 | if P_all[i][j]==0 and P_f[f][j]==0:
570 | continue
571 | elif P_all[i][j]>P_f[f][j]:
572 | P_f[f][j]=P_all[i][j]
573 | B_f[f][j]=i
574 | elif P_all[i][j]==P_f[f][j] and i>B_f[f][j]:
575 | B_f[f][j]=i
576 | n+=1
577 | # print(n)
578 | # print(P_all)
579 | #print(P)
580 | # print(J)
581 | if Pchange==[0]*nu:
582 | lcr+=1
583 | if lcr==netdiameter_f:
584 | break
585 | else:
586 | lcr=0
587 |
588 | end=time.time()
589 |
590 | #print("迭代次数%d"%n)
591 | sum=0
592 | for i in range(nu):
593 | #print("无人机%d选择了目标"%i,end='')
594 | for j in range(nt):
595 | if J[i][j]==1:
596 | sum+=A[i][j]
597 | #print("%d(%d),"%(j,K_dic[j]),end='')
598 | #print('')
599 | print("总收益值为%d"%sum)
600 | y_timefederate.append(end-start)
601 |
602 |
603 |
604 |
605 | while(cnt<3):
606 | if cnt==1 or cnt==0:
607 | cnt+=1
608 | continue
609 | #设置全局变量并初始化
610 | if cnt==0:#完全图
611 | arcs=[([0]*nu) for i in range(nu)]
612 | for i in range(nu):
613 | for j in range(nu):
614 | if i0 and nkicopy[i][k_ord]>0: #如果价值大于0且没到分组限制上限
683 | #ni[i]-=1
684 | nkicopy[i][k_ord]-=1
685 | #re_J.add(V_order[j][0])
686 | re_K[k_ord].add(V_order[j][0])
687 | else:
688 | if V_order[j][1]>0 and k_flag[k_ord]==0:
689 | k_secondprice[k_ord]=V_order[j][1]
690 | k_flag[k_ord]=1
691 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
692 | k_secondprice[k_ord]=0
693 | k_flag[k_ord]=1
694 | # print(nki[i])
695 | # print(k_flag)
696 | #print(k_secondprice)
697 | # print(re_K)
698 | #print(re_J)
699 | kchose_set=set() #用于记录投标全集
700 | for k in range(ns):
701 | kchose_set=kchose_set|re_K[k]
702 | C={}
703 | cnt=0
704 | for j in kchose_set:
705 | C[j]=V[j]
706 | cnt+=1
707 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
708 | #print(C_order)
709 | #print(cnt)
710 | #print(kchose_set)
711 |
712 | re_J=set([])
713 | for j in range(cnt):
714 | if nil<=0: #若超过载核限制则退出
715 | break
716 | nil-=1
717 | re_J.add(C_order[j][0])
718 | #print(j,nil)
719 | #print(re_J)
720 | #储存载核的次优价格
721 | if ni[i]>=cnt:
722 | secondprice=0
723 | else:
724 | secondprice=C_order[j][1]
725 | # for k in range(ns):
726 | # print(Kall_set[k]-re_K[k])
727 | #print(secondprice)
728 | #更新任务分配信息
729 | for j in re_J:
730 | J[i][j]=1
731 | B_new[i][j]=i
732 | #print(J[i])
733 | #更新价格
734 | for j in re_J:
735 | k_ord=K_dic[j]
736 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
737 | P_all_old[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
738 | #print(P_all[i])
739 |
740 |
741 |
742 |
743 | def BidingPhase_d(i): #定义投标阶段函数,参数i为第i个无人机投标
744 | for u in range(nu):
745 | if arcs[u][i]==1 or u==i:
746 | for j in range(nt):
747 | if P_all_old[u][j]>P_all_new[i][j]:
748 | P_all_new[i][j]=P_all_old[u][j]
749 | B_new[i][j]=B_old[u][j]
750 | elif P_all_old[u][j]==P_all_new[i][j] and B_old[u][j]>B_new[i][j]:
751 | B_new[i][j]=B_old[u][j]
752 | #nkicopy=deepcopy(nki)
753 | re_Knum=[0]*ns #每一组当前含最高价格的投标数
754 | re=0 #需要重新投标数
755 | J_old=set()
756 | #print(J[i])
757 | for j in range(nt): #将列表转化为集合
758 | if J[i][j]==1:
759 | J_old.add(j)
760 | #print(J_old)
761 | for j in J_old.copy():
762 | #非当前最高价需要重新投标或者存在同时最高价,低优先级无人机需要重新投标
763 | if P_all_old[i][j]P_all_new[i][j] or P_all_old[i][j]==P_all_new[i][j] and B_new[i][j]==i :
769 | k_ord=K_dic[j]
770 | re_Knum[k_ord]+=1
771 | #print(re_Knum)
772 | #print(J_old)
773 | new_Knum={} #每个分组需要补充的数量,使用字典表示
774 | secondnum=0 #记录有多少个组需要重新补充任务
775 | for k in range(ns):
776 | if nki[i][k]-re_Knum[k]!=0:
777 | new_Knum[k]=nki[i][k]-re_Knum[k]
778 | secondnum+=1
779 | #print(new_Knum)
780 | #print(secondnum)
781 | V={}
782 | #print(re)
783 | #print(J_old)
784 | #print(A[i])
785 | for j in range(nt):
786 | V[j]=round(A[i][j]-P_all_new[i][j],4) #计算每个商品的当前收益,小数点保留四位
787 | #print(V)
788 | V_order=sorted(V.items(),key=lambda x:x[1],reverse=True)
789 | #print(V_order)
790 | leftset=all_set-J_old #再余下的集合中将投标补至ni
791 | #print(leftset)
792 |
793 |
794 | re_K=[set() for i in range(ns)] #用于记录每个分组想投标的集合
795 | #print(re_K)
796 | k_secondprice=[0]*ns #用于记录每个分组的次优价格
797 | k_flag=[0]*ns #用于辅助记录次优价格,1表示已经存过
798 | flagnum=0
799 | for j in range(nt):
800 | k_ord=K_dic[V_order[j][0]] #根据物品j查的其所在分组的下标
801 | if new_Knum=={}:
802 | break
803 | jud = all(x == 0 for x in new_Knum.values())
804 | if jud and flagnum==secondnum: #
805 | break
806 | if V_order[j][0] in leftset and k_ord in new_Knum.keys():
807 | if V_order[j][1]>0 and new_Knum[k_ord]>0: #如果价值大于0且没到分组限制上限
808 | new_Knum[k_ord]-=1
809 | re_K[k_ord].add(V_order[j][0])
810 | else:
811 | if V_order[j][1]>0 and k_flag[k_ord]==0:
812 | k_secondprice[k_ord]=V_order[j][1]
813 | k_flag[k_ord]=1
814 | flagnum+=1
815 | elif V_order[j][1]<=0 and k_flag[k_ord]==0:
816 | k_secondprice[k_ord]=0
817 | k_flag[k_ord]=1
818 | flagnum+=1
819 | #print(re_K)
820 | #print(k_secondprice)
821 | # print()
822 |
823 | kchose_set=set() #用于记录投标全集
824 | for k in range(ns):
825 | kchose_set=kchose_set|re_K[k]
826 | C={}
827 | cnt=0
828 | for j in kchose_set:
829 | C[j]=V[j]
830 | cnt+=1
831 | C_order=sorted(C.items(),key=lambda x:x[1],reverse=True)
832 | #print(C_order)
833 | #print(cnt)
834 | #print(kchose_set)
835 |
836 | re_J=set([])
837 | for j in range(cnt):
838 | if re<=0: #若超过载核限制则退出
839 | break
840 | re-=1
841 | re_J.add(C_order[j][0])
842 | #print(re_J)
843 | #储存载核的次优价格
844 | if ni[i]>=cnt:
845 | secondprice=0
846 | else:
847 | secondprice=C_order[j][1]
848 | # for k in range(ns):
849 | # print(Kall_set[k]-re_K[k])
850 | #print(secondprice)
851 | #print()
852 | #更新任务分配信息
853 | for j in re_J:
854 | J[i][j]=1
855 | B_new[i][j]=i
856 | #print(J[i])
857 | #更新价格
858 | if re_J==set():
859 | Pchange[i]=0
860 | else:
861 | for j in re_J:
862 | k_ord=K_dic[j]
863 | maxsecondprice=max(secondprice,k_secondprice[k_ord])
864 | P_all_new[i][j]=round(P_all_old[i][j]+V[j]-maxsecondprice+minadd,4)
865 | Pchange[i]=1
866 |
867 | # print(P_all_new[i])
868 |
869 |
870 | start=time.time()
871 |
872 | for i in range(nu): #第一轮价格初始化
873 | BidingFirst_d(i)
874 |
875 | n=0
876 | lcr=0 #least communication rounds停止需要的最少轮次
877 | while(1):
878 | for i in range(nu):
879 | BidingPhase_d(i)
880 | B_old=deepcopy(B_new)
881 | P_all_old=deepcopy(P_all_new)
882 |
883 | n+=1
884 | # print(n)
885 | # print(P_all)
886 | # print(P)
887 | # print(J)
888 | if Pchange==[0]*nu:
889 | lcr+=1
890 | if lcr==netdiameter:
891 | break
892 | else:
893 | lcr=0
894 |
895 | end=time.time()
896 |
897 | # af=[i for i in range(nt)]
898 | # print(af)
899 | # print("迭代次数%d"%n)
900 | sum=0
901 | for i in range(nu):
902 | # print("无人机%d选择了目标"%i,end='')
903 | for j in range(nt):
904 | if J[i][j]==1:
905 | # af.remove(j)
906 | sum+=A[i][j]
907 | #print("%d(%d),"%(j,K_dic[j]),end='')
908 | # print('')
909 | print("总收益值为%d"%sum)
910 | # print(af)
911 | if cnt==0:
912 | y_sumall.append(sum)
913 | y_timeall.append(end-start)
914 | elif cnt==1:
915 | y_sumline.append(sum)
916 | y_timeline.append(end-start)
917 | elif cnt==2:
918 | x_scale.append(scale_n)
919 | y_sumrandom.append(sum)
920 | y_timerandom.append(end-start)
921 | cnt+=1
922 | scale_n+=5
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 | #plt.plot(x_scale,y_timeall, linewidth=1,c='red',label="all")
931 | #plt.plot(x_scaleline,y_timeline, linewidth=1,c='yellow',label='line')
932 | plt.plot(x_scale,y_timerandom, linewidth=1,c='blue',label='random Distributed')
933 | plt.plot(x_scale,y_timegrouplimit, linewidth=1,c='black',label="Shared Memory")
934 | plt.plot(x_scale,y_timefederate, linewidth=1,c='red',label='Federate System')
935 | plt.legend()
936 | plt.xlabel('Number of drones')
937 | #plt.ylabel('Sum')
938 | plt.ylabel('Second')
939 | plt.show()
--------------------------------------------------------------------------------
/src/graph.py:
--------------------------------------------------------------------------------
1 | arcs_5=[[0, 0, 0, 1, 0], [0, 0, 0, 1, 1], [0, 0, 0, 1, 0], [1, 1, 1, 0, 1], [0, 1, 0, 1, 0]]
2 |
3 | arcs_20=[[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]
4 |
5 | arcs_40=[[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]
6 |
7 | arcs_50=[[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]]
8 |
9 | arcs_line20=[[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]]
10 |
11 | arcs_random20=[[0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1], [1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1], [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0], [1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0], [1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1], [1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1], [1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0], [1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1], [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0], [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1], [1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0], [1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0], [1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0]]
--------------------------------------------------------------------------------
/src/graphdraw.py:
--------------------------------------------------------------------------------
1 | import networkx as nx
2 | import matplotlib.pyplot as plt
3 | import random
4 |
5 |
6 | nodes = [1, 2, 3, 4]
7 | edge_list = [(1, 2), (2, 3), (2, 4), (3, 4)]
8 |
9 | pos = {1: (0, 0), 2: (0, 0), 3: (0, 0), 4: (0, 0)}
10 | # for e in edge_list: # 添加边, 参数name为边权值
11 | # g.add_edge(e[0], e[1], name=e[2])
12 | def test():
13 | fig = plt.figure() # 生成画布
14 | plt.ion() # 打开交互模式
15 | cnt=0
16 | while(cnt<=10):
17 | fig.clf()
18 | ax = fig.add_subplot(111)
19 | ax.set(xlim=[-10, 10], ylim=[-10, 10], title='An Example Axes',ylabel='Y-Axis', xlabel='X-Axis')
20 | plt.show()
21 | g = nx.Graph() # 新建一个无向图
22 | g.add_nodes_from(nodes)
23 | g.add_edges_from(edge_list)
24 | l=len(nodes)
25 | for i in range(1,l+1):
26 | t=(pos[i][0]+random.randint(-1,1),pos[i][1]+random.randint(-1,1))
27 | pos[i]=t
28 | nx.draw(g,pos,ax,with_labels=True)
29 | plt.pause(1)
30 | cnt+=1
31 | # 关闭交互模式
32 | plt.ioff()
33 | plt.show()
34 |
35 | test()
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/graphsetup.py:
--------------------------------------------------------------------------------
1 | import random
2 | import matplotlib.pyplot as plt
3 | import networkx as nx
4 |
5 |
6 | nu=5
7 | arcs=[([0]*nu) for i in range(nu)]
8 | #cnt=0
9 | for i in range(nu):
10 | for j in range(nu):
11 | if i 0.5:
68 | # print(f'Worker {i} assigned to task {j}.' +
69 | # f' Cost: {costs[i][j]}')
70 | # else:
71 | # print('No solution found.')
72 | x_n.append(n)
73 | y_sum.append(solver.Objective().Value())
74 | n=10
75 | while(n<=100):
76 | main(n)
77 | n+=10
78 | plt.plot(x_n,y_sum, linewidth=1,c='red')
79 | plt.show()
--------------------------------------------------------------------------------
/src/ortooltest2.py:
--------------------------------------------------------------------------------
1 | from ortools.linear_solver import pywraplp
2 | from num import A_2060
3 | from num import A_40200
4 | from num import A_50500
5 |
6 | def main():
7 | # Data
8 | costs=A_2060
9 | num_workers = len(costs)
10 | num_tasks = len(costs[0])
11 | group=4
12 | groupnum=int(num_tasks/group)
13 |
14 | # Solver
15 | # Create the mip solver with the SCIP backend.
16 | solver = pywraplp.Solver.CreateSolver('SCIP')
17 |
18 | if not solver:
19 | return
20 |
21 | # Variables
22 | # x[i, j] is an array of 0-1 variables, which will be 1
23 | # if worker i is assigned to task j.
24 | x = {}
25 | for i in range(num_workers):
26 | for j in range(num_tasks):
27 | x[i, j] = solver.IntVar(0, 1, '')
28 |
29 | # Constraints
30 | # Each worker is assigned to at most 1 task.
31 | for i in range(num_workers):
32 | solver.Add(solver.Sum([x[i, j] for j in range(num_tasks)]) <= 3)#载核限制
33 | for k in range(group):
34 | solver.Add(solver.Sum([x[i, j] for j in range(k*groupnum,(k+1)*groupnum)]) <= 1)#分组限制
35 | # Each task is assigned to exactly one worker.
36 | for j in range(num_tasks):
37 | solver.Add(solver.Sum([x[i, j] for i in range(num_workers)]) == 1)
38 |
39 | # Objective
40 | objective_terms = []
41 | for i in range(num_workers):
42 | for j in range(num_tasks):
43 | objective_terms.append(costs[i][j] * x[i, j])
44 | solver.Maximize(solver.Sum(objective_terms))
45 |
46 | # Solve
47 | status = solver.Solve()
48 |
49 | # Print solution.
50 | if status == pywraplp.Solver.OPTIMAL or status == pywraplp.Solver.FEASIBLE:
51 | print(f'Total cost = {solver.Objective().Value()}\n')
52 | for i in range(num_workers):
53 | for j in range(num_tasks):
54 | # Test if x[i,j] is 1 (with tolerance for floating point arithmetic).
55 | if x[i, j].solution_value() > 0.5:
56 | print(f'Worker {i} assigned to task {j}.' +
57 | f' Cost: {costs[i][j]}')
58 | else:
59 | print('No solution found.')
60 |
61 |
62 | if __name__ == '__main__':
63 | main()
--------------------------------------------------------------------------------
/src/test.py:
--------------------------------------------------------------------------------
1 | nu=20
2 | avef=4
3 | nt=60
4 | nf=5
5 | for j in range(nt): #第一轮价格一致阶段
6 | for f in range(nf): #每一个联邦进行价格一致
7 | print()
8 | for i in range(f*avef,(f+1)*avef):
9 | print(i,end='')
--------------------------------------------------------------------------------