1046. Shortest Distance 解析

本文介绍了一种计算环形路径中两点间最短距离的算法,通过累加节点间的距离并利用环形特性来确定顺时针或逆时针方向上的最短路径。

问题是一个环中的亮点,怎么走最近的问题。

一个环中的亮点肯定是有两条路径的,一个顺时针,一个逆时针,两者的和等于环的长度。

有了这一点,我们就好做了。

在读入数据的时候我们就累加posd【i】表示从【1】到【i】的顺时针的距离。

那么从【a】到【b】的距离就等于posd【b】-posd【a】,另一段就不用说了。两个求最小。


#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <queue>
#include <stack>
#include <cstring>

#define MAX 100010

using namespace std;
int N,M;
int d[MAX];
int pos[MAX],rev[MAX];

int main(){

	scanf("%d",&N);
	int dis = 0;
	for(int i = 1 ;i <= N ;i++){
		pos[i] = dis;
		scanf("%d",&d[i]);
		dis += d[i];
	}
	int sumLen = dis;
	
	
	scanf("%d",&M);
	int a,b;
	int ans;
	for(int i = 0 ;i < M ;i++){
		scanf("%d%d",&a,&b);
		int posd = abs(pos[a]-pos[b]);
		ans = min(posd,sumLen-posd);
		printf("%d\n",ans);
	}


	return 0 ;
}


import numpy as np import matplotlib.pyplot as plt import pandas as pd def calc_distance(city1, city2): return np.linalg.norm(np.array(city1) - np.array(city2)) def calc_distances(cities): n_cities = len(cities) distances = np.zeros((n_cities, n_cities)) for i in range(n_cities): for j in range(i + 1, n_cities): distances[i][j] = distances[j][i] = calc_distance(cities[i], cities[j]) return distances class AntColony: def __init__(self, distances, n_ants, n_iterations, decay, alpha=1, beta=5, rho=0.1, Q=1): self.distances = distances self.pheromone = np.ones_like(distances) / len(distances) self.n_ants = n_ants self.n_iterations = n_iterations self.decay = decay self.alpha = alpha self.beta = beta self.rho = rho self.Q = Q self.shortest_path_lengths = [] def run(self): shortest_path = None shortest_path_length = np.inf for _ in range(self.n_iterations): all_paths = self.gen_all_paths() self.spread_pheromone(all_paths) shortest_path, shortest_path_length = self.get_shortest(all_paths, shortest_path, shortest_path_length) self.pheromone *= (1 - self.rho) self.shortest_path_lengths.append(shortest_path_length) return shortest_path, shortest_path_length def spread_pheromone(self, all_paths): for path in all_paths: for move in path: self.pheromone[move] += self.Q / self.distances[move] def gen_path_dist(self, path): total = 0 for move in path: total += self.distances[move] return total def gen_all_paths(self): all_paths = [] for _ in range(self.n_ants): path = self.gen_path() all_paths.append(path) return all_paths def gen_path(self): n_cities = len(self.distances) path = [] visited = set() start = np.random.randint(n_cities) visited.add(start) prev = start for _ in range(n_cities - 1): next_city = self.pick_city(prev, visited) path.append((prev, next_city)) prev = next_city visited.add(next_city) path.append((prev, start)) return path def pick_city(self, prev, visited): pheromone = np.copy(self.pheromone[prev]) pheromone[list(visited)] = 0 row = pheromone ** self.alpha * (1.0 / (self.distances[prev] + 1e-6) ** self.beta) norm_row = row / row.sum() next_city = np.random.choice(range(len(self.distances)), 1, p=norm_row)[0] return next_city def get_shortest(self, all_paths, shortest_path, shortest_path_length): for path in all_paths: path_dist = self.gen_path_dist(path) if path_dist < shortest_path_length: shortest_path = [(int(a), int(b)) for (a, b) in path] shortest_path_length = path_dist return shortest_path, shortest_path_length try: df = pd.read_excel("100个城市的坐标.xlsx", header=None) cities = df.iloc[:, [0, 1]].values assert cities.shape[1] == 2, "坐标数据必须包含X,Y两列" except FileNotFoundError: print("错误:Excel文件未找到,请检查以下事项:") print("1. 文件是否位于当前工作目录") print("2. 文件名是否为'100个城市的坐标.xlsx'") print("3. 文件扩展名是否正确(.xlsx)") exit() except Exception as e: print(f"数据加载失败:{str(e)}") exit() # 计算距离矩阵 distances = calc_distances(cities) # 参数设置 n_ants = 20 n_iterations = 1000 decay = 0.1 alpha = 1 beta = 2 rho = 0.1 Q = 1 # 创建并运行蚁群算法 ant_colony = AntColony(distances, n_ants, n_iterations, decay, alpha, beta, rho, Q) shortest_path, shortest_path_length = ant_colony.run() # 输出结果 print("最短路径:", shortest_path) print("最短路径长度:", shortest_path_length) # 绘制迭代曲线 plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示 plt.rcParams['axes.unicode_minus'] = False plt.figure(figsize=(10, 5)) plt.plot(range(1, n_iterations + 1), ant_colony.shortest_path_lengths) plt.xlabel('迭代') plt.ylabel('最短路径长度') plt.title('优化过程') plt.grid(True) plt.show() # 路径可视化函数 def plot_path(cities, path): path_order = [path[0][0]] + [move[1] for move in path] x, y = cities[path_order, 0], cities[path_order, 1] plt.figure(figsize=(12, 8)) # 绘制城市点并添加编号(从1开始) for idx, (xi, yi) in enumerate(cities): plt.scatter(xi, yi, color='red', s=6,zorder=2) plt.text(xi, yi, str(idx + 1), fontsize=8,ha='center',va='bottom', color='black',zorder=3) # 绘制路径连线 plt.rcParams['font.sans-serif'] = 'SimHei' # 设置中文显示 plt.rcParams['axes.unicode_minus'] = False plt.plot(x, y, linestyle='-', marker='o', color='blue', linewidth=1, markersize=4, zorder=1) plt.xlabel('X坐标', fontsize=12) plt.ylabel('Y坐标', fontsize=12) plt.title('最佳路线 城市编号(1-100)', fontsize=14) plt.grid(True, linestyle='--', alpha=0.7) plt.tight_layout() plt.show() plot_path(cities, shortest_path) 修改路径输出格式为:最短路径序列: 40,41,95,13,16,66,96,56,85,97,27,38,10,64,5,81,57,71,51,72,8,49,29,2,50,4,12,61,62,92,22,79,80,21,83,7,17,9,63,43,32,37,19,24,54,69,58,11,74,59,68,89,87,53,23,84,67,0,34,33,60,86,47,90,42,82,77,25,28,36,31,1,44,76,6,93,30,52,18,14,39,98,88,26,75,3,20,73,91,65,48,99,78,70,45,35,94,15,46,55 最短路径长度: 8302.192271155956
最新发布
05-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值