学校“数据结构”课程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…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...