Skip to content

Commit 506b66f

Browse files
author
Jens Frenkel
committed
- make Tarjans Algorithme O(N)
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15439 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 1427fde commit 506b66f

File tree

2 files changed

+46
-35
lines changed

2 files changed

+46
-35
lines changed

Compiler/BackEnd/BackendDAETransform.mo

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,12 +1056,14 @@ algorithm
10561056
Integer n;
10571057
list<list<Integer>> comps;
10581058
array<Integer> number,lowlink;
1059+
array<Boolean> stackflag;
10591060
case (_,_)
10601061
equation
10611062
n = arrayLength(ass2);
10621063
number = arrayCreate(n,0);
10631064
lowlink = arrayCreate(n,0);
1064-
(_,_,comps) = strongConnectMain(mt, ass2, number, lowlink, n, 0, 1, {}, {});
1065+
stackflag = arrayCreate(n,false);
1066+
(_,_,comps) = strongConnectMain(mt, ass2, number, lowlink, stackflag, n, 0, 1, {}, {});
10651067
then
10661068
comps;
10671069
else
@@ -1093,6 +1095,7 @@ public function strongConnectMain "function: strongConnectMain
10931095
input array<Integer> a2;
10941096
input array<Integer> number;
10951097
input array<Integer> lowlink;
1098+
input array<Boolean> stackflag;
10961099
input Integer n;
10971100
input Integer i;
10981101
input Integer w;
@@ -1103,29 +1106,29 @@ public function strongConnectMain "function: strongConnectMain
11031106
output list<list<Integer>> ocomps;
11041107
algorithm
11051108
(oi,ostack,ocomps):=
1106-
matchcontinue (mt,a2,number,lowlink,n,i,w,istack,icomps)
1109+
matchcontinue (mt,a2,number,lowlink,stackflag,n,i,w,istack,icomps)
11071110
local
11081111
Integer i1,num;
11091112
list<Integer> stack;
11101113
list<list<Integer>> comps;
11111114

1112-
case (_,_,_,_,_,_,_,_,_)
1115+
case (_,_,_,_,_,_,_,_,_,_)
11131116
equation
11141117
(w > n) = true;
11151118
then
11161119
(i,istack,icomps);
1117-
case (_,_,_,_,_,_,_,_,_)
1120+
case (_,_,_,_,_,_,_,_,_,_)
11181121
equation
11191122
true = intEq(number[w],0);
1120-
(i1,stack,comps) = strongConnect(mt,a2,number,lowlink,i,w,istack,icomps);
1121-
(i1,stack,comps) = strongConnectMain(mt,a2,number,lowlink,n,i,w + 1,stack,comps);
1123+
(i1,stack,comps) = strongConnect(mt,a2,number,lowlink,stackflag,i,w,istack,icomps);
1124+
(i1,stack,comps) = strongConnectMain(mt,a2,number,lowlink,stackflag,n,i,w + 1,stack,comps);
11221125
then
11231126
(i1,stack,comps);
1124-
case (_,_,_,_,_,_,_,_,_)
1127+
else
11251128
equation
11261129
num = number[w];
11271130
(num == 0) = false;
1128-
(i1,stack,comps) = strongConnectMain(mt,a2,number,lowlink, n, i, w + 1, istack, icomps);
1131+
(i1,stack,comps) = strongConnectMain(mt,a2,number,lowlink, stackflag, n, i, w + 1, istack, icomps);
11291132
then
11301133
(i1,stack,comps);
11311134
end matchcontinue;
@@ -1143,7 +1146,8 @@ protected function strongConnect "function: strongConnect
11431146
input BackendDAE.IncidenceMatrixT mt;
11441147
input array<Integer> a2;
11451148
input array<Integer> number;
1146-
input array<Integer> lowlink;
1149+
input array<Integer> lowlink;
1150+
input array<Boolean> stackflag;
11471151
input Integer i;
11481152
input Integer v;
11491153
input list<Integer> stack;
@@ -1153,20 +1157,21 @@ protected function strongConnect "function: strongConnect
11531157
output list<list<Integer>> ocomps;
11541158
algorithm
11551159
(oi,ostack,ocomps):=
1156-
matchcontinue (mt,a2,number,lowlink,i,v,stack,comps)
1160+
matchcontinue (mt,a2,number,lowlink,stackflag,i,v,stack,comps)
11571161
local
11581162
Integer i_1;
11591163
list<Integer> stack_1,eqns,stack_2,stack_3,comp;
11601164
list<list<Integer>> comps_1,comps_2;
1161-
case (_,_,_,_,_,_,_,_)
1165+
case (_,_,_,_,_,_,_,_,_)
11621166
equation
11631167
i_1 = i + 1;
11641168
_ = arrayUpdate(number,v,i_1);
11651169
_ = arrayUpdate(lowlink,v,i_1);
11661170
stack_1 = (v :: stack);
1171+
_ = arrayUpdate(stackflag,v,true);
11671172
eqns = reachableNodes(v, mt, a2);
1168-
(i_1,stack_2,comps_1) = iterateReachableNodes(eqns, mt, a2,number,lowlink, i_1, v, stack_1, comps);
1169-
(stack_3,comp) = checkRoot(v, stack_2,number,lowlink);
1173+
(i_1,stack_2,comps_1) = iterateReachableNodes(eqns, mt, a2, number, lowlink, stackflag, i_1, v, stack_1, comps);
1174+
(stack_3,comp) = checkRoot(v, stack_2, number, lowlink, stackflag);
11701175
comps_2 = consIfNonempty(comp, comps_1);
11711176
then
11721177
(i_1,stack_3,comps_2);
@@ -1251,7 +1256,8 @@ protected function iterateReachableNodes "function: iterateReachableNodes
12511256
input BackendDAE.IncidenceMatrixT mt;
12521257
input array<Integer> a2;
12531258
input array<Integer> number;
1254-
input array<Integer> lowlink;
1259+
input array<Integer> lowlink;
1260+
input array<Boolean> stackflag;
12551261
input Integer i;
12561262
input Integer v;
12571263
input list<Integer> istack;
@@ -1261,45 +1267,45 @@ protected function iterateReachableNodes "function: iterateReachableNodes
12611267
output list<list<Integer>> outComps;
12621268
algorithm
12631269
(outI,outStack,outComps):=
1264-
matchcontinue (eqns,mt,a2,number,lowlink,i,v,istack,icomps)
1270+
matchcontinue (eqns,mt,a2,number,lowlink,stackflag,i,v,istack,icomps)
12651271
local
12661272
Integer i1,lv,lw,minv,w,nw,nv,lowlinkv;
12671273
list<Integer> stack,ws;
12681274
list<list<Integer>> comps_1,comps_2,comps;
12691275

12701276
// empty case
1271-
case ({},_,_,_,_,_,_,_,_) then (i,istack,icomps);
1277+
case ({},_,_,_,_,_,_,_,_,_) then (i,istack,icomps);
12721278

12731279
// nw is 0
1274-
case ((w :: ws),_,_,_,_,_,_,_,_)
1280+
case ((w :: ws),_,_,_,_,_,_,_,_,_)
12751281
equation
12761282
true = intEq(number[w],0);
1277-
(i1,stack,comps_1) = strongConnect(mt, a2, number, lowlink, i, w, istack, icomps);
1283+
(i1,stack,comps_1) = strongConnect(mt, a2, number, lowlink, stackflag, i, w, istack, icomps);
12781284
lv = lowlink[v];
12791285
lw = lowlink[w];
12801286
minv = intMin(lv, lw);
12811287
_ = arrayUpdate(lowlink,v,minv);
1282-
(i1,stack,comps_2) = iterateReachableNodes(ws, mt, a2, number, lowlink, i1, v, stack, comps_1);
1288+
(i1,stack,comps_2) = iterateReachableNodes(ws, mt, a2, number, lowlink, stackflag, i1, v, stack, comps_1);
12831289
then
12841290
(i1,stack,comps_2);
12851291

12861292
// nw
1287-
case ((w :: ws),_,_,_,_,_,_,_,_)
1293+
case ((w :: ws),_,_,_,_,_,_,_,_,_)
12881294
equation
12891295
nw = number[w];
12901296
nv = lowlink[v];
12911297
(nw < nv) = true;
1292-
true = listMember(w, istack);
1298+
true = stackflag[w];
12931299
lowlinkv = lowlink[v];
12941300
minv = intMin(nw, lowlinkv);
12951301
_ = arrayUpdate(lowlink,v,minv);
1296-
(i1,stack,comps) = iterateReachableNodes(ws, mt, a2, number, lowlink, i, v, istack, icomps);
1302+
(i1,stack,comps) = iterateReachableNodes(ws, mt, a2, number, lowlink, stackflag, i, v, istack, icomps);
12971303
then
12981304
(i1,stack,comps);
12991305

1300-
case ((_ :: ws),_,_,_,_,_,_,_,_)
1306+
case ((_ :: ws),_,_,_,_,_,_,_,_,_)
13011307
equation
1302-
(i1,stack,comps) = iterateReachableNodes(ws, mt, a2, number, lowlink, i, v, istack, icomps);
1308+
(i1,stack,comps) = iterateReachableNodes(ws, mt, a2, number, lowlink, stackflag, i, v, istack, icomps);
13031309
then
13041310
(i1,stack,comps);
13051311

@@ -1317,24 +1323,25 @@ protected function checkRoot "function: checkRoot
13171323
input Integer v;
13181324
input list<Integer> istack;
13191325
input array<Integer> number;
1320-
input array<Integer> lowlink;
1326+
input array<Integer> lowlink;
1327+
input array<Boolean> stackflag;
13211328
output list<Integer> ostack;
13221329
output list<Integer> ocomps;
13231330
algorithm
13241331
(ostack,ocomps):=
1325-
matchcontinue (v,istack,number,lowlink)
1332+
matchcontinue (v,istack,number,lowlink,stackflag)
13261333
local
13271334
Integer lv,nv;
13281335
list<Integer> comps,stack;
1329-
case (_,_,_,_)
1336+
case (_,_,_,_,_)
13301337
equation
13311338
lv = lowlink[v];
13321339
nv = number[v];
13331340
true = intEq(lv,nv);
1334-
(stack,comps) = checkStack(nv, istack, number, {});
1341+
(stack,comps) = checkStack(nv, istack, number, stackflag, {});
13351342
then
13361343
(stack,comps);
1337-
case (_,_,_,_) then (istack,{});
1344+
else then (istack,{});
13381345
end matchcontinue;
13391346
end checkRoot;
13401347

@@ -1349,22 +1356,24 @@ protected function checkStack "function: checkStack
13491356
input Integer vn;
13501357
input list<Integer> istack;
13511358
input array<Integer> number;
1359+
input array<Boolean> stackflag;
13521360
input list<Integer> icomp;
13531361
output list<Integer> ostack;
13541362
output list<Integer> ocomp;
13551363
algorithm
13561364
(ostack,ocomp):=
1357-
matchcontinue (vn,istack,number,icomp)
1365+
matchcontinue (vn,istack,number,stackflag,icomp)
13581366
local
13591367
Integer top;
13601368
list<Integer> rest,comp,stack;
1361-
case (_,(top :: rest),_,_)
1369+
case (_,(top :: rest),_,_,_)
13621370
equation
13631371
true = intGe(number[top],vn);
1364-
(stack,comp) = checkStack(vn, rest, number, top :: icomp);
1372+
_ = arrayUpdate(stackflag,top,false);
1373+
(stack,comp) = checkStack(vn, rest, number, stackflag, top :: icomp);
13651374
then
13661375
(stack,comp);
1367-
case (_,_,_,_) then (istack,icomp);
1376+
else then (istack,listReverse(icomp));
13681377
end matchcontinue;
13691378
end checkStack;
13701379

Compiler/BackEnd/Tearing.mo

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ protected
274274
array<list<Integer>> mapEqnIncRow;
275275
array<Integer> mapIncRowEqn;
276276
DAE.FunctionTree funcs;
277+
array<Boolean> stackflag;
277278
algorithm
278279
// generate Subsystem to get the incidence matrix
279280
size := listLength(vindx);
@@ -333,9 +334,10 @@ algorithm
333334
// subsyst := BackendDAE.EQSYSTEM(vars,eqns,SOME(m1),SOME(mt1),BackendDAE.MATCHING(ass1,ass2,{}));
334335
// BackendDump.printEqSystem(subsyst);
335336
number := arrayCreate(size,0);
336-
lowlink := arrayCreate(size,0);
337+
lowlink := arrayCreate(size,0);
338+
stackflag := arrayCreate(size,false);
337339
number := setIntArray(residual,number,size);
338-
(_,_,othercomps) := BackendDAETransform.strongConnectMain(mt1, ass2, number, lowlink, size, 0, 1, {}, {});
340+
(_,_,othercomps) := BackendDAETransform.strongConnectMain(mt1, ass2, number, lowlink, stackflag, size, 0, 1, {}, {});
339341
Debug.fcall(Flags.TEARING_DUMP, print, "OtherEquationsOrder:\n");
340342
Debug.fcall(Flags.TEARING_DUMP, BackendDump.dumpComponentsOLD,othercomps);
341343
Debug.fcall(Flags.TEARING_DUMP, print, "\n");

0 commit comments

Comments
 (0)