终于走到这个项目了,BearMap是一个类似GoogleMap的网页端地图,BearMap做完后Proj3近期没打算做了,看之后的情况随缘吧.BearMap大体上由三个部分组成,分别是Proj2AB、HW4、Proj2C.
成品展示
世界生成、搜索补全、标记、A*寻路:
1.Proj2AB
1.1 Proj2A
- Build my own ArrayHeapMinPQ
- 注意时间复杂度,mostly logN
- 可以选择构建helper method,但必须声明为private(为了方便测试可以为package)
- 在内部类PriorityNode中重写一些方法,主要用来比较和取值
- 自己写测试以确保每个方法可以信任
还是需要考虑一些情况,一开始在建类的时候就要考虑到需要一个内部类来定义优先节点的属性,PriorityNode是带有item和priority的类的实例化,将pqnode存在ArrayList里,而itemMapIndex是一个存键值对的HashMap,存放数据类型和值的映射(在本类中 pqNode.item 即值是唯一的).
堆的变动要根据优先级来定。为什么不是传统的按值来构建小顶堆呢?
Where would we actually use this structure or need it?
Consider the scenario where we are monitoring text messages between citizens and want to keep track of unharmonious conversations.
Each day, you prepare a report of MM messages that are the most unharmonious using a
HarmoniousnessComparator
.
因为要考虑 real-life problem,而不单单是数值的比较,在之后的项目中会有体现吧。
1.2 Proj2B
- build my own K-D Tree (K Dimensional)
- 写一个O(n)的PointSet用以对比效率
- 注意剪枝的必要性,以及badSide是否有查看的必要
K-D Tree,若是在二维上则与线段树相似?对于BearMap的实现很有帮助。具体来说,当用户点击地图上的某一点时,线段树能帮你找出距离该点最近的路口。(maybe Quad Tree can Implement this too 😄)
构建K-D Tree时注意如果要插入的项的属性等于当前节点的该属性,视为大于它。在做查询的时理应选择剪枝,但不剪枝也still be correct, but less effectionly.
A Walkthroguh step:
-
编写 NaivePointSet 并保证它正常工作。
-
为KD Tree编写构造函数,通过插入测试样本来保证它能正常工作,推荐使用BSTMap作为模板。
-
编写随机测试用来比较KDTree的最近节点方法与NaivePointSet的最近节点方法 。
-
先实现比较没有效率的版本:先查找左子树,然后是右子树,不做剪枝操作,伪码如下:
- nearest(Node n, Point goal, Node best)
- If n is null, return best
- If n.distance(goal) < best.distance(goal), best = n
- best = nearest(n.leftChild, goal, best)
- best = nearest(n.rightChild, goal, best)
- return best
-
编写另一个KDTree的测试,比较NaivePointSet和KDTree的耗时(use 100000 points and 10000 queries).
-
修改nearest method,它将考虑"good side" and “bad side” .先别担心剪枝的问题。
-
添加剪枝,使其效率符合预期。
2.HW4
- Build my A Star Solver
- 注意和课上所讲的不同
- 可以解决一些经典问题
- 注意思考比较和取值的方法,考虑边界情况
How to implement Dijkstra’s Algorithm?
- Create a priority queue.
- Add s to the priority queue with priority 0. Add all other vertices to the priority queue with priority ∞.
- While the priority queue is not empty: pop a vertex out of the queue, and relex all of the edges going out from the vertex.
But Dijkstra is not smart enough, we need to make it better: A Star(A)*.
In pseudocode, this memory optimized version of A* is given below:
- Create a PQ where each vertex v will have priority p equal to the sum of v’s distance from the source plus the heuristic estimate from v to the goal, i.e. p = distTo[v] + h(v, goal).
- Insert the source vertex into the PQ.
- Repeat until the PQ is empty, PQ.getSmallest() is the goal, or timeout is exceeded:
- p = PQ.removeSmallest()
- relax all edges outgoing from p
And where the relax method pseudocode is given as below:
- relax(e):
- p = e.from(), q = e.to(), w = e.weight()
- if distTo[p] + w < distTo[q]:
- distTo[q] = distTo[p] + w
- if q is in the PQ: changePriority(q, distTo[q] + h(q, goal))
- if q is not in PQ: add(q, distTo[q] + h(q, goal))
3.Proj2C
- Basic Setup
- Part I, Map Rastering,地图格式化。给定世界矩形区域的坐标和Web浏览器窗口的大小,请提供覆盖该区域的具有适当分辨率的深度及图像组合阵列。
- Part II, Routing,路径选择。给定起点和终点的,请显示这些点之间的最短街道。
- Part III, Autocomplete (gold point), 自己动!给定一个字符串,找到与该字符串匹配的所有位置。e.g. all the Top Dogs in Berkeley.
- Part IV, Written Directions (optional, very hard), 标注方向。扩展第二部分的路线,以包括书面的驾驶指南。
Fill in the class:
- part I: RasterAPIHandler
- Part II: AugmentedStreetMapGraph, Router
- Part III: AugmentedStreetMapGraph
一些值得注意的点:
**1.**将经纬度信息转化为实际的地图,接收用户请求的矩形参数,生成对应的地图。
我们先来看这样一个问题:要展示同一个区域,我们可以使用多张高分辨率的图片组合,也可以使用较少张低分辨率的图片组合。为了适应用户的要求,我们需要定义单位像素的经度距离:longitudinal distance per pixel (LonDPP)
我们要展示的是小于用户要求的LonDPP的最大值。比方说用户要求每个像素2度,如果我们大于2,那么分辨率低到不能满足要求,只有小于2才能满足要求。又不能太小,分辨率太高展示范围变小。当然如果用户要求的很低,只能用现有的最低的LonPPp图
片。
2. 寻路工作:给定一个起始点和终点,选一条距离最短的路径。这个路径点不能随便选,而是要从距离起点最近的 Node 开始并到距离终点最近的 Node 结束。而这些 Node 本身需要是 Connected 的,不然会显示不可达。
吐槽下功能写完没改路由去跑,一直跑不起来,后来才发现Router.java里没有uncomment implement。
3. 使用Trie,搜索地标、店铺名时只要输入一部分,就返回以他开头的所有地名.搜索成昆后会有一个红色的小圈圈出现在找到的地方。It Works!
要注意有重名的问题:怎么办呢?在添加单词的时候,TrieNode‘s property中加入经纬度和ID,这样重名的地点的加入List中一起显示。