├── .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 | ![p](pic/model.png) 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 | ![p](pic/simulation.png) 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='') --------------------------------------------------------------------------------