yelp商家数据集上使用火算法求解TSP 问题

先简要回顾下什么是TSP问题, 旅行商问题(Traveling Salesman Problem,TSP)是一个经典的组合优化问题,广泛应用于运筹学、计算机科学和物流等领域。TSP的基本描述如下:

问题描述

  1. 定义:假设有一位旅行商需要访问一组城市(或地点),每个城市只能访问一次,最后旅行商需要返回到起始城市。
  2. 目标:找到一条最短的路径,使得旅行商能够访问所有城市一次,并返回起点。

yelp 数据集里yelp_academic_dataset_business.json 刚好有饭馆的位置信息

因此在该数据集上求解TSP 问题可以理解为找到最佳路线去吃遍所有馆子,嗯~吃货的最爱

本文就不赘絮退火算法的细节了,直接在yelp数据集上试验退火算法

把店铺的位置信息输出到csv文件总里

# coding=utf-8
import json
import csv  # Ensure this line is present to import the csv module# 读取JSON文件
with open('yelp_academic_dataset_business.json', 'r', encoding='utf-8') as file:businesses = []for line in file:business = json.loads(line)# 筛选出餐厅if 'Restaurants' in business['categories']:businesses.append({'name': business['name'],'latitude': business['latitude'],'longitude': business['longitude'],'id': business['business_id']})# 将餐厅信息输出到CSV文件
with open('restaurants.csv', 'w', newline='', encoding='utf-8') as csvfile:fieldnames = ['name', 'latitude', 'longitude', 'id']writer = csv.DictWriter(csvfile, fieldnames=fieldnames)writer.writeheader()  # 写入表头for business in businesses:writer.writerow(business)  # 写入每一行数据print("餐厅信息已成功输出到 restaurants.csv")

要使用退火算法处理从 restaurants.csv 文件中提取的位置信息,以解决旅行商问题(TSP),可以按照以下步骤进行:

步骤概述

  1. 读取CSV文件:加载餐厅位置信息,包括名称、纬度和经度。
  2. 计算距离:实现一个函数,计算餐厅之间的距离。
  3. 实现退火算法:使用退火算法寻找最佳巡游路径。
  4. 输出结果:打印最佳路径及其总距离。

# 计算两个餐厅之间的距离(Haversine公式)
def haversine(coord1, coord2):R = 6371  # 地球半径,单位为公里lat1, lon1 = coord1lat2, lon2 = coord2dlat = np.radians(lat2 - lat1)dlon = np.radians(lon2 - lon1)a = np.sin(dlat/2) ** 2 + np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) * np.sin(dlon/2) ** 2c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))return R * c

Haversine公式

  • 计算地球表面两点(餐厅)之间的距离。
  • 输入为两个坐标(纬度和经度),输出为两点之间的距离(公里)。
# 计算路径总长度
def total_distance(path):dist = 0for i in range(len(path)):dist += haversine((path[i]['latitude'], path[i]['longitude']),(path[(i + 1) % len(path)]['latitude'], path[(i + 1) % len(path)]['longitude']))return dist

路径长度计算

  • 遍历给定路径,计算从一个餐厅到下一个餐厅的总距离。
  • 使用Haversine公式,确保路径是循环的,即最后一个餐厅回到第一个餐厅。

退火算法实现

# 退火算法
def simulated_annealing(initial_path, initial_temp, cooling_rate, max_iterations):current_path = initial_pathcurrent_temp = initial_tempcurrent_dist = total_distance(current_path)best_path = current_path[:]best_dist = current_distfor iteration in range(max_iterations):# 生成新解new_path = current_path[:]i, j = random.sample(range(len(new_path)), 2)new_path[i], new_path[j] = new_path[j], new_path[i]  # 交换new_dist = total_distance(new_path)# 接受新解if new_dist < current_dist or random.random() < math.exp((current_dist - new_dist) / current_temp):current_path = new_pathcurrent_dist = new_dist# 更新最佳解if current_dist < best_dist:best_path = current_path[:]best_dist = current_dist# 降温current_temp *= cooling_ratereturn best_path, best_dist

  • 参数
    • initial_path:初始路径(餐厅顺序)。
    • initial_temp:初始温度,用于控制接受新解的概率。
    • cooling_rate:降温速率,控制温度下降的速度。
    • max_iterations:最大迭代次数。
  • 过程
    • 初始化当前路径和距离为初始路径和计算的总距离。
    • 进行多次迭代:
      • 生成新路径,通过随机交换路径中的两个餐厅。
      • 计算新路径的总距离。
      • 根据接受准则决定是否接受新路径:
        • 如果新路径更短,则直接接受。
        • 如果新路径更长,则以一定概率接受(根据当前温度计算)。
      • 更新当前路径和最佳路径。
      • 降温,逐步减少温度。
# 初始化参数
initial_path = restaurants[:]  # 使用所有餐厅
random.shuffle(initial_path)  # 随机打乱初始路径
best_path, best_distance = simulated_annealing(initial_path, initial_temp=1000, cooling_rate=0.995, max_iterations=10000)

参数设置

  • 使用所有餐厅的初始路径。
  • 随机打乱路径顺序以增加多样性。
  • 调用退火算法并获取最佳路径和最短距离。

完整代码如下

import csv
import numpy as np
import random
import math
import matplotlib.pyplot as plt
import seaborn as sns
from tqdm import tqdm  # 导入 tqdm 库# 读取CSV文件
restaurants = []
with open('restaurants.csv', 'r', encoding='utf-8') as csvfile:reader = csv.DictReader(csvfile)for row in reader:restaurants.append({'name': row['name'],'latitude': float(row['latitude']),'longitude': float(row['longitude']),'id': row['id']})def haversine(coord1, coord2):R = 6371  # 地球半径,单位为公里lat1, lon1 = coord1lat2, lon2 = coord2dlat = np.radians(lat2 - lat1)dlon = np.radians(lon2 - lon1)a = np.sin(dlat/2) ** 2 + np.cos(np.radians(lat1)) * np.cos(np.radians(lat2)) * np.sin(dlon/2) ** 2c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))return R * cdef total_distance(path):dist = 0for i in range(len(path)):dist += haversine((path[i]['latitude'], path[i]['longitude']),(path[(i + 1) % len(path)]['latitude'], path[(i + 1) % len(path)]['longitude']))return distdef simulated_annealing(initial_path, initial_temp, cooling_rate, max_iterations):current_path = initial_pathcurrent_temp = initial_tempcurrent_dist = total_distance(current_path)best_path = current_path[:]best_dist = current_dist# 记录每次迭代的路径和距离distances = []# 使用 tqdm 显示进度条for iteration in tqdm(range(max_iterations), desc="优化进度"):new_path = current_path[:]i, j = random.sample(range(len(new_path)), 2)new_path[i], new_path[j] = new_path[j], new_path[i]  # 交换new_dist = total_distance(new_path)if new_dist < current_dist or random.random() < math.exp((current_dist - new_dist) / current_temp):current_path = new_pathcurrent_dist = new_distif current_dist < best_dist:best_path = current_path[:]best_dist = current_dist# 记录当前距离distances.append(current_dist)current_temp *= cooling_ratereturn best_path, best_dist, distances# 初始化参数
initial_path = restaurants[:]
random.shuffle(initial_path)
best_path, best_distance, distances = simulated_annealing(initial_path, initial_temp=1000, cooling_rate=0.995, max_iterations=10000)# 输出结果
print("最佳路径:")
for restaurant in best_path:print(restaurant['name'])
print("最短距离: {:.2f} 公里".format(best_distance))

添加热力图,热力图将显示每次迭代中路径的总距离,横轴表示迭代次数,纵轴表示路径总距离。通过这种可视化,您可以直观地观察到退火算法在求解过程中如何逐步降低路径总距离。

# 可视化热力图
plt.figure(figsize=(12, 6))
sns.heatmap(np.array(distances).reshape(-1, 1), cmap='YlGnBu', cbar=True)
plt.title('退火算法迭代过程中的路径总距离变化')
plt.xlabel('迭代次数')
plt.ylabel('路径总距离')
plt.show()
  1. 记录距离变化

    • simulated_annealing 函数中,增加了一个 distances 列表,用于记录每次迭代的总距离。
  2. 绘制热力图

    • 使用 Matplotlib 和 Seaborn 库绘制热力图:将 distances 列表转换为 NumPy 数组,并重塑为适合热力图的形状(这里是单列)。使用 sns.heatmap 绘制热力图,显示路径总距离的变化。

开始优化求解

求解顺序

热力图效果distance单列优化并不明显,毕竟饭馆的分布太分散了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10419.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习目标检测|YOLO算法1】YOLO家族进化史:从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析...

【深度学习目标检测|YOLO算法1】YOLO家族进化史&#xff1a;从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析… 【深度学习目标检测|YOLO算法1】YOLO家族进化史&#xff1a;从YOLOv1到YOLOv11的架构创新、性能优化与行业应用全解析… 文章目录 【深度学习目标检测|YOL…

星期-时间范围选择器 滑动选择时间 最小粒度 vue3

星期-时间范围选择器 功能介绍属性说明事件说明实现代码使用范例 根据业务需要&#xff0c;实现了一个可选择时间范围的周视图。用户可以通过鼠标拖动来选择时间段&#xff0c;并且可以通过快速选择组件来快速选择特定的时间范围。 功能介绍 时间范围选择&#xff1a;用户可以…

Java | Leetcode Java题解之第554题砖墙

题目&#xff1a; 题解&#xff1a; class Solution {public int leastBricks(List<List<Integer>> wall) {Map<Integer, Integer> cnt new HashMap<Integer, Integer>();for (List<Integer> widths : wall) {int n widths.size();int sum 0…

牛客小白月赛104 —— C.小红打怪

C.小红打怪 1.题目&#xff1a; 2.样例 输入 5 1 2 3 4 5 输出 2 说明 第一回合&#xff0c;小红攻击全体怪物&#xff0c;队友1攻击5号怪物&#xff0c;队友2攻击4号和5号怪物&#xff0c;剩余每只怪物血量为[0,1,2,2,2]。 第二回合&#xff0c;小红攻击全体怪物&#…

python画图|text()和dict()初探

【1】引言 在进行hist()函数的学习进程中&#xff0c;了解到了subplot_mosaic()函数&#xff0c;在学习subplot_mosaic()函数的时候&#xff0c;又发现了text()和dict()函数。 经探究&#xff0c;text()和dict()函数有很多一起使用的场景&#xff0c;为此&#xff0c;我们就一…

BUG: scheduling while atomic

▌▌上篇文章的内容还没有结束 中断处理函数中如果执行了调度&#xff0c;会发生什么 ▌这次&#xff0c;我修改了程序&#xff0c;在中断处理函数中调用了msleep 程序执行后&#xff0c;会有这样的日志 ▌关键就是这句 BUG: scheduling while atomic 我们追代码&#xff0c;可…

算法 -选择排序

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【算法】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 文章目录 &#x1f4a1;选择排序1. &#x1f504; 选择排序&#x1f5bc;️示意图&#x1f4d6;简介&#x1f4a1;实现思路1&#x1f4bb;代码实现1&#x1f4a1;实现思路2…

ubuntu 22.04 镜像源更换

双11抢了个云服务器&#xff0c;想要整点东西玩玩&#xff0c;没想到刚上来就不太顺利 使用sudo apt update更新软件&#xff0c;然后发生了如下报错 W: Failed to fetch http://mirrors.jdcloudcs.com/ubuntu/dists/jammy/InRelease 理所当然想到可能是镜像源连接不是很好&…

2016年7月29日至2017年2月21日NASA大气层层析(ATom)任务甲醛(HCHO)、羟基(OH)和OH生产率的剖面积分柱密度

目录 简介 摘要 引用 网址推荐 知识星球 机器学习 ATom: Column-Integrated Densities of Hydroxyl and Formaldehyde in Remote Troposphere ATom&#xff1a; 远对流层中羟基和甲醛的柱积分密度 简介 该数据集提供了甲醛&#xff08;HCHO&#xff09;、羟基&#xff…

一夜吸粉10万!AI妖精变身视频如何做的?5分钟你也能赶上末班车!

本文背景 最近有小伙伴跟我发了一个AI视频&#xff0c;问我是怎么做的&#xff1f; 很多人在各大自媒体平台&#xff0c;像某音、蝴蝶号都刷到过下面这种妖精变身的短视频。 我也常刷到&#xff0c;从这类视频能看到点赞、收藏、评论的数据都特别高&#xff0c;动不动就几千、几…

【JAVA项目】基于jspm的【医院病历管理系统】

技术简介&#xff1a;采用jsp技术、MySQL等技术实现。 系统简介&#xff1a;通过标签分类管理等方式&#xff0c;实现管理员&#xff1b;个人中心、医院公告管理、用户管理、科室信息管理、医生管理、出诊信息管理、预约时间段管理、预约挂号管理、门诊病历管理、就诊评价管理、…

Oasis:首个可玩的AI生成互动游戏

游戏玩法介绍 Oasis 是由AI公司Decart开发的一款实时生成、可交互的Minecraft风格游戏。这款游戏利用生成式AI技术,创造出独特的“开放世界”体验。Oasis基于大量Minecraft游戏视频进行训练,通过键盘和鼠标输入实时生成游戏画面,模拟物理效果、规则及视觉效果。用户在游戏中…

Python网络爬虫入门篇!

预备知识 学习者需要预先掌握Python的数字类型、字符串类型、分支、循环、函数、列表类型、字典类型、文件和第三方库使用等概念和编程方法。 2. Python爬虫基本流程 a. 发送请求 使用http库向目标站点发起请求&#xff0c;即发送一个Request&#xff0c;Request包含&#xf…

【C++】踏上C++学习之旅(五):auto、范围for以及nullptr的精彩时刻(C++11)

文章目录 前言1. auto关键字&#xff08;C11&#xff09;1.1 为什么要有auto关键字1.2 auto关键字的使用方式1.3 auto的使用细则1.4 auto不能推导的场景 2. 基于范围的for循环&#xff08;C11&#xff09;2.1 范围for的语法2.2 范围for的使用条件 3. 指针空值nullptr&#xff0…

科研绘图系列:R语言组合多个不同图形(violin density barplot heatmap)

文章目录 介绍加载R包数据下载函数图1: Boxplots导入数据数据预处理画图图2: Violin导入数据数据预处理画图图3: Density plots per habitat数据预处理画图图4: Density plots per depth数据预处理画图图5: bar plot准备颜色导入数据数据预处理数据预处理画图图6: Mantel Heat…

系统聚类的分类数确定——聚合系数法

breast_cancer数据集分析——乳腺癌诊断 #读取乳腺癌数据 import pandas as pd import numpy as np from sklearn.datasets import load_breast_cancer data load_breast_cancer() X data.data y data.target.. _breast_cancer_dataset:Breast cancer wisconsin (diagnosti…

jsp+sevlet+mysql实现用户登陆和增删改查功能

jspsevletmysql实现用户登陆和增删改查功能 一、系统介绍二、功能展示1.用户登陆2.用户列表3.查询用户信息4.添加用户信息5.修改用户信息6.删除用户信息 四、其它1.其他系统实现 一、系统介绍 系统主要功能&#xff1a; 用户登陆、添加用户、查询用户、修改用户、删除用户 二…

一文了解Java序列化

Java 序列化&#xff08;Serialization&#xff09;是将对象的状态转换为字节流&#xff0c;以便将对象的状态保存到文件中或通过网络传输的过程。反序列化&#xff08;Deserialization&#xff09;则是将字节流恢复为原始对象。Java 序列化主要通过 Serializable 接口实现。 为…

斗破QT编程入门系列之前言:认识Qt:获取与安装(四星斗师)

本系列是在学习完C之后&#xff0c;然后通过Qt构建界面来&#xff0c;赋予枯燥的代码新的样貌&#xff0c;这样我们才能开发出更人性化的程序&#xff0c;同时会进一步提高初学者对编程的兴趣&#xff0c;大家加油&#xff0c;斗破Qt来了。 斗破Qt目录&#xff1a; 斗破Qt编程…

Spring Boot - 扩展点 EnvironmentPostProcessor源码分析及真实案例

文章目录 概述EnvironmentPostProcessor 作用EnvironmentPostProcessor 实现和注册创建类并实现接口注册到 Spring Boot常见应用场景 源码分析1. EnvironmentPostProcessor 接口定义2. 扩展点加载流程3. 加载 EnvironmentPostProcessor 实现类4. EnvironmentPostProcessor 执行…