此算法能稳定求出柏林52城问题最优解7540.23(整数时为7538),比传统旅行商问题的算法7544.37还优

import math, time, random

from itertools import permutations

def rot(m, k):

mlen = len(m)

if k == 0: return m

return \[m\[(i-k)%mlen(j-k)%mlen for j in range(mlen)] for i in range(mlen)]

def cs(m, ker):

ml, kl = len(m), len(ker)

res = 0

for i in range(ml - kl + 1):

for ki in range(kl):

res += mi+kii+ki * kerkiki

return res

def tsp(b52, s, e, k):

st = time.time()

n = len(b52)

d = \[0*n for _ in range(n)]

for i in range(n):

x1, y1 = b52i

for j in range(i+1, n):

x2, y2 = b52j

dist = int(math.hypot(x1-x2, y1-y2))

dij = dji = dist

sidx = \[\]

for i in range(n):

r = (d\[ij, j) for j in range(n) if j != i]

r.sort()

sidx.append(idx for _, idx in r)

wm = \[\]

for c in range(n):

o = sidxc

m = n-1

mat = \[0*m for _ in range(m)]

for i in range(m):

for j in range(m):

if i != j: matij = 1 if oi > oj else 0

wm.append(mat)

ce = \[set() for _ in range(n) for __ in range(n)]

cf = [

\[0.5, -0.5\], \[-0.5, 0.5\]

] + [

\[0.5, -0.5, 0.5\], \[-0.5, 0.5, -0.5\], \[0.5, -0.5, 0.5\]

]

for fl in cf:

ns = \[\]

for c in range(n):

mat = wmc

sc = (cs(rot(mat, r), fl), r) for r in range(n-1)

sc.sort(reverse=True)

ns.append(sc:k)

for i in range(n):

for sc, r in nsi:

j = sidxir

ceij.add(r)

if len(ceij) > k:

ceij = set(list(ceij):k)

ec = \[\[ for _ in range(n)] for __ in range(n)]

for i in range(n):

if i != s:

for j in range(n):

if i != j and ceij:

for r in sorted(list(ceij)):k:

ecij.append(sidxir)

p = s

v = False*n

vs = True

for _ in range(n-1):

u = p-1

nn = vb for vl in ec\[u for vb in vl if vb and not vvb]

if not nn:

nn = vb for vb in range(n) if not v\[vb]

p.append(nn0)

vp\[-1] = True

p.append(e)

def cpd(pth):

return sum(dpth\[i]pth\[i+1] for i in range(len(pth)-1))

bd = cpd(p)

imp = True

mx = 1000

cnt = 0

while imp and cnt < mx:

imp = False

cnt += 1

for i in range(1, len(p)-2):

for j in range(i+1, len(p)-1):

dt = dp\[i-1]p\[j] + dp\[i]p\[j+1] - dp\[i-1]p\[i] - dp\[j]p\[j+1]

if dt < 0:

pi:j+1 = pi:j+1::-1

bd += dt

imp = True

return bd, p, time.time()-st,n

def c(p, e, D):

return sum(Dp\[i]p\[i+1] for i in range(len(p)-1)) + Dp\[-1]e

def g(k, ei):

el, ci = len(ei), 0

eg = {u: \[\] for u in range(k)}

for (u, v), i in ei.items():

egu.append(i)

ud = set()

for ids in eg.values():

for i in ids:

while True:

pb = (i << 1) | random.getrandbits(1)

if pb not in ud:

ud.add(pb)

ci |= (pb & 1) << i

break

if k >= 2:

u1, u2 = random.sample(range(k), 2)

df = len(egu1) - len(egu2)

if abs(df) <= math.isqrt(k):

elc = int(abs(math.sin(k) * df))

if elc > 0:

src = u2 if df > 0 else u1

ai = random.sample(egsrc, min(elc, len(egsrc)))

ci |= sum(1 << i for i in ai) if df > 0 else ~sum(1 << i for i in ai)

ec = {}

ci %= 1 << el

for (u, v), i in ei.items():

ec(u, v) = ec(v, u) = (ci >> i) & 1

return ec

def o(p, D):

imp = True

while imp:

imp = False

for i in range(1, len(p) - 2):

for k in range(i + 2, len(p)):

if Dp\[i-1]p\[i] + Dp\[k-1]p\[k] > Dp\[i-1]p\[k-1] + Dp\[i]p\[k]:

pi:k = pi:k::-1

imp = True

return p

berlin52=(565.0,575.0),(25.0,185.0),(345.0,750.0),(945.0,685.0),(845.0,655.0),(880.0,660.0),(25.0,230.0),(525.0,1000.0),(580.0,1175.0),(650.0,1130.0),(1605.0,620.0),(1220.0,580.0),(1465.0,200.0),(1530.0,5.0),(845.0,680.0),(725.0,370.0),(145.0,665.0),(415.0,635.0),(510.0,875.0),(560.0,365.0),(300.0,465.0),(520.0,585.0),(480.0,415.0),(835.0,625.0),(975.0,580.0),(1215.0,245.0),(1320.0,315.0),(1250.0,400.0),(660.0,180.0),(410.0,250.0),(420.0,555.0),(575.0,665.0),(1150.0,1160.0),(700.0,580.0),(685.0,595.0),(685.0,610.0),(770.0,610.0),(795.0,645.0),(720.0,635.0),(760.0,650.0),(475.0,960.0),(95.0,260.0),(875.0,920.0),(700.0,500.0),(555.0,815.0),(830.0,485.0),(1170.0,65.0),(830.0,610.0),(605.0,625.0),(595.0,360.0),(1340.0,725.0),(1740.0,245.0)

print("TSP问题求解 - 柏林52个城市")

print("正在计算基础解...")

s=0

se=0

base_dist, base_path, base_time,n = tsp(berlin52, s, se, 1000)

d = \[0*n for _ in range(n)]

for i in range(n):

x1, y1 = berlin52i

for j in range(i+1, n):

x2, y2 = berlin52j

dij = dji = ((x1 - x2)**2 + (y1 - y2)**2)**0.5

print(f"基础解距离: {base_dist:.2f}, 耗时: {base_time:.4f}s")

print(f"基础路径: {base_path}")

st = time.time()

dt0 = sorted((di0, i) for i in range(1, n))

df0 = sorted((d0i, i) for i in range(1, n))

rt0 = {idx: r+1 for r, (_, idx) in enumerate(dt0)}

rf0 = {idx: r+1 for r, (_, idx) in enumerate(df0)}

vn = \[\]

for i in range(1, n):

a, b = rt0i, rf0i

fd = False

for m in range(1, b):

for t in range(1, 3):

if (m * (a**t)) % b == 0:

vn.append(i)

fd = True

break

if fd:break

vn = vn if vn else list(range(1, n))

bp = base_path

bd = base_dist

ei = {}

idx = 0

for i in range(n):

for k in range(i+1, n):

ei(i, k) = idx

idx += 1

opt2_cnt = 0

for _ in range(50):

random.seed()

for _ in range(50):

ec = g(n, ei)

random.shuffle(vn)

p = s + vn + se

gss = \[ for _ in range(2)]

for nd in vn:gssec.get((nd % n, (nd + 1) % n), 0).append(nd)

np = s

for gs in gss:

if gs:np.extend(random.sample(gs, len(gs)))

np.append(se)

cd = c(np, se, d)

if cd < bd * 4:

np = o(np, d)

opt2_cnt += 1

cd = c(np, se, d)

if cd < bd:

bd = cd

bp = np

print(f"\n优化后结果:")

print(f"{n}节点 起点:{s} 终点:{se}")

print(f"最优路径: {bp}")

print(f"最优距离: {bd}")

print(f"总时间: {time.time()-st:.2f}s")

print(f"opt2调用次数: {opt2_cnt}")

相关推荐
hhzz1 小时前
基于监控视频的水位尺自动识别技术方案与实现
python·opencv·yolo·图像识别·cv
yongche_shi1 小时前
ragas官方文档中文版(五十)
开发语言·python·ai·ragas·如何评估和改进 rag 应用
前端之虎陈随易1 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
一路向北he1 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
QiLinkOS2 小时前
第三视觉理解徐玉生与他的商业活动(30)
大数据·c++·人工智能·算法·开源协议
kyriewen2 小时前
豆包和千问同时关了智能体,我用它们搭的 3 个自动化全废了——迁移方案整理
前端·javascript·ai编程
疯狂打码的少年2 小时前
【操作系统】页面置换算法(OPT/FIFO/LRU)
算法
前端一小卒2 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
小O的算法实验室2 小时前
2026年CIE,优化客货协同运输:综合地铁系统的列车容量动态分配
算法
weixin_408099672 小时前
OCR批量识别图片方案:从手动处理到自动化API系统(Python/Java/PHP实战)
图像处理·python·ocr·文字识别·api调用·批量识别·石榴智能