算法解释
首先第一步要看懂的2-OPT的算法,不懂得参考链接:https://blog.youkuaiyun.com/qq_30008595/article/details/95033476
K-OPT的特点,就是把路径随机分成K段然后,然后调用2-OPT,由于有很多段,但不是每一段都要使用2-OPT,所以这产生了很多种组合方式:1段使用、2段使用…K段使用,所以,每一种都要尝试,若出现更优的路径,就留下来,不然就不留下来。
推荐一个paper(可能要翻墙):https://pdfs.semanticscholar.org/ab7c/c83bb513a91b06f6c8bc3b9da7f60cbbaee5.pdf
完整代码
import random
import numpy as np
import matplotlib.pyplot as plt
import TWOPT
from itertools import combinations, permutations
MAXCOUNT = 1
def KDevide(routes_length, k):
PartNumber = []
for i in range(len(routes_length)):
if len(PartNumber) == 0:
PartNumber.append(random.randint(0, len(routes_length) - 1))
else:
if PartNumber[i-1]+2 < len(routes_length) - 1:
PartNumber.append(random.randint(PartNumber[i-1]+2, len(routes_length) - 1))
else:
break
return PartNumber
def Update_routes(routes, PartNumber):
Part_Routes = []
# routes.remove(7)
for Part_i in range(len(PartNumber)):
if Part_i == 0:
Part_Route = routes[0:PartNumber[Part_i]]
Part_Routes.append(Part_Route)
continue
elif Part_i <= len(PartNumber) - 1:
print(Part_i, PartNumber[Part_i])
Part_Route = routes[PartNumber[Part_i-1]:PartNumber[Part_i]]
else:
break
if len(Part_Route) != 0:
Part_Routes.append(Part_Route)
print(PartNumber[-1])
if PartNumber[-1] != 7:
Part_Routes.append(routes[PartNumber[-1]:])
else:
Part_Routes.append([7])
return Part_Routes
def UpdatePartPath(bestPath, LocidList, durationlist):
count = 0
while count < MAXCOUNT:
start, end, path = TWOPT.generateRandomPath(bestPath)
rePath = TWOPT.reversePath(path)
print('path:', path,'repath:', rePath, 'end:', end)
if TWOPT.pathCompare(path, rePath, LocidList, durationlist):
count += 1
continue
else:
count = 0
print('path:', path, 'repath:', rePath, 'end:', end)
bestPath[start:end+1] = rePath
return bestPath
def Combination(Part_Routes):
Part = []
for i in range(len(Part_Routes)):
Part.append(i)
Modify_parts = []
for i in range(len(Part_Routes)):
Modify_parts.append(list(combinations(Part,i+1)))
return Modify_parts
#列举排列结果 Modify_parts: [[(1, 2)], [(1, 2), (2, 3)]] Modify_part: [(1, 2), (2, 3)]
def UpdateOnece(Modify_parts, Part_Routes):
temp = Part_Routes
UpdateRoutes = []
for Modify_part in Modify_parts:
for Modify_subpart in Modify_part:
Part_Routes = temp.copy()
for Modify_subsubpart in Modify_subpart:
Part_Routes[Modify_subsubpart] = TWOPT.reversePath(Part_Routes[Modify_subsubpart])
UpdateRoutes.append(Part_Routes)
return UpdateRoutes
def Merge(UpdateRoutes):
Merge_Routes = []
for UpdateRoute in UpdateRoutes:
Merge_Route = []
for SubUpdateRoute in UpdateRoute:
Merge_Route.extend(SubUpdateRoute)
Merge_Routes.append(Merge_Route)
return Merge_Routes
routes = ['40001', '40003', '40002', '40004', '40005', '40006', '40007', '40008']
(routes_pathindex, LocId, duration) = TWOPT.ProduceInput(routes)
k = KDevide(routes_pathindex, 4)
test = Update_routes(routes_pathindex, k)
result = UpdateOnece(Combination(test), test)
print(Merge(result))