3.6
重新开始编码:
今天开始写的是最大流算法中的Edmondes-Karp算法。
*非常非常慎重地记下: Graph数据结构中,Matrix的标准是,有边相连的存放权重,无边的存0,i=j的也是0,可能与之前最短路算法冲突了,
记下这一点,非常重要。
* 第二个问题是 深度广度搜索算法中,对m_pDistance的记录,权重是没有算进去的,都是按每条边1计算。
* 第三个问题:由于深搜广搜中的遍历算子没有很好完成,我先注释掉了,关闭了该功能,测试时传0即可。
------------------------------------------------------------------------------------------------------------------------------------------
3.7 完成Edmondes-Karps算法
3.8 写PushRelabel和RelableToFront方法
3.9 调试PushRelabel未果/ 主要花在other' work和聊天中
------------------------------------------------------------------------------------------------------------------------------
3.10
继续调试PR算法,发现倒来倒去最终有可能将水倒回去原来的点,即结果为0
靠!!! 原来错误出现在: 对算法的理解不够!!!
---对于溢出节点的定义是除去s,t以外的所有结点,那么就是说,对于s,t来说 根本不会出现Relabel的情况,也就是说 根本不会让t的高度一直增加
t的高度只能为0,这就保证了算法不会倒来倒去最后全部倒回去!
Mother fuck!弄了我两个晚上!
*还应该注意的一点是,这PR算法中,残余网络的定义是通过height来进行的,即如果h(u)>h(v)+1,则(u,v)不是残留网络中的边
-------------------------------------------------------------------------------------------------------------------------------------------
3.11
今晚首先解决Relable-To-Front算法,其实我原来的做法已经非常类似了,只是没有引入容许网络的概念,即清空结点余流的顺序有所不同
首先用第一节时间完成了算法的改写。
第二节后15分钟完成算法调试:遇到一个Bug:问题出在LinkedList的Delete函数中,函数有一个错误:
是当时修改为双向链表时遗留下来的:
if (p!=0)
{
del = p->key;
q->next = p->next;
Node* p = p->next; p->pre = q;
delete[] p;
}
标为红色的语句是功能是讲被删除结点的后一个结点的前驱设为被删结点的前驱。而这里出现了问题,因为这样删除的时候就会是被删除结点的后继
被删除!!!
----------------------------------------------------------------------------------------------------------------------------------------
3.19
今晚回归数据结构,因为要写计算几何学的基础数据结构和一些基本的算法,如叉乘等。
结果问题不断,泛型编程真的相当...
!!原来今晚的调试问题主要是类名或者函数名的不匹配造成,这种粗心的粗心的错误导致了太多的时间的浪费,所以一定要冷静下来,不要求快!!!求稳!!!
!!又一个白痴错误! 不过也可以总结出一个问题就是类成员变量是一个指针的时候,初始化为0xCCCCCCCC,而不是0.
---------------------------------------------------------------------------------------------------------------------
3.20
(1)解决昨晚遗留的问题:问题有两个:
<1>非常白痴的粗心错误,就是dimension是没有赋值的,但是用它来进行数组分配了。
<2>稍微有点技术含量的错误:就是在变长参数函数中,编译器是不会对参数进行隐式转换的,如Point(2,1,1),这样传入了两个各四个字节的整形,变长参数宏读入的时候就会按照8个字节的double来读,结果发生错误。
问题解决后,开始写graham-scan 和 jarvis-step
-------------------------------------------------------------------------------------------------------
3.21
(1) 写Graham遇到的第一个问题,如何对points排序,其实思路很简单,可以直接利用已经写好的排序算法,对对象的排序,之前已经做过的,就是自定义一个结构体包装一下,关键是要定义这个结构体的比较操作符的重载函数就可以了。
(2) 编码速度还是很慢呀。。。Graham还没调试,最快明天可以写完jevis-step。要进入那种状态,才能提高速度。要开始注意利用暗时间了。
-----------------------------------------------------------------------------------------------------------------
3.22
1. 调试Graham
(1)记录一个问题:const_cast<Type>(expression),强制去除const限制
(2)令一个问题:对于容器,编译器会为代码中装入容器的类进行检查,检查该类是否满足放入该容器的条件:即该类型是否能够实现容器定义了的所有成员函数,包括< == 这些操作符重载是否已经都实现。
比如Point放入容器中就引发了编译错误,因为LinearList中定义的Minimum函数,需要用到T的<运算符,但是Point无法定义。
(3)『Algo Error』再次发现一个算法性错误,问题出在按极角排序时,错误的做法是直接p0*p,但是两点有叉积吗?
解决:其实这题出自书本P579 33.1-3 利用叉积的方法很简单,就是将两个向量的比较操作符重载,哪个向量在左边,那个向量的极角更大。
(4)『Algo Error』再次发生算法错误!! 这次错误的起源是由于一些边界条件。原来的想法是不需剔除相同极角的点,算法可以自动抛弃,但是发生了一个问题,那就是如果一开头的几个点都是极角相同的,前三次pop就会导致堆栈下溢错误发生!!!
解决: 加一个补丁,就是加上一个判断条件,当栈长度大于等于2时再做操作,否则直接进栈~~~
========================================
可以开始Jevas-step了
(1)25分钟写完,不过这当然要归功于暗时间和Graham的代码复用了。明晚测试~!
(2)明晚还要完成两点间最短距离。
----------------------------------------------------------------------------------------------------------------------
3.23
(1) 调试Jarvis,花费半个小时。问题是一开始就删除了p0,导致算法最后不能返回到p0处,结果死循环。
(2) 开始写最短点距离
(3) 未能完成最短点距离,明晚可以完成加调试。
------------------------------------------------------------------------------------------------------------------------
3.24
(1) 调试最短距离发现一个问题:对_y进行排序(按照x的顺序分成两半,然后两边重新排序时)发现一个问题,即不能预测序列中有多少个是在中线左边,多少个在中线右边。
解决方法是: 将在中线右边的点插到表的后端,用Add,最后用delete将中间的删去。虽然这个方法效率也不怎么高
(1.1)记录一个教训是,自定义的结构体(用以各种包装用途的)要定义默认构造函数和复制构造函数。
(2) 第二个问题:也是出现在划分的情况下:即选择的划分线上有多个点时,如(1,0) (1,2),划分线为1,则由于划分是对px是简单地选取地m个,如(1,0),那么(1,2)就被归到右半区,但是在py划分时,(1,2)是会被归到左半区的。
(3) 第三个问题:还是一个边界情况,就是对递归分割的时候,可能出现一种情况是,被划分的点都位于分界线上。这样就会出现死循环的情况,因为根据问题二的解决,是将x坐标相同的点都划到一个分区内。
解决方案:难道又要打补丁!!!看来唯有打补丁了。就是在函数入口做检测,如果发现px中全部点的x坐标都相同,则在py中做一个线性比较,输入最小的相邻两点距离就行了。
Done!又花了一个晚上的时间才能调试好。
-------------------------------------------------------------------------------
3.27
(1) 今晚完成了矩阵LU分解,明晚要写完LUP分解~!! 速度还是有点慢吧。不过只用了一个小时零20分钟,包写矩阵数据结构和一些基本函数重载,还算可以把。
-----------------------------------------------------------------------------
3.28
(1) 完成了LUP分解。剩余的时间准备UML的presentation。应该可以可以做好的。
--------------------------------------------------------------------------------------------------------------
3.29
(1) 写完了解线性方程组的算法,调试中,发现昨天写的LUP有重大Bug。幸好还测试出来了,不然又是一个冤死!
【算法问题】问题是:在计算L矩阵的时候,不是计算出外层元素就可以不管,在进行调换的时候,L矩阵的元素也要跟着调换,而这也是为什么书上的算法在A中直接完成的原因!!!
出现这个问题的原因是没有很好的理解Q P 和P'的关系。
(2) 第二个错误,又是一些非常低级的错误,一定要静下来,细心地去做:想一些for(i=0;j<i;i++) j应该写成i的错误就尽量不要发生!!!