主题没有,内容瞎写

芳草伴青山, 雲影入湖心, 松梢鶴嘯長, 蘆屋酣夢沉。

0%

描述“事件”,如果是仅用自然语言,那么似乎是小学生就应该可以办到的事情。但如果想要结构化的去描述一个事件,却不容易。比如这个事件:

昨天我们一家一起上午9点半驱车前往长沙县江背镇,在油菜花田里走了一会,然后在江背镇吃了午饭,之后又到乌川湖水库看了看,然后下午3点半返回长沙。

这件事情里面涉及到了至少两个时间点,两个层次中的三个位置(都在江背镇这个粗粒度层次,但具体包括了一处油菜花田和一处乌川湖水库两个细粒度层次),以及驾车和步行两种交通模式,还有两条不同的驾车线路(去的时候是走长浏高速然后一直到江背出口才下去的,而回来的时候是先走了一段省道,然后从永安上高速回的长沙)。这个前后仅用时6小时左右的旅行都包含了这么多细节,更不用说那些时间跨度更长的旅程了。

就昨天这条事件来说,如果我用“时间、地点、人物、事件”来描述,那么就会遇到粒度控制的问题。说白了就是这个描述可繁可简,我既可以说我们仨去了趟江背镇,也可以像上面那样把它详细的描述出来。因为事件本身就是多尺度的,我们既可以非常粗线条的勾勒出事件的大致经过,也可以一秒一秒的逐帧观察。到底需要哪种详细程度,就看使用目的了。

过年的时候,知乎上对年的讨论自然也会多起来。在现在这个80后基本掌握主流话语权的时代,出现诸如“年味为什么变淡了”之类的问题也会让我很有共鸣。在同类问题下的诸多回复中,我看到了一个大体意思是这样:

年就不是给我们这个年纪的人过的,而是给小孩和老人过的。我们的任务就是多做家务,帮老人分担负担,让小孩开心。

我深以为然。所以说,现在过年回家压根就不应该想着怎么休闲,怎么玩,怎么放松。ALL CRAP! 干活就是了。但我们的那些个同龄人,似乎还没有都看明白这个道理呢。

我没有考证过嫁闺女的时候娘家大规模要彩礼到底是我国古已有之,还是近年来才出现的新风尚。但我觉得,把男方家人叫过来,然后告诉他们说:“我们这里的习俗就是这个过程总共分为n步,第1步需要提供m样东西,分别是w箱A、x箱B、y瓶C和z斤D,一万〇一(表示万里挑一)的见面礼等等,另外还有6万、8万、10万、20万…上不封顶的礼金自己看着办,然后是第2步…”然后进一步表示这还是简单的,如果是乡里那更厉害。

我在观察他们提需求的时候,感觉到的是这样一种心态:我们这黄花大闺女是天下第一好的姑娘,要嫁给你可没那么容易,没过个五关八关的你休想从我们这娶走我们闺女。

但让我感觉无力吐槽的是,上面说的那些个ABCD之类的,都是些一听起来就会有“这都是些神马奇奇怪怪的鬼!?”的感觉。

婚姻本是两个人你情我愿的事情,但在好事将近时却突然蹦出一帮关系不大的人在这里大谈各种条件门槛。这背后透着一股深深的自卑情绪,这种深入骨髓的自卑一定要通过一些物化的东西去弥补,于是就出现了ABCD。然后借着这些ABCD,可以让提要求的一方产生一种我们就是壁垒森严坚不可摧居高临下舍我其谁的莫名优越感。然后再美其名曰:这就是我们这里的规矩。

但在我看来,除了一股子浓浓的土气和欲盖弥彰的自卑以外,什么都没有。这也是我深深厌恶的所谓传统之一。

全球化的时代,经济好与不好都是联动的,很难有哪个国家或地区能独善其身。区别只是在差的时期谁能不那么差;在好的时期谁能更好而已。而且不仅是经济层面,大众情绪、社会思潮都会与之联动,这些再进而影响政治,逐渐演变成波及世界各地、影响各个社会阶层的历史大事件。这是在宏观层面。

而在微观层面,每个工作团队、每个家庭、每个个体的情况又会表现出巨大的差异。他们有的可能深受宏观层面事件的影响而随之潮起潮落,也有的似乎事不关己,还有的甚至能逆势而动。

有趣的是,无数这些微观的个体又共同组成了宏观的图景。然而,在这幅壮丽图景上,又有哪些微观个体能跳出自己那方寸之地,以上帝视角看清整体的样貌,甚至是大潮前进的方向呢?

这个工作缘于我在指导实验室今年的一篇硕士论文时蹦出来的一个想法。本来,我是想在这篇论文中把CH应用到mmrp中,通过减少IO来提高mmspa的整体性能。但后来我发现我想错了,因为我错误的理解了CH。CH并不是把道路网进行类似影像金字塔那样的多层次组织,尽管它的名字叫“分层压缩”,而是通过在原始网络中增加很多的“快捷边”,让后续的路径搜索算法可以“绕过”很多不必要去考察的顶点,从而大幅减少松弛操作的次数,达到加速最短路径搜索的目的。当然了,这种加速是有代价的,那就是在事先寻找、确定并建立这些“捷径边”所需的时间开销,以及增加了这些捷径边所带来的空间开销。

虽然应用CH来改善mmspa的IO看来暂时无望,但我在去年年底又想到了另一个可以改善目前每次计算都慢得要命的办法,尽管有点简单粗暴。那就是在程序启动时就把所有mode的图都读进来,然后后面针对每次routing plan进行graph装配的时候都不要再去访问数据库了(那个读graph的sql着实费时),而是从内存里的这个graph cache中取数据,装配成临时的graph集合,然后计算结束后再释放掉这些临时图。

顺着这个思路,我就开始着手于去年12月中旬实现这个feature,顺便也把mmspa这个老库好好整理了一下,动了动手术。最终在1月5号发布了2.0版本的mmspa,在增加了内存开销的代价下,把单次路径规划的性能提升了大约10倍,但到了http服务的层次,这个提升被打折到了5倍左右。

这次改造,对代码的结构进行了大幅调整,但仍然保留了原来的主要实现方式,没有动基础的算法和数据结构。尽管如此,过程也并不是一帆风顺。最主要的障碍就是装配公交系统graph,因为按照新方法组装起来的graph中的vertex不再是按照id排序的。所以只能又加入了一个快排函数,专门为公交graph进行顶点排序。这里费了一点时间。最后,用valgrind彻底清理了一遍所有内存泄漏的问题,确实找到了好几个,而且其中还有当年留下的千年老bug。昨天,我又发布了一个2.1.0版本,删除了对原来1.x版本的接口兼容(因为我知道受影响的只有我自己的pymmrouting),但也保留了能兼容1.x版本接口的2.0.1版本。

至此,虽然还有很多可以改进的东西(都写在issues里面了),但这次的工作暂时告一段落。路径规划,multimodal路径规划,是个永无止境的工作,而且就如杨剑说的,后面的优化工作量会非常大,而带来的收益会越来越小。这也算是一种边际效应递减吧。不知道今后是否还有机会继续3.0的工作,抑或把它变成未来某块工作的基础,那也算是幸事一件。

跨年的时候,我扫了一眼很久没打开的朋友圈,不出所料的发现很多人都在尝试用一两句简短的话总结和挥别2015,再用一两句话寄语2016。为了赶在那一两分钟之内把消息发出去,也只能写的很短。我当时也想写两句,但发现好难。而且,没有仔细的思考,很难客观的评价自己过去的这一年,更难一下子规划出新一年的目标。

跨年,尽管只是一个瞬间,但应该用一段更长的时间沉下来,反思2015,规划2016,就像过去每年这个时候一样。还有一点,2016对我和我们全家来说,必将会成为一生中的重大转折点。

2015,我33,2016,老婆33。常言道:三十三,大转弯。看来,要想全家一起大转弯,必须得从2015开始,然后在2016完成。

其实重构mmspa的想法早已有之,因为那是我2009年4月份开始写的库,后面在2010年集中开发Multimodal Route Planning System for Munich的时候基本就不再动它了,主要是有一种怕一碰就不能用了的心理在作怪。直到去年把上层的wrapper重新用Python写成pymmrouting的时候都没敢大动mmspa的代码,只是稍微添加了几个函数。但实际上,它的代码已经too(不) ugly(忍) to(直) read(视)了,而且现在又有了个改进效率的想法作为契机,那就做个大扫除吧。

之前的代码问题很多,要列清单可以列很长,这里就不详述了,当自己重构的动作提起速度来的时候也是脑子中几条线同时前进,有的问题随着发现就随着解决了,可能都没来得及反映到commit comments中。这里只提纲挈领的记几个要点:

  1. 之前的代码组织主要是分成了parser(负责从数据库里读取数据并装配multimodal graph set)、multimodal-twoq(负责最短路径算法)和mmspa4pg(一个…大杂烩,里面既有routing plan的创建,还有最终路径的获取与销毁函数)。这样的组织显然混乱,所以把代码打散并重新组织成了routingplanroutingresultgraphassemblermmtwoqmmspa4pg这几个部分,数据结构主要都定义在modegraph.h中。结构比之前清晰了很多
  2. 消灭了graphassembler,也就是之前parser中的几个超长函数,提取出了一票小函数
  3. 更加合理的使用externstatic等,用以理清全局、局部、公有和私有的关系
  4. 规范化命名约定,并且专门写了一个文件,记录Coding standards

这次的重构过程也是一次对C的再学习,《K&R》《C Interfaces and Implementations》帮了很大的忙。特别是K&R,尽管只是薄薄一本,但其实信息密度很高,在里面总能找到自己的C知识短板。

重构后的版本作为1.1发布了,当然距离一个真正好用的库还差很远,不过总归是迈出了有意义的一步。

下一步,就是2.0。它最大的特点就是会比之前的库快,效率的提升会主要体现在Multimodal Route Planner for Munich的demo中。敬请期待。

O2O产业化的浪潮正在“全民创业,万众创新”、“互联网+”等等大旗的挥舞下席卷着这个处在实体经济萧条、政府债台高筑投资疲软、股市动荡、楼市热浪褪去、货币贬值、外资加速撤离、人口红利消逝、全民焦虑的世界第二大经济体。

从之前的呱呱洗车、1号社区到现在楼下正在拼命吆喝着”首单减10元“的浮点社区。O2O的烧钱之旅在如火如荼的进行着。但是在我看来,他们绝大多数都是在堆积泡沫。没有长期扎实的技术和人才积累,没有雄厚的基础制造业根基,没有让利于民的政策,没有公平的法制环境,也没有对失败者充分包容的氛围,仅凭印出来大把大把的钞票,以及找到的无数”痛点“,就可以完成几十年都没有完成的产业结构调整,实现新的经济腾飞吗?在我看来,这才是梦,是个真的梦,而且又是个十分浮躁的春梦。

都这么多年了,还是没有学会踏踏实实做事,认认真真积累。总想着走捷径,抄近道,多快好省,一夜暴富,点石成金。这样下去是没有希望的,梦就永远是个梦。

正当我看着Marienplatz那里一坨乱麻般的GPX思考该如何把它们match并snap到road network上去的时候,Mapbox的matching API在7月8日发布了。真是不得不佩服Mapbox,想人所想,及人所及,太善解人意了。

Road network around Marieplatz, Munich from OSM

with GPX tracks overlaid...

另外的感觉呢,就是像matching、routing,还有map generalization这样的问题,看起来好像都研究了很久了,但其实历久弥新,还是有很多可以做的地方。这也算是让自己坚持下去的一个理由吧。

尽管还是算的很慢(平均一次请求的处理时间要10s左右),而且bug也不少,但这个三年前就应该上线的多模式路径规划演示系统Multimodal route planner demo for Munich还是可以用了。除了核心算法库(mmspa)几乎没变以外,其它部分全都重写了。前端部分的代码大量参考了Mapbox的mapbox.directions.js项目,但我并没有fork它,而是基于它的代码进行了修改,这在它的license中是允许的。另外,从底图到样式,也都利用了Mapbox提供的多个服务和开源项目,所以这里这里要特别对Mapbox的开发人员们致以诚挚的谢意。
我还会继续不断改善它,改善它的性能、规划质量、稳定性、交互体验等等,要让它变得越来越好用,因为,它主要是

  • 给我自己用的
  • 给我自己用的
  • 给我自己用的
    对,重要的事情要多说几遍。
    后面用于验证新想法的实验都会基于这个演示平台来做,希望能有些收获。