fix step size 过高引起的Precision异常
Projection method 里面分为两步,一步是步长测试,二是其他函数值得计算。从fix step size做起,可以先排除step size adjust 上的问题。
数据准备好,初次实验成功,下面看边界条件。
回想Fix 遇到什么问题?步长超过边界不能迭代
Ptt并不高
step size 没有下限,怎么低都可以,就是计算效率不高。比如极限情况,步长为0.0001,迭代数百万次,精度一直在提高。迭代数百万次,说明运行稳定。精度一直在提高说明,虽然慢,但没有错误。
下面看看另一个极端情况。
![](https://img.haomeiwen.com/i1456994/7cd7908767f343e5.png)
![](https://img.haomeiwen.com/i1456994/9b178101fc7b6041.png)
![](https://img.haomeiwen.com/i1456994/0650681d4d89e25c.png)
发现Bug:精度突变。最后出现古怪符号。精度最高e-16
![](https://img.haomeiwen.com/i1456994/4d2c7a2690489f34.png)
![](https://img.haomeiwen.com/i1456994/469e3c745758f5b6.png)
继续测试步长极限
![](https://img.haomeiwen.com/i1456994/5ee88153e88eba6a.png)
![](https://img.haomeiwen.com/i1456994/f5cf75c6bc3842b7.png)
![](https://img.haomeiwen.com/i1456994/0465ab0f48292983.png)
- Note: step size=40, Exception appears, the precision reduce and then, exception appears.
![](https://img.haomeiwen.com/i1456994/9355638545048c10.png)
- Note: step size=50, Exception again appears, the precision reduce and then, exception appears.
![](https://img.haomeiwen.com/i1456994/ae03e9c1357501c2.png)
![](https://img.haomeiwen.com/i1456994/248084b40bd34a8f.png)
![](https://img.haomeiwen.com/i1456994/23dfc4d459cea669.png)
-
note: we have not good results when step size or precision go to limitations.
Route cost 没有问题
Mode cost 在前面的测试中都是正常的, 这里也没有出现异常。只是数值比path cost要大一些。
![](https://img.haomeiwen.com/i1456994/93d2a46ed2e10e4b.png)
从程序上看不出问题
测试flow update,从结果上看不出问题,就是一个projection 操作,从中间过程看,也没有问题。首先是mode做流量调整,fix step size 乘以 transfer cost。投影。流量守恒。然后解路径流量。将升级后的流量分配到下辖的各条路径上。按mode demand plus 守恒。投影运算,流量-cost,没错。
然后计算误差
![](https://img.haomeiwen.com/i1456994/4b49a151dd2e14c8.png)
误差没有缩小,反而变大了。但是结合以前的情况也没有问题。在接下来的几次迭代中,精度反复波动。第七次迭代,误差急剧变大。
第八次:not a number
path flow -- path cost (OK) -- mode cost (Exception) ---
检查mode cost
nest sum 出现有的nest一点流量都没分到的情况。
在上一步中所有流量都分到一个nest mode上。上一步就有问题了,流量分配不对。logit based 每种方式都有一定的流量。
![](https://img.haomeiwen.com/i1456994/bd116509402a6a80.png)
![](https://img.haomeiwen.com/i1456994/94dc6310258455f2.png)
ptt (OK)
mode cost :
input是mode demand,其中一个demand是0,导致endogenous cost为负无穷。取值-999999999999999。外部cost是0.603289. 所以,总体cost是:
![](https://img.haomeiwen.com/i1456994/575066ee210ef95f.png)
然后,减去最小值就变成
![](https://img.haomeiwen.com/i1456994/8f901151244cf0b8.png)
这个基本是没错的。有点误差。不知道为啥,小数点后面的问题。简单的减法,小数点后面几位不一致。
![](https://img.haomeiwen.com/i1456994/21c6410b39b0871c.png)
正常情况下没有这个问题,可能是数值太大引起的。可以单独领出来试试。
总的来说就是Demand=0引起的。
![](https://img.haomeiwen.com/i1456994/ca7680c64160c023.png)
那么就是怎么处理demand=0的情况?
在输入端控制,给一个极小的demand:e-20。
if (nm[nestmode_i].NestSum != 0) {
nm[nestmode_i].EndogenousCost = \
(MuE / Theta)*log(0.00000000000000000001/ pow(nm[nestmode_i].Membership, 1 / MuE)) \
+ ((1 - MuE) / Theta)*log(nm[nestmode_i].NestSum);
}
else {
nm[nestmode_i].EndogenousCost = \
(MuE / Theta)*log(0.00000000000000000001 / pow(nm[nestmode_i].Membership, 1 / MuE)) \
+ ((1 - MuE) / Theta)*log(0.00000000000000000002);
}
Demand 调整以后,再测试精度。在第八次迭代出现not a number的情况。
在求ptt和path cost的时候应该没有问题了。
问题可能处在termination test上。
IndexNM[nestmode_i] = IndexNM[nestmode_i] + (p[path_i].Pf / nm[nestmode_i].Demand) * (p[path_i].PttTrans / p[path_i].Ptt);
分母nm[nestmode_i].Demand)确实可能为0;
至此,基本确定了fix step size 过高引起的Precision异常的问题。
Self-adaptive Projection 的问题,在ND上还是有问题,(Demand)
FW 解ND net 已经可以了。
Fix step size 至少处理了
S2FunValueNth(l, p, nm, od);
S3SolutionUpdate(p, nm, od, Alpha);
TerminationIndex = S8Termination(p, nm, od); printf("%.10lf\n", TerminationIndex);
S9Transit(p, nm);
都没什么问题,其中S2和S3是重要步骤,S8和S9相对简单。
在self adaptive中,还有更多的计算量。
2,3,4,5,6试算步长
7调整步长之Gamma调整
8收敛测试
9流量交替
9.1步长交替
先考虑那些东西要交替?flow/demand;alpha ;Gamma每次赋值就行。flow/demand cost都是计算而来的。在SAGP中涉及到的所有变量,x, y, alpha, alpha Plus, 这些变量中需要进行交替操作的只有input(流量)和步长。这两步骤很简单,且经过多次操作没有问题。
8收敛测试刚刚做过,没问题。
7步长调整中Gamma步长是步长调整阶段的变量。其他还有一个变量是最小整数l。S2-S6就是为了找到最优l,S7就是为了调整这个Gamma
S7和S6几乎相同,只是S6中的Delta是外部决定的,在S7直接给了0.5. 2-Delta始终大于0.5,所以S6中的不等式比S7更容易达到。如果S7中的不等式也成立,说明这个不等式条件很容易达成,步长可以扩大一点。由于S7和S6几乎相同,S7的检查也pass。
检查S6. 首先大于等于,基本公式都对过,没有问题。
S6中有三大函数:都是内积。内积的input分别是demand/flow;demand/flow cost;demand/flow cost (alpha)。先就这内积的形式来看看。三个内积的计算形式都很简单。没有问题,下面就是看看input对不对。
S5算demand/flow cost plus(alpha)
S4算demand/flow cost plus
S3算demand/flow plus
S2算demand/flow cost
S3 and S2 已经完成测试,没有太多问题。
S4 S5在一些情况下也正常工作,下面就极端情况做个别测试即可。FW就是在这种情况下测出问题的。
尝试跑起来
initial step size
when initial step size =5; step size does not change, but after 395 iterations, the precision collapse and go into endless loop
![](https://img.haomeiwen.com/i1456994/0c6539ed6fbcac53.png)
when initial step size =10, the step size keeps increase, but after 94 iterations, the precision collapse and step size becomes zero, but didn't go into endless loop
![](https://img.haomeiwen.com/i1456994/58cca39e3542c807.png)
check above phenomenon
in 93th iteration, we obtain good results, and then these results will be like input.
the input is x, alpha k, gamma, the following y, alpha k plus,x plus, residual is the product of x, alpha k, and gamma.
![](https://img.haomeiwen.com/i1456994/1e659fdef56b2ffa.png)
so, the red part is the input variable, plus gamma and alpha k
-
we can see, Gamma=alpha k+1 / 0.9. match the definition.
as definition, Part1 - Part2 >= Part3 holds.
Part1 - Part2 - Part3
to be more detail, it can be observed that part 1,2 and 3 are all small.
part 1, part 2, part 3
- input is mode demand/path flow, the output is path flow cost.
path flow ---link flow ---link cost---path cost---- under each nest mode (path cost - min path cost) - input is min path cost under each mode, the output is nest mode cost
min path cost under each mode + nest mode demand + dispersion parameter: Mu, Theta, Membership---nest mode cost
Mode cost function
the input is OK, nest mode demand is not equal to 0; so, the input is ok.
demand, cost, endogenous demand, exogenous demand
note: test whether we can use scientific notation for calculation. Yes, scientific notation can be used for calculation. --> mode cost, mode cost plus, we all use scientific notation to indicate a small enough value to replace zero. - solution update:
-
input: x, y, alpha k+1
mode demad plus, mode demand, alpha*cost
o,d,nest, mode,mode demad plus,mode demand, alpha*cost
demand update is normal, flow conservation is held.
- flow demand
- y plus
input is x plus,
path flow plus---link flow ---link cost ---path cost plus---- under each nest mode (path cost plus - min path cost plus)
min path cost under each mode plus + nest mode demand plus + dispersion parameter: Mu, Theta, Membership---nest mode cost plus
目前为止都没问题。总结:Debug要回溯,逆序,从问题查起。 -
start from the problem.
only one modification was made, give demand which supposed to be zero to be a very small number.
in 95th iteration, the precision do not collapse, but the step size become zero.
step size become a very small value.
where is the problem? Input or operation?
-
see the operation in S6
part 1 =0;
part 2 ~~0;
part 3 =0;
before 95th iteration, part 1 !=0;
so, check part 1.
part 1, 2, 3
part 1, 2, 3
evaluation trend of part 1
cost, cost P
It is observed that cost p is unnormal. As expected, cost P in the previous iteration is stable.
cost, cost P in previous iteration
S4FunValueNPth(l, p, nm, od); produce unnormal cost p
可能存在两个costP为0的情况
确实是两个mode cost都为0,而mode cost P异常
为什么会有两个相同的最小值
Demand没有变异,正常,说明输入正常。
第一次接待就有问题,所以看第一次就好。
![](https://img.haomeiwen.com/i1456994/745405dcab1946c5.png)
![](https://img.haomeiwen.com/i1456994/74def96a6efe35d4.png)
![](https://img.haomeiwen.com/i1456994/24aa23c63b087afe.png)
如果第一个mode 的cost加上一个极小值,效果如何?
nm[0].Cost = nm[0].Cost + 1e-100;
1e-100太小,没有效果。![](https://img.haomeiwen.com/i1456994/d2ad1238bad43ee1.png)
这步就先不处理,其实本质上是精度处理能力不足引起的。
那解决的办法一般是用科学计数法来算了;
对于精度问题,想起前几天一件事,18个9减一个极小值,如0.15732,没有得出正确结果。
精度没有显示出来
15位9,确实有数字,但是结果不正确,小数点后面应该是8426
为什么cost P变异
![](https://img.haomeiwen.com/i1456994/f22ee221eb2a4d50.png)
![](https://img.haomeiwen.com/i1456994/4f237d4b49464462.png)
![](https://img.haomeiwen.com/i1456994/a8d320d335a020e7.png)
bug出现:存在多条最短路的时候,把非负最短路的流量加起来,就不对。只能选一条最短路。如果两条最短路都考虑,那么做流量升级的时候,没有好的升级方法来使得流量微调。所以只能选一条最短路。
解决办法,增加一个指标作为最短路指示指标。要做任何改动必须改一步试一步。
![](https://img.haomeiwen.com/i1456994/70ca175ec6490120.png)
![](https://img.haomeiwen.com/i1456994/4367b26a5a655a84.png)
其实同理,在path flow update上也一样。
精度是一个反复升降的过程
精度的升降与是否存在多条最短路没有关系
![](https://img.haomeiwen.com/i1456994/c57fb7e45b74baf5.png)
![](https://img.haomeiwen.com/i1456994/907ba7e86d0d2f1b.png)
![](https://img.haomeiwen.com/i1456994/bc410f217c6d8814.png)
总之,精度是一个反复升降的过程可能是在精度达到瓶颈以后遇到的问题,这里先不管。
精度最高到e-20
appendix
debug s2 s3
for (path_i = 0; path_i < NoPs; path_i++) {
//printf("%d %d %d %d %lf %lf\t%lf\t%lf\n", p[path_i].Path[0], p[path_i].Path[5], p[path_i].Nest, p[path_i].Mode, \
p[path_i].Pf, p[path_i].Ptt, p[path_i].PttTrans);
}
S22FunValueNth_ModeFun(nm, od);
for (nestmode_i = 0; nestmode_i < NoNMs; nestmode_i++) {
//printf("%d %d %d %d %lf %lf %lf %lf\n", nm[nestmode_i].O, nm[nestmode_i].D, \
nm[nestmode_i].Nest, nm[nestmode_i].Mode, \
nm[nestmode_i].Demand, nm[nestmode_i].Cost, nm[nestmode_i].EndogenousCost, nm[nestmode_i].ExogenouCost);
}
//S3SolutionUpdate(p, nm, od, Alpha);
for (od_i = 0; od_i < NoODs; od_i++) {
od[od_i].NMNonMinSum2 = 0;
od[od_i].NMNonMinSum = 0;
od[od_i].NMCounter = 0;
od[od_i].Flag = 0;
}
for (nestmode_i = 0; nestmode_i < NoNMs; nestmode_i++) {
if (nm[nestmode_i].CostTrans != 0) {
nm[nestmode_i].DemandP = nm[nestmode_i].Demand - Alpha[1] * nm[nestmode_i].CostTrans;
if (nm[nestmode_i].DemandP < 0) {
nm[nestmode_i].DemandP = 0;
}
//printf("%d %d %d %d %.5e\t%.5e\t%.5e\n", nm[nestmode_i].O, nm[nestmode_i].D, nm[nestmode_i].Nest, nm[nestmode_i].Mode\
, nm[nestmode_i].DemandP, nm[nestmode_i].Demand, Alpha[1] * nm[nestmode_i].CostTrans);
}
}
for (od_i = 0; od_i < NoODs; od_i++) {
for (nestmode_i = 0; nestmode_i < NoNMs; nestmode_i++) {
if (nm[nestmode_i].CostTrans != 0 \
&& od[od_i].O == nm[nestmode_i].O && od[od_i].D == nm[nestmode_i].D) {
od[od_i].NMNonMinSum = od[od_i].NMNonMinSum + nm[nestmode_i].DemandP;
}
}
}
for (od_i = 0; od_i < NoODs; od_i++) {
for (nestmode_i = 0; nestmode_i < NoNMs; nestmode_i++) {
if (nm[nestmode_i].CostTrans == 0 && od[od_i].NMCounter == 0 && \
od[od_i].O == nm[nestmode_i].O && od[od_i].D == nm[nestmode_i].D) {
nm[nestmode_i].DemandP = (od[od_i].Dem - od[od_i].NMNonMinSum);
od[od_i].NMCounter = 1;
}
}
}
for (nestmode_i = 0; nestmode_i < NoNMs; nestmode_i++) {
//printf("%d %d %d %d %.5e\n", nm[nestmode_i].O, nm[nestmode_i].D, nm[nestmode_i].Nest, nm[nestmode_i].Mode, nm[nestmode_i].DemandP);
}
网友评论