坐在这个椅子上,腰已经很酸痛了。今天又是花了十个小时左右来写这个作业,
首先,最重要的一句话。普林斯顿毕竟是普林斯顿。作业实在是太牛逼。
这次对图,对最短路径,对贪婪算法有了很深刻的认识,毕竟写了这么多代码。
那个老教授说得对,贪心算法是学生接触到的第一个日后会经常使用到的算法思想,对,是算法思想,而不是算法。
贪心,就是对路径长度不停地刷新,直到选出最优解。
最短路径也是根据这个求出来的。弄懂了之后也没觉得有什么难了。自然,看我这么一篇文章也不可能弄懂。什么东西都得是花时间的。
对于有向无内环的图来说,直接用 topological sort即可得出最短路径,
复杂度仅为 E + V.
如果是有向有内环图,则只能使用Dijkstra 最短路径算法,复杂度是 ElogV.
如果是有向有内环图,且有负边,则用上述算法会陷入无限循环,于是出现了新的算法,Bell-Fordman 算法。复杂度为 E*V。
如果是有向有内环图,且有负边,且有负循环。额。。。天知道了。
然后说说这次作业。
这次作业就拿了90分。最后放弃调试了,因为错误都没了。剩下的就是 他觉得我内存用多了。我把所有用过的对象都申明为null,以此减少内存,但是还是太多。我想应该是我实现方法是有问题吧。我是这么做的。用一个二维数组来记录到每一个点最短的energy和。再用一个二维数组记录到每一个点的最短路径上一行的点,类似于edgeTo[].
然后我把topological order压入栈中,按照老师讲的方法来寻找最短路径,并且不断优化距离。中途也犯过很多错误,但是经过大量时间调试后都解决了。就是这个内存问题。
他测的是 五次水平删除后 这个Seam对象所占的大小。只有类成员才会占内存,所以我在每次删除后,都会将这些大型数组指向null。等到下次删除时,再重新生成这些数组。这样的确会浪费一些运行时间,但应该所占用内存会很小啊,怎么会还是这么大。不理解。
后来我也想过,每次删除后不释放那些大型数组,而是再次刷新。后来太累了,想不动了,就放弃了。
我觉得topological order总有BFS的影子。一直这么觉得。最短路径算法,就是一层层向外推进,被推到的点,都将被确认为最短路径点。然后以此作为根据,继续向外推进。一层一层,不就是BFS么。。。
还有一个教训,写代码最好的就是一口气写完。我本以为写的差不多了。然后就和一同学闲聊了好久。结果回来继续写发现第一次提交就44分,自己那种状态也没了,很浮躁。浪费了大量的时间来调试。而且把很多对的逻辑又改错了,走了挺多冤枉路。
Anyway, week2 终于又搞定了。应该还有三节课了吧,一定得跟下去啊。。。
之前有个阶段很累,然后bug也一直改不出来,绝望了。上网想找源码参考。后来还是放弃了。最终花了大量的时间调出了bug。这次花了一个多小时想着怎么实现这个程序,还是很有效的。之后写的比较顺利。最高潮的三个小时,写的我很爽。我感觉我自己在进步。现在也可以写一些简单的遍历了。对于数组的操作感觉理解更深刻了。这个怎么说呢?就是看数组看得更加透彻了。额。。。好像他成为我的一部分了。额。。。
然后是对栈和队列的理解。也是突然就领悟到,为什么要有栈,为什么要有队列。
其实不是为了存东西,或者说,不是主要为了存东西。而是为了改变事物发生的顺序。
栈的话,是先进后出。队列的话,是先进先出。这是两种不同的顺序,或者说容器的类型。也是做事情的两种方式。
最后对于迭代器的理解。什么是迭代器。我觉得iterator翻译成迭代器很不成功,太复杂,让人看不清本质。我觉得迭代器就是一种途径,让你可以不摸清这个容器里面是怎么存放成员的,但是你可以通过迭代器来获得成员。迭代器是一种快速通道,是黑盒子通往外界的一个通道。
最累的时候,女朋友给我发来了一个码农猝死的消息。其实挺害怕的。思考过度应该很容易猝死吧。每次写普林斯顿作业都是思考过度。。。实在太有挑战了。
然后很愧疚,没能帮女朋友做好听力。实在是扛不住了。我先好好休息下。明天再听力。
哦,对了。宾大也被拒了。这周五等不到CMU就去康奈尔了。
好运,Richardo. 好运,Shirley.