(u,v),(next_u,w),(next_v,next_w) 16 restart = True while restart: restart = False nbhd = ((i,j,k) for i in range(num_node) for j in range(i+2,num_node) for k in range(j+2,num_node)) for i,j,k in nbhd: # evaluate difference delta, oper = eval_diff(tour,i,j,k) if delta < 0: # change tour change_tour(tour,i,j,k,oper) restart = True break 3-opt近傍⾛査の⼿続き operでtype1-4を指定 def eval_diff(tour, i, j, k): best, arg_best = float('inf'), None u, next_u = tour[i], tour[(i+1) % num_node] v, next_v = tour[j], tour[(j+1) % num_node] w, next_w = tour[k], tour[(k+1) % num_node] cur = calc_dist(u,next_u) + calc_dist(v,next_v) + calc_dist(w,next_w) new = calc_dist(u,next_v) + calc_dist(v,next_w) + calc_dist(w,next_u) if new - cur < best: best, arg_best = new - cur, 'type1' new = calc_dist(u,w) + calc_dist(next_v,next_u) + calc_dist(v,next_w) if new - cur < best: best, arg_best = new - cur, 'type2' new = calc_dist(u,next_v) + calc_dist(w,v) + calc_dist(next_u,next_w) if new - cur < best: best, arg_best = new - cur, 'type3' new = calc_dist(v,u) + calc_dist(next_w,next_v) + calc_dist(w,next_u) if new - cur < best: best, arg_best = new - cur, 'type4' return best, arg_best 巡回路⻑の差分計算 type1-4で最も良かった 近傍操作を返す