学校“数据结构”课程Project—扩展功能(自主设计)
目录
一、设想功能描述
想法缘起
目标功能
二、问题抽象
三、算法设计和优化
1. 易想的朴素搜索 / dp
搜索想法
动态规划(dp)想法
2. 思考与优化
四、算法实现
五、结果示例
附:使用的地图API
一、设想功能描述
想法缘起
-
OSM 导出的地图数据中有 “amenity”(便民设施)点,并在
<tag k="amenity" v="..."/>中标记了每个 amenity 的具体类型,比如:fast_food,pub,toilets……

-
而人们在路途或旅途中,常常关注最近的某种类型(常为 amenity,如卫生间、停车车场)的最近处,而尚未明确目的地。从而容易想到去设计一个扩展功能:给定 amenity,查询距离当前点最近的该类的点。显然,这个问题仍用 Dijkstra 求单源最短路即可。
-
然而,有时人们想连续去多个便民点,比如:先去停车场停车再去吃饭,最后逛逛周边的公园等等。为了提高效率与体验,很可能需要一个总路程最短的方案,这就是该 “扩展功能” 考虑的问题。
目标功能
★ 用户给定当前位置,并指定一个 amenity 种类的顺序。求出最短路线,并呈现在地图上。

二、问题抽象
地图上有某些点带有颜色。给出起点 s 与颜色序列 ,尽可能快地求出一条以 s 为起点的最短路线
,要求其依次经过颜色为
的点。
存在数据约束与特征:,其中
为
颜色点集,此外,各种颜色的点大致均匀分布。

三、算法设计和优化
1. 易想的朴素搜索 / dp
搜索想法
直接以每个 为阶段,进行深度优先搜索(DFS),这部分时间复杂度已经有
,虽然可以进行剪枝,即当前搜素的长度
cur 超过搜到的最短长度 res,就直接 return,但光这样时间复杂度不变的。
动态规划(dp)想法
以每个 为阶段设计 dp,易得状态转移方程类似如下形式:
然而,显然其时间复杂度是同搜索的,而且还很难剪枝,所以比搜索更差。
此外,还要计算中间相邻颜色两点的最短路,从而全求出来的时间复杂度应比上面更大,空间复杂度亦大。
2. 思考与优化
直观地,最终答案的路线几乎不可能 “兜得很远”,这启发我们优化搜索顺序。对于每个 ,我们考虑先走到离最近的
搜索下去,回溯后再搜次近的
……可以想象这样搜出来的前几条路已经得到或较接近最终答案。进一步来看,又因为各种颜色的点大致均匀分布,所以这样的剪枝效果一定是非常显著的。
不过,如何求出搜 的顺序?其实我们完全不必先预处理出最短路然后排序。注意到 Dijkstra 的最短路算法就是按照距离由到达的顺序得到 “确定点” 的。所以,我们把 Dijkstra 算法 “嵌入” 搜索框架之中,从当前
做 Dijkstra,遍历到一个下一颜色的
,我们就从
递归进行搜索。这样相当于又解决了花大代价计算最短路的问题。

总之,本问题基于搜索的大框架,而其内部融入 Dijkstra,每个结点处的下一个点通过 Dijkstra 确定,当前搜索路上的每个点都保留了一个 Dijkstra 状态。
四、算法实现
关键在于构建搜索的代码,尤其是解决 “每一层” 都在做 Dijkstra 带来的问题。
原始 Dijkstra 只有一个答案数组 d[MAXN] ,这里我们显然需要多个,不过我们若开 n 个这样的数组,内存开销较大,且可能不易扩展。注意到 {d[u], u} 保留在原始 Dijkstra 的 std::priority_queue 中,我们可以用 std::set 代替这个 std::priority_queue,既可以取出最小值,又存下来当前有用的 {d[u], u} 且能 std::find 得到 {d[v], v},而 vis 数组可用 std::unordered_set 代替。
这样,我们相当于仅在搜索路上开 C++ 的容器,空间开销显著减小而并未增大过多增加时间常数,且易于扩展。
void DFS(int s, int x, double cur) {if (x == Ord.size()) { // ... }set<pair<double, int>> d; d.insert({0.0, s});unordered_set<int> vis;while (d.size()) {int u = d.begin()->second;double dis = d.begin()->first;if (cur + dis > ans) return;
d.erase(d.begin());if (vis.find(u) != vis.end()) continue;vis.insert(u);auto itt = M.p[u].Ames.find(Ord[x]);if (itt != M.p[u].Ames.end()) {curOrd.push_back(u);DFS(u, x+1, cur+dis);curOrd.pop_back();}
for (int e = M.head[u]; e; e = M.nxt[e]) {// ...auto it = d.upper_bound({-1.0, v});if (it==d.end() || it->second!=v || dis+w<it->first) d.insert({dis+w, v});}}
}
五、结果示例
-
n=6:起点在徐家汇一带,(较为随意地)指定下面 6 个 Amenity Type 的顺序:

附:使用的地图API
基于 Leaflet.js 库的 Python 交互式地图包 Folium
相关文章:
学校“数据结构”课程Project—扩展功能(自主设计)
目录 一、设想功能描述 想法缘起 目标功能 二、问题抽象 三、算法设计和优化 1. 易想的朴素搜索 / dp 搜索想法 动态规划(dp)想法 2. 思考与优化 四、算法实现 五、结果示例 附:使用的地图API 一、设想功能描述 想法缘起 OSM 导出…...
从0开始搭建若依微服务项目 RuoYi-Cloud(保姆式教程 一)
掌握陌生项目解读技巧 掌握若依(RuoYi-Cloud)框架 掌握SpringCloud Alibaba体系项目开发套路,结合我之前所有企业项目来学习就知道有多么简单。 一、框架介绍 1. 简介 一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空…...
【Chrome】浏览器怎么清除缓存并强制刷新
文章目录 1、正常刷新:正常刷新网页,网页有缓存则采用缓存。 F5 或 刷新键2、强制刷新:忽略缓存刷新,重新下载资源不用缓存。 CtrlF5 或 ShiftF5 或 CtrlShiftR3、在浏览器的设置里面清除所有数据...
Android创建保存Excel文件
Android开发生成保存Excel文件,首先下载两个jar包。下载地址:Android读写Excel文件的两个jar包资源-CSDN文库 poi-3.12-android-a.jar poi-ooxml-schemas-3.12-20150511-a.jar 把jar包放在app的libs文件夹下,引用jar我一般都在build.gradle的…...
Selenium + Django + Echarts 实现亚马逊商品数据可视化爬虫项目
最近完成了1个爬虫项目,记录一下自己的心得。 项目功能简介 根据用户输入商品名称、类别名称,使用Selenium, BS4等技术每天定时抓取亚马逊商品数据,使用Pandas进行数据清洗后保存在MySql数据库中. 使用Django提供用户端功能,显…...
【深度学习】初识深度学习
初识深度学习 什么是深度学习 关系: #mermaid-svg-7QyNQ1BBaD6vmMVi {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-7QyNQ1BBaD6vmMVi .error-icon{fill:#552222;}#mermaid-svg-7QyNQ1BBaD6vmMVi .err…...
探索 Xind3 生态系统,解锁铭文资产的新玩法
铭文市场的兴起,不仅是新资产发行方案向市场的代表,更是新资产革命的代表。通过“公平启动”的方式,任何人都可以按照先到先得的原则“铸造”资产。虽然这看起来是意识形态上的新升级,但实际上最火的铭文风潮是由CEX引发的。 我们…...
js有哪些内置对象?
在 JavaScript 中,内置对象可以分为三类:原始值的包装对象、构造函数和其他对象。这里列举一些常见的内置对象及其方法: 原始值的包装对象: String:字符串类型的包装对象,有 charAt、concat、indexOf、repl…...
拦截器的简单使用
拦截器的简单使用 拦截器的使用创建拦截器preHandle 目标方法执行前执行postHandle 目标方法执行后执行afterCompletion 视图渲染后执行 拦截器使用场景返回值注册拦截器运用拦截器 拦截器的使用 创建拦截器 首先,我们需要创建一个拦截器器的类,并且需要继承自HandlerIntercep…...
【gmsh源码阅读】OCC对象绑定tag及获取几何与网格映射关系
一、Tag是什么? gmsh中的几何模型相对于OCC的模型增加了id编号,也叫tag,在gmsh中可以显示出来。在gmsh中,点、线、面、体都有Tag,以方便对其查找定位查找。在OCC中TopoDS_Shape只有几何与拓扑结构,没有唯一…...
【RTP】webrtc 学习3: webrtc对h264的rtp解包
rtp_rtcp\source\video_rtp_depacketizer_h264.cc【RTP】webrtc 学习2: webrtc对h264的rtp打包 中分析了打包过程的代码,这样再来看解析过程的源码就容易多了:本代码主要基于m79,m98类似。这里注明了jitterbuffer 会再次 做 解析stap-a 变为NAL units解析ParseFuaNalu 第一…...
幻兽帕鲁服务器多少钱?4核16G支持32人在线吗?
4核16G服务器是幻兽帕鲁Palworld推荐的配置,阿里云和腾讯云均推出针对幻兽帕鲁的4核16G服务器,阿里云4核16G幻兽帕鲁专属服务器32元1个月、66元3个月,腾讯云4核16G14M服务器66元1个月、277元3个月、1584元一年。云服务器吧yunfuwuqiba.com分享…...
AD/DA(模数数模转换)
文章目录 前言一、介绍部分介绍AD/DA硬件电路模型硬件电路ADC模块DAC模块ADC0809DAC0832 运算放大器(运放)运放电路 DA原理两种不同的DA转换器 AD原理部分AD/DA性能指标XPT2046介绍主要功能XPT2046时序结构控制字节解释单端模式配置表 二、实例使用AD读取…...
Docker数据卷挂载(以容器化Mysql为例)
数据卷 数据卷是一个虚拟目录,是容器内目录与****之间映射的桥梁 在执行docker run命令时,使用**-v 本地目录:容器目录**可以完成本地目录挂载 eg.Mysql容器的数据挂载 1.在根目录root下创建目录mysql及三个子目录: cd ~ pwd m…...
YOLOv8-Seg改进:注意力系列篇 | non-local自注意力,助力小目标分割
🚀🚀🚀本文改进:non-local自注意力,助力小目标分割 🚀🚀🚀YOLOv8-seg创新专栏:http://t.csdnimg.cn/KLSdv 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1)手把手教你如何训练YOLOv8-seg; 2)模型创新,提升分割性能; 3)独家自研模块助力分割;…...
【Qt无门槛入门】信号以及信号机制及其常用控件(1)
信号与信号槽 信号源:由哪个控件发出的信号。 信号的类型:用户进行不同的操作,就可能出发不同的信号。 信号处理的方式:槽(slot)某个对象接收到这个信号之后,就会做一些相关的处理动作。但是Qt对象不会无故…...
【python】爬取百度热搜排行榜Top50+可视化【附源码】【送数据分析书籍】
英杰社区https://bbs.csdn.net/topics/617804998 一、导入必要的模块: 这篇博客将介绍如何使用Python编写一个爬虫程序,从斗鱼直播网站上获取图片信息并保存到本地。我们将使用requests模块发送HTTP请求和接收响应,以及os模块处理文件和目录操…...
排序(插入排序)
现在,我们学习了之前数据结构的部分内容,即将进入一个重要的领域:排序,这是一个看起来简单,但是想要理清其中逻辑并不简单的内容,让我们一起加油把! 排序的概念及其运用 排序的概念 排序&…...
Spring MVC 请求流程
SpringMVC 请求流程 一、DispatcherServlet 是一个 Servlet二、Spring MVC 的完整请求流程 Spring MVC 框架是基于 Servlet 技术的。以请求为驱动,围绕 Servlet 设计的。Spring MVC 处理用户请求与访问一个 Servlet 是类似的,请求发送给 Servlet…...
鸿蒙ArkUI 宫格+列表+HttpAPI实现
鸿蒙ArkUI学习实现一个轮播图、一个九宫格、一个图文列表。然后请求第三方HTTPAPI加载数据,使用了axios鸿蒙扩展库来实现第三方API数据加载并动态显示数据。 import {navigateTo } from ../common/Pageimport axios, {AxiosResponse } from ohos/axiosinterface IDa…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
OpenGL-什么是软OpenGL/软渲染/软光栅?
软OpenGL(Software OpenGL)或者软渲染指完全通过CPU模拟实现的OpenGL渲染方式(包括几何处理、光栅化、着色等),不依赖GPU硬件加速。这种模式通常性能较低,但兼容性极强,常用于不支持硬件加速…...
