sugi2.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606
  1. /*
  2. * Copyright 2021
  3. * (C) Universitaet Passau 1986-1991 (34 year old c-source)
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * These are the four essential freedoms with GNU GPL software:
  19. * 1: freedom to run the program, for any purpose
  20. * 2: freedom to study how the program works, and change it to make it do what you wish
  21. * 3: freedom to redistribute copies to help your Free Software friends
  22. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  23. * , ,
  24. * / \
  25. * ((__-^^-,-^^-__))
  26. * `-_---' `---_-'
  27. * `--|o` 'o|--'
  28. * \ ` /
  29. * ): :(
  30. * :o_o:
  31. * "-"
  32. *
  33. * SPDX-License-Identifier: GPL-3.0+
  34. * License-Filename: LICENSE
  35. */
  36. /* this is a re-work of 1 file part of graphlet program */
  37. /* graphviz dot does layout in multiple steps of parts of the graph
  38. * todo this is prepared for similar task but need more updates.
  39. */
  40. #include "config.h"
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <limits.h> /* for CHAR_BIT is 8 definition */
  45. #include "main.h"
  46. #include "hier.h"
  47. #include "uniqnode.h"
  48. #include "sugi.h"
  49. #include "dpmem.h"
  50. struct mmatrix {
  51. int level; /* upper level */
  52. int nrows; /* nr. of rows (in upper level) */
  53. int ncols; /* nr. of cols (in level+1) */
  54. int nbytes; /* bytes used for matrix */
  55. int *mi0; /* row node id's level i */
  56. int nmi0; /* how many byte's in mi0 */
  57. int *m0i; /* col node id's level (i+1) */
  58. int nm0i; /* how many bytes in m0i */
  59. int bbytes; /* bytes for double barycenter values */
  60. double *b; /* buffer barycenter values */
  61. unsigned char *bits; /* matrix bits */
  62. };
  63. static inline void setbit(unsigned char a[], int k)
  64. {
  65. if (k == 0) {
  66. printf("setbit(0)\n");
  67. fflush(stdout);
  68. } else {
  69. a[k / CHAR_BIT] |= (1 << (k % CHAR_BIT));
  70. }
  71. return;
  72. }
  73. static inline void clearbit(unsigned char a[], int k)
  74. {
  75. if (k == 0) {
  76. printf("clearbit(0)\n");
  77. fflush(stdout);
  78. } else {
  79. a[k / CHAR_BIT] &= ~(1 << (k % CHAR_BIT));
  80. }
  81. return;
  82. }
  83. static inline int testbit(struct mmatrix *m, unsigned char a[], int k)
  84. {
  85. int ret = 0;
  86. unsigned int mask = 0;
  87. unsigned int mask2 = 0;
  88. unsigned int i = 0;
  89. if (k == 0) {
  90. printf("testbit(0)\n");
  91. fflush(stdout);
  92. }
  93. /* todo here tofix */
  94. if (k > ((m->ncols + 1) * (m->nrows + 1))) {
  95. printf("%s(): k=%d max is %d\n", __func__, k, ((m->ncols + 1) * (m->nrows + 1)));
  96. }
  97. /* compiler issue: the use of << is undefined here */
  98. /* issue CHAR_BIT is often 8 but does not have to be 8 */
  99. mask = (k % CHAR_BIT);
  100. /*old: mask2 = (1 << mask); */
  101. mask2 = 1;
  102. for (i = 0; i < mask; i++) {
  103. mask2 = (mask2 * 2);
  104. }
  105. ret = ((a[k / CHAR_BIT]) & mask2);
  106. /*old return ((a[k / CHAR_BIT] & (1 << (k % CHAR_BIT))) != 0); */
  107. return (ret);
  108. }
  109. /* i cols, j rows */
  110. static inline int mget(struct mmatrix *m, int i, int j)
  111. {
  112. return (testbit(m, m->bits, ((i * (m->ncols + 0)) + j)));
  113. }
  114. /* i is the from-node, j is the to-node, value is 1 for edge, otherwise 0 */
  115. static inline void mget_set(struct mmatrix *m, int i, int j, int value)
  116. {
  117. if (value) {
  118. setbit(m->bits, ((i * (m->ncols + 0)) + j));
  119. } else {
  120. clearbit(m->bits, ((i * (m->ncols + 0)) + j));
  121. }
  122. return;
  123. }
  124. static int number_of_crossings2(struct mmatrix *m, int r, int c)
  125. {
  126. int j = 0;
  127. int k = 0;
  128. int alpha = 0;
  129. int beta = 1;
  130. int result = 0;
  131. for (j = 1; j <= r - 1; j++) {
  132. for (k = j + 1; k <= r; k++) {
  133. for (alpha = 1; alpha <= c - 1; alpha++) {
  134. for (beta = alpha + 1; beta <= c; beta++) {
  135. /* here 1*0=0, 0*1=0, 0*0=0 or 1*1=1 */
  136. result = result + ((mget(m, j, beta) * mget(m, k, alpha)));
  137. }
  138. }
  139. }
  140. }
  141. return (result);
  142. }
  143. /*
  144. * crossings
  145. * computes the number of crossings
  146. * algorithm:
  147. * matrix[i][j] represents the number of edges between position i on the upper
  148. * level and position j on the lower level, call it (i,j).
  149. * The edges crossing edge (i,j) from right to left are exactly those
  150. * edges (k,l) with k > i and l < j. You get the number of those edges
  151. * by adding all elements of the submatrix[k][l] with k > i and l < j.
  152. * The product of the elements of the submatrix and m[i][j] yields the
  153. * number of crossings.
  154. * To compute all crossings you must iterate over all elements of the matrix.
  155. * This computation time is linear in the size of the matrix.
  156. */
  157. static int number_of_crossings3(struct mmatrix *m, int r, int c)
  158. {
  159. int j = 0;
  160. int k = 0;
  161. int alpha = 0;
  162. int beta = 1;
  163. int result2 = 0;
  164. if (0) {
  165. result2 = number_of_crossings2(m, r, c);
  166. }
  167. for (j = 1; j <= (r - 1); j++) {
  168. for (k = (j + 1); k <= r; k++) {
  169. for (alpha = 1; alpha <= (c - 1); alpha++) {
  170. /* */
  171. if (mget(m, k, alpha)) {
  172. for (beta = alpha + 1; beta <= c; beta++) {
  173. /* */
  174. if (mget(m, j, beta)) {
  175. result2++;
  176. }
  177. }
  178. }
  179. /* */
  180. }
  181. }
  182. }
  183. return (result2);
  184. }
  185. /* number of crossings in whole graph */
  186. static int number_of_crossings_a(struct gml_graph *g, struct mmatrix **mm)
  187. {
  188. int ktot = 0;
  189. int k = 0;
  190. int i = 0;
  191. for (i = 0; i < g->maxlevel; i++) {
  192. if (mm[i]) {
  193. k = number_of_crossings3(mm[i], mm[i]->nrows, mm[i]->ncols);
  194. /* save number of edge crossings at level */
  195. g->numce[i] = k;
  196. ktot = ktot + k;
  197. }
  198. }
  199. return (ktot);
  200. }
  201. /* configure matrix data for level l in the graph */
  202. static void make_matrix(struct gml_graph *g, int l, struct mmatrix *m)
  203. {
  204. struct gml_nlist *nl = NULL;
  205. struct gml_elist *el = NULL;
  206. int i = 0;
  207. int j = 0;
  208. int c = 0;
  209. int r = 0;
  210. /* add node numbers in the 0 position */
  211. nl = g->nodelist;
  212. while (nl) {
  213. /* if (level(n) == l) */
  214. if (nl->node->rely == l) {
  215. /* rows */
  216. i = nl->node->relx;
  217. m->mi0[i] = nl->node->nr; /* uniq node number, not id */
  218. } else if (nl->node->rely == (l + 1)) {
  219. /* columns */
  220. j = nl->node->relx;
  221. m->m0i[j] = nl->node->nr; /* uniq node number, not id */
  222. }
  223. nl = nl->next;
  224. }
  225. /* matrix bits config, first init then set bits. */
  226. r = m->nrows;
  227. c = m->ncols;
  228. for (i = 1; i <= r; i++) {
  229. for (j = 1; j <= c; j++) {
  230. mget_set(m, i, j, 0);
  231. }
  232. }
  233. nl = g->nodelist;
  234. while (nl) {
  235. /* if (level(n) == l) */
  236. if (nl->node->rely == l) {
  237. /* outgoing edges : for_sourcelist (n, e) */
  238. el = nl->node->outgoing_e;
  239. while (el) {
  240. /* skip the horizontal edges */
  241. if (el->edge->hedge == 0) {
  242. /* from-node rel. x pos */
  243. i = nl->node->relx;
  244. /* to-node rel. x pos */
  245. j = el->edge->to_node->relx;
  246. /* set this is edge */
  247. mget_set(m, i, j, 1);
  248. }
  249. el = el->next;
  250. }
  251. }
  252. nl = nl->next;
  253. }
  254. if (0) {
  255. printf("make_matrix(): initial matrix level %d (%dx%d)\n", m->level, m->nrows, m->ncols);
  256. fflush(stdout);
  257. printf("\nm->bits():\n");
  258. fflush(stdout);
  259. r = m->nrows;
  260. c = m->ncols;
  261. for (i = 1; i <= r; i++) {
  262. for (j = 1; j <= c; j++) {
  263. if (mget(m, i, j)) {
  264. printf("0");
  265. } else {
  266. printf("1");
  267. }
  268. }
  269. printf("\n");
  270. fflush(stdout);
  271. }
  272. printf("\n");
  273. fflush(stdout);
  274. }
  275. return;
  276. }
  277. /* find node with given id number */
  278. static struct gml_node *su_find_node_with_number(struct gml_graph *g, int nr)
  279. {
  280. if (g) {
  281. }
  282. /* NULL for the global database or g for local database */
  283. /* uniqnode2() is the work nodes db in nodelist */
  284. return (uniqnode2(NULL, nr));
  285. }
  286. static void store_new_positions(struct gml_graph *g, struct mmatrix *m, int l)
  287. {
  288. struct gml_node *n = NULL;
  289. int i = 0;
  290. if (m == NULL) {
  291. return;
  292. }
  293. for (i = 1; i <= m->nrows; i++) {
  294. /* rows */
  295. n = su_find_node_with_number(g, m->mi0[i]);
  296. if (n) {
  297. if (0) {
  298. printf("node nr=%d from x=%d to x=%d y=%d\n", n->nr, n->relx, i, l);
  299. }
  300. /* offset is 1, make it into 0..n */
  301. n->relx = (i - 1);
  302. } else {
  303. printf("%s(): no node with nr=%d found (0)\n", __func__, m->mi0[i]);
  304. }
  305. }
  306. for (i = 1; i <= m->ncols; i++) {
  307. /* columns */
  308. n = su_find_node_with_number(g, m->m0i[i]);
  309. if (n) {
  310. if (0) {
  311. printf("node nr=%d from x=%d to x=%d y=%d\n", n->nr, n->relx, i, l + 1);
  312. }
  313. /* offset is 1, make it into 0..n */
  314. n->relx = (i - 1);
  315. } else {
  316. printf("%s(): no node with nr=%d found (1)\n", __func__, m->m0i[i]);
  317. }
  318. }
  319. return;
  320. }
  321. /* copy matrix m1 to m2 */
  322. static void copy_m(struct mmatrix *m1, struct mmatrix *m2)
  323. {
  324. if (m1 && m2) {
  325. m2->level = m1->level; /* upper level */
  326. m2->nrows = m1->nrows; /* nr. of rows (in upper level) */
  327. m2->ncols = m1->ncols; /* nr. of cols (in level+1) */
  328. m2->nbytes = m1->nbytes; /* bytes used for matrix */
  329. (void)memmove(m2->bits, m1->bits, m1->nbytes); /* matrix bits */
  330. (void)memmove(m2->mi0, m1->mi0, m1->nmi0); /* row node id's level i */
  331. m2->nmi0 = m1->nmi0; /* how many byte's in mi0 */
  332. (void)memmove(m2->m0i, m1->m0i, m1->nm0i); /* col node id's level (i+1) */
  333. m2->nm0i = m1->nm0i; /* how many bytes in m0i */
  334. m2->bbytes = m1->bbytes; /* bytes for double barycenter values */
  335. (void)memmove(m2->b, m1->b, m1->bbytes); /* barycenter values */
  336. }
  337. return;
  338. }
  339. /* are m1,m2 equal? */
  340. static int equal_m(struct mmatrix *m1, struct mmatrix *m2, int r, int c)
  341. {
  342. int i = 0;
  343. int j = 0;
  344. for (i = 1; i <= r; i++) {
  345. for (j = 1; j <= c; j++) {
  346. if (mget(m1, i, j) != mget(m2, i, j)) {
  347. return (0); /* FALSE */
  348. }
  349. }
  350. }
  351. return (1); /* TRUE */
  352. }
  353. /* is whole graph equal */
  354. static int equal_a(struct gml_graph *g, struct mmatrix **mm1, struct mmatrix **mm2)
  355. {
  356. int l = 0;
  357. if (mm1 == NULL || mm2 == NULL) {
  358. return (0);
  359. }
  360. for (l = 0; l < g->maxlevel; l++) {
  361. if (equal_m(mm1[l], mm2[l], mm1[l]->nrows /* old g->nnodes_of_level[l] */ ,
  362. mm1[l]->ncols /* old g->nnodes_of_level[l + 1] */ ) ==
  363. 0 /* FALSE */ ) {
  364. return (0); /* FALSE */
  365. }
  366. }
  367. return (1); /* TRUE */
  368. }
  369. /* copy whole graph */
  370. static inline void copy_a(struct gml_graph *g, struct mmatrix **mm1, struct mmatrix **mm2)
  371. {
  372. int i = 0;
  373. for (i = 0; i < g->maxlevel; i++) {
  374. copy_m(mm1[i], mm2[i]);
  375. }
  376. return;
  377. }
  378. static void exch_rows(struct mmatrix *m, int r1, int r2)
  379. {
  380. int j = 0;
  381. int id1 = 0;
  382. int id2 = 0;
  383. int bit1 = 0;
  384. int bit2 = 0;
  385. /*
  386. * h = m[r1][j];
  387. * m[r1][j] = m[r2][j];
  388. * m[r2][j] = h;
  389. */
  390. /* swap node id numbers */
  391. id1 = m->mi0[r1];
  392. id2 = m->mi0[r2];
  393. m->mi0[r1] = id2;
  394. m->mi0[r2] = id1;
  395. /* swap matrix bits */
  396. for (j = 1; j <= m->ncols; j++) {
  397. bit1 = mget(m, r1, j);
  398. bit2 = mget(m, r2, j);
  399. mget_set(m, r1, j, bit2);
  400. mget_set(m, r2, j, bit1);
  401. }
  402. return;
  403. }
  404. static void exch_columns(struct mmatrix *m, int c1, int c2)
  405. {
  406. int i = 0;
  407. int id1 = 0;
  408. int id2 = 0;
  409. int bit1 = 0;
  410. int bit2 = 0;
  411. /*
  412. * h = m[i][c1];
  413. * m[i][c1] = m[i][c2];
  414. * m[i][c2] = h;
  415. */
  416. /* swap node id numbers */
  417. id1 = m->m0i[c1];
  418. id2 = m->m0i[c2];
  419. m->m0i[c1] = id2;
  420. m->m0i[c2] = id1;
  421. /* swap matrix bits */
  422. for (i = 1; i <= m->nrows; i++) {
  423. bit1 = mget(m, i, c1);
  424. bit2 = mget(m, i, c2);
  425. mget_set(m, i, c1, bit2);
  426. mget_set(m, i, c2, bit1);
  427. }
  428. return;
  429. }
  430. static int reverse_r(struct mmatrix *m, int r1, int r2)
  431. {
  432. int i = 0;
  433. int j = 0;
  434. int ch = 0;
  435. for (i = r1, j = r2; i < j; i++, j--) {
  436. ch++;
  437. exch_rows(m, i, j);
  438. }
  439. return (ch);
  440. }
  441. static int reverse_c(struct mmatrix *m, int c1, int c2)
  442. {
  443. int i = 0;
  444. int j = 0;
  445. int ch = 0;
  446. for (i = c1, j = c2; i < j; i++, j--) {
  447. ch++;
  448. exch_columns(m, i, j);
  449. }
  450. return (ch);
  451. }
  452. static double row_barycenter(struct mmatrix *m, int i, int maxval)
  453. {
  454. int j = 0;
  455. int r1 = 0; /* sum */
  456. int r2 = 0; /* div */
  457. for (j = 1; j <= maxval; j++) {
  458. if (mget(m, i, j)) {
  459. r1 = r1 + j;
  460. r2++;
  461. }
  462. }
  463. if (r2 == 0) {
  464. return (0.0);
  465. } else {
  466. return ((double)r1 / (double)r2);
  467. }
  468. }
  469. static double column_barycenter(struct mmatrix *m, int j, int maxval)
  470. {
  471. int i = 0;
  472. int r1 = 0; /* sum */
  473. int r2 = 0; /* div */
  474. for (i = 1; i <= maxval; i++) {
  475. if (mget(m, i, j)) {
  476. r1 = r1 + i;
  477. r2++;
  478. }
  479. }
  480. if (r2 == 0) {
  481. return (0.0);
  482. } else {
  483. return ((double)r1 / (double)r2);
  484. }
  485. }
  486. /* reverse rows */
  487. static int r_r(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  488. {
  489. int i = 0;
  490. int j = 0;
  491. int ch = 0;
  492. for (i = 1; i <= max_r; i++) {
  493. m1->b[i] = row_barycenter(m1, i, max_c);
  494. }
  495. for (i = 1; i < max_r; i++) {
  496. j = i;
  497. while ((j < max_r) && (m1->b[j + 1] == m1->b[j])) {
  498. j++;
  499. }
  500. if (j > i) {
  501. ch += reverse_r(m1, i, j);
  502. if (m2 != NULL) {
  503. ch += reverse_c(m2, i, j);
  504. }
  505. i = j;
  506. }
  507. }
  508. return (ch);
  509. }
  510. /* reverse columns */
  511. static int r_c(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  512. {
  513. int i = 0;
  514. int j = 0;
  515. int ch = 0;
  516. for (i = 1; i <= max_c; i++) {
  517. m1->b[i] = column_barycenter(m1, i, max_r);
  518. }
  519. for (i = 1; i < max_c; i++) {
  520. j = i;
  521. while ((j < max_c) && (m1->b[j + 1] == m1->b[j])) {
  522. j++;
  523. }
  524. if (j > i) {
  525. ch += reverse_c(m1, i, j);
  526. if (m2 != NULL) {
  527. ch += reverse_r(m2, i, j);
  528. }
  529. i = j;
  530. }
  531. }
  532. return (ch);
  533. }
  534. /* barycenter rows */
  535. static int b_r(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  536. {
  537. double tmpb = 0.0;
  538. int i = 0;
  539. int j = 0;
  540. int k = 0;
  541. int ch = 0;
  542. for (i = 1; i <= max_r; i++) {
  543. m1->b[i] = row_barycenter(m1, i, max_c);
  544. }
  545. for (j = max_r; j > 1; j--) {
  546. if (m1->b[j] != 0.0) {
  547. for (i = 1; i < j; i++) {
  548. if (m1->b[i] != 0.0) {
  549. k = i + 1;
  550. while (m1->b[k] == 0.0) {
  551. k++;
  552. }
  553. if (m1->b[i] > m1->b[k]) {
  554. ch++;
  555. /* exch_double */
  556. tmpb = m1->b[k];
  557. m1->b[k] = m1->b[i];
  558. m1->b[i] = tmpb;
  559. exch_rows(m1, i, k);
  560. if (m2 != NULL) {
  561. ch++;
  562. /* exchange cols from i to k */
  563. exch_columns(m2, i, k);
  564. }
  565. }
  566. }
  567. }
  568. }
  569. }
  570. return (ch);
  571. }
  572. /* barycenter cols */
  573. static int b_c(struct mmatrix *m1, struct mmatrix *m2, int max_r, int max_c)
  574. {
  575. double tmpb = 0.0;
  576. int i = 0;
  577. int j = 0;
  578. int k = 0;
  579. int ch = 0;
  580. for (i = 1; i <= max_c; i++) {
  581. m1->b[i] = column_barycenter(m1, i, max_r);
  582. }
  583. for (j = max_c; j > 1; j--) {
  584. if (m1->b[j] != 0.0) {
  585. for (i = 1; i < j; i++) {
  586. if (m1->b[i] != 0.0) {
  587. k = i + 1;
  588. while (m1->b[k] == 0.0) {
  589. k++;
  590. }
  591. if (m1->b[i] > m1->b[k]) {
  592. ch++;
  593. /* exch_double */
  594. tmpb = m1->b[k];
  595. m1->b[k] = m1->b[i];
  596. m1->b[i] = tmpb;
  597. /* exchange cols from i to k */
  598. exch_columns(m1, i, k);
  599. if (m2 != NULL) {
  600. ch++;
  601. exch_rows(m2, i, k);
  602. }
  603. }
  604. }
  605. }
  606. }
  607. }
  608. return (ch);
  609. }
  610. /* test if array is sorted, 1 if sorted from hight-to-low */
  611. static int sorted(double *vector, int maxval)
  612. {
  613. int i = 0;
  614. for (i = 1; i < maxval; i++) {
  615. /* but ignore 0.0 values */
  616. if ((vector[i] > vector[i + 1]) && (vector[i + 1] != 0.0)) {
  617. return (0); /* FALSE */
  618. }
  619. }
  620. return (1); /* TRUE */
  621. }
  622. static inline int phase1_down(struct gml_graph *g, struct mmatrix **mm)
  623. {
  624. int i = 0;
  625. int ch = 0;
  626. /* from level0 down to level max */
  627. for (i = 0; i < g->maxlevel - 1; i++) {
  628. ch += b_c(mm[i], mm[i + 1], mm[i]->nrows, mm[i]->ncols);
  629. }
  630. ch += b_c(mm[g->maxlevel - 1], NULL, mm[g->maxlevel - 1]->nrows, mm[g->maxlevel - 1]->ncols);
  631. return (ch);
  632. }
  633. static inline int phase1_up(struct gml_graph *g, struct mmatrix **mm)
  634. {
  635. int i = 0;
  636. int ch = 0;
  637. if (mm == NULL) {
  638. return (0);
  639. }
  640. /* from level max up to level0 */
  641. for (i = (g->maxlevel - 1); i > 0; i--) {
  642. ch += b_r(mm[i], mm[i - 1], mm[i]->nrows /* old g->nnodes_of_level[i] */ ,
  643. mm[i]->ncols /* old g->nnodes_of_level[i + 1] */ );
  644. }
  645. ch += b_r(mm[0], NULL, mm[0]->nrows /* g->nnodes_of_level[0] */ ,
  646. mm[0]->ncols /* g->nnodes_of_level[1] */ );
  647. return (ch);
  648. }
  649. /* */
  650. static inline int phase2_down(struct gml_graph *g, struct mmatrix **mm)
  651. {
  652. int l = 0; /* Level */
  653. int i = 0;
  654. int ch = 0;
  655. for (l = 0; l < (g->maxlevel - 1); l++) {
  656. for (i = 1; i <= mm[l]->ncols /* g->nnodes_of_level[l + 1] */ ; i++) {
  657. mm[l]->b[i] = column_barycenter(mm[l], i, mm[l]->nrows /* g->nnodes_of_level[l] */ );
  658. }
  659. if (sorted(mm[l]->b, mm[l]->ncols /* g->nnodes_of_level[l + 1] */ ) ==
  660. 1 /* TRUE */ ) {
  661. /* reverse columns */
  662. ch += r_c(mm[l], mm[l + 1], mm[l]->nrows /* g->nnodes_of_level[l] */ ,
  663. mm[l]->ncols /* g->nnodes_of_level[l + 1] */ );
  664. } else {
  665. return (ch);
  666. }
  667. }
  668. for (i = 1; i <= g->nnodes_of_level[g->maxlevel]; i++) {
  669. mm[g->maxlevel - 1]->b[i] = column_barycenter(mm[g->maxlevel - 1], i, mm[g->maxlevel - 1]->nrows
  670. /* g->nnodes_of_level[g->maxlevel - 1] */ );
  671. }
  672. if (sorted(mm[g->maxlevel - 1]->b, mm[g->maxlevel - 1]->ncols /* g->nnodes_of_level[g->maxlevel] */ ) ==
  673. 1 /* TRUE */ ) {
  674. /* reverse columns */
  675. ch += r_c(mm[g->maxlevel - 1], NULL, mm[g->maxlevel - 1]->nrows /* g->nnodes_of_level[g->maxlevel - 1] */ ,
  676. mm[g->maxlevel - 1]->ncols /* g->nnodes_of_level[g->maxlevel] */ );
  677. }
  678. return (ch);
  679. }
  680. /* */
  681. static inline int phase2_up(struct gml_graph *g, struct mmatrix **mm)
  682. {
  683. int l = 0; /* Level */
  684. int i = 0;
  685. int ch = 0;
  686. if (g) {
  687. }
  688. for (l = (g->maxlevel - 1); l > 0; l--) {
  689. for (i = 1; i <= /* g->nnodes_of_level[l] */ mm[l]->nrows; i++) {
  690. mm[l]->b[i] = row_barycenter(mm[l], i, /* g->nnodes_of_level[l + 1] */
  691. mm[l]->ncols);
  692. }
  693. if (sorted(mm[l]->b, /* g->nnodes_of_level[l] */ mm[l]->nrows) ==
  694. 1 /* TRUE */ ) {
  695. /* reverse rows */
  696. ch += r_r(mm[l], mm[l - 1], mm[l]->nrows /* g->nnodes_of_level[l] */ ,
  697. mm[l]->ncols /* g->nnodes_of_level[l + 1] */ );
  698. } else {
  699. return (ch);
  700. }
  701. }
  702. for (i = 1; i <= mm[0]->nrows /* g->nnodes_of_level[0] */ ; i++) {
  703. mm[0]->b[i] = row_barycenter(mm[0], i, mm[0]->ncols /* g->nodes_of_level[1] */ );
  704. }
  705. /* if level0 is sorted, r_r */
  706. if (sorted(mm[0]->b, mm[0]->nrows /* g->nnodes_of_level[0] */ ) ==
  707. 1 /* TRUE */ ) {
  708. /* reverse rows */
  709. ch += r_r(mm[0], NULL, mm[0]->nrows /* g->nnodes_of_level[0] */ ,
  710. mm[0]->ncols /* g->nnodes_of_level[1] */ );
  711. }
  712. return (ch);
  713. }
  714. /* convert large number to easier human string */
  715. static const char *humansize(int bytes)
  716. {
  717. static char output[200];
  718. char *suffix[] = { "", "K", "M", "G", "T" };
  719. char length = sizeof(suffix) / sizeof(suffix[0]);
  720. int i = 0;
  721. double dblbytes = bytes;
  722. if (bytes > 1000) {
  723. for (i = 0; (bytes / 1000) > 0 && i < length - 1; i++, bytes /= 1000)
  724. dblbytes = bytes / 1000.0;
  725. }
  726. memset(output, 0, 200);
  727. snprintf(output, (200 - 1), "%.01lf %s", dblbytes, suffix[i]);
  728. return output;
  729. }
  730. /* here if maxlevel >1 */
  731. static void bc_n(struct gml_graph *g, int it1value, int it2value)
  732. {
  733. char charbuffer[64];
  734. struct mmatrix **a = NULL;
  735. struct mmatrix **a1 = NULL;
  736. struct mmatrix **a2 = NULL;
  737. struct mmatrix **as = NULL;
  738. int i = 0;
  739. int ks = 0;
  740. int k = 0;
  741. int n1 = 0;
  742. int n2 = 0;
  743. int cht = 0;
  744. int ch1 = 0;
  745. int ch2 = 0;
  746. int r1 = 0;
  747. int r2 = 0;
  748. int r3 = 0;
  749. int rr1 = 0;
  750. int rr2 = 0;
  751. int rr3 = 0;
  752. int it1 = 20; /* iterations phase1 */
  753. int it2 = 40; /* iterations pahse2 */
  754. if (it1value == 0) {
  755. it1 = 20;
  756. } else {
  757. it1 = it1value;
  758. }
  759. if (it2value == 0) {
  760. it2 = 40;
  761. } else {
  762. it2 = it2value;
  763. }
  764. /* the whole graph structures */
  765. a = dp_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  766. a1 = dp_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  767. a2 = dp_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  768. as = dp_calloc(1, g->maxlevel * sizeof(struct mmatrix *));
  769. /* get matrix struct */
  770. for (i = 0; i < g->maxlevel; i++) {
  771. a[i] = dp_calloc(1, sizeof(struct mmatrix));
  772. a1[i] = dp_calloc(1, sizeof(struct mmatrix));
  773. a2[i] = dp_calloc(1, sizeof(struct mmatrix));
  774. as[i] = dp_calloc(1, sizeof(struct mmatrix));
  775. }
  776. /* get data inside struct */
  777. for (i = 0; i < g->maxlevel; i++) {
  778. /* upper level */
  779. a[i]->level = i;
  780. a1[i]->level = i;
  781. a2[i]->level = i;
  782. as[i]->level = i;
  783. /* number of rows */
  784. a[i]->nrows = g->nnodes_of_level[i];
  785. a1[i]->nrows = g->nnodes_of_level[i];
  786. a2[i]->nrows = g->nnodes_of_level[i];
  787. as[i]->nrows = g->nnodes_of_level[i];
  788. /* number of columns */
  789. a[i]->ncols = g->nnodes_of_level[i + 1];
  790. a1[i]->ncols = g->nnodes_of_level[i + 1];
  791. a2[i]->ncols = g->nnodes_of_level[i + 1];
  792. as[i]->ncols = g->nnodes_of_level[i + 1];
  793. /* buffer for barycenter values */
  794. if (a[i]->nrows > a[i]->ncols) {
  795. a[i]->bbytes = ((a[i]->nrows + 1) * sizeof(double));
  796. a1[i]->bbytes = ((a1[i]->nrows + 1) * sizeof(double));
  797. a2[i]->bbytes = ((a2[i]->nrows + 1) * sizeof(double));
  798. as[i]->bbytes = ((as[i]->nrows + 1) * sizeof(double));
  799. } else {
  800. a[i]->bbytes = ((a[i]->ncols + 1) * sizeof(double));
  801. a1[i]->bbytes = ((a1[i]->ncols + 1) * sizeof(double));
  802. a2[i]->bbytes = ((a2[i]->ncols + 1) * sizeof(double));
  803. as[i]->bbytes = ((as[i]->ncols + 1) * sizeof(double));
  804. }
  805. a[i]->b = dp_calloc(1, a[i]->bbytes);
  806. a1[i]->b = dp_calloc(1, a1[i]->bbytes);
  807. a2[i]->b = dp_calloc(1, a2[i]->bbytes);
  808. as[i]->b = dp_calloc(1, as[i]->bbytes);
  809. /* number of bytes used */
  810. a[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  811. a1[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  812. a2[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  813. as[i]->nmi0 = ((a[i]->nrows + 1) * sizeof(int));
  814. /* row node id's (int's) */
  815. a[i]->mi0 = dp_calloc(1, a[i]->nmi0);
  816. a1[i]->mi0 = dp_calloc(1, a1[i]->nmi0);
  817. a2[i]->mi0 = dp_calloc(1, a2[i]->nmi0);
  818. as[i]->mi0 = dp_calloc(1, as[i]->nmi0);
  819. /* number of bytes used */
  820. a[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  821. a1[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  822. a2[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  823. as[i]->nm0i = ((a[i]->ncols + 1) * sizeof(int));
  824. /* col node id's (int's) */
  825. a[i]->m0i = dp_calloc(1, a[i]->nm0i);
  826. a1[i]->m0i = dp_calloc(1, a1[i]->nm0i);
  827. a2[i]->m0i = dp_calloc(1, a2[i]->nm0i);
  828. as[i]->m0i = dp_calloc(1, as[i]->nm0i);
  829. /* bits array for the matrix */
  830. a[i]->nbytes = 1 + ((((a[i]->nrows + 1) * (a[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  831. a1[i]->nbytes = 1 + ((((a1[i]->nrows + 1) * (a1[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  832. a2[i]->nbytes = 1 + ((((a2[i]->nrows + 1) * (a2[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  833. as[i]->nbytes = 1 + ((((as[i]->nrows + 1) * (as[i]->ncols + 1)) + CHAR_BIT) / CHAR_BIT);
  834. a[i]->bits = dp_calloc(1, a[i]->nbytes);
  835. a1[i]->bits = dp_calloc(1, a1[i]->nbytes);
  836. a2[i]->bits = dp_calloc(1, a2[i]->nbytes);
  837. as[i]->bits = dp_calloc(1, as[i]->nbytes);
  838. }
  839. /* fill the matrix with data for all levels */
  840. for (i = 0; i < g->maxlevel; i++) {
  841. make_matrix(g, i, a[i]);
  842. }
  843. copy_a(g, a, as);
  844. ks = number_of_crossings_a(g, as);
  845. printf("bc_n(++): initial crossings is %d\n", ks);
  846. fflush(stdout);
  847. /* update status text line */
  848. memset(charbuffer, 0, 64);
  849. snprintf(charbuffer, (64 - 1), "initial crossings is %d", ks);
  850. update_status_text_cross(charbuffer);
  851. g->sugi_icrossings = ks; /* sugiyama initial crossings */
  852. if (ks > 0) {
  853. /* Phase1 */
  854. ch1 = 0;
  855. /* first does alwasy improve */
  856. ch1 += phase1_down(g, a);
  857. copy_a(g, a, as);
  858. ch1 += phase1_up(g, a);
  859. copy_a(g, a, as);
  860. /* loop phase1 */
  861. n1 = 0;
  862. do {
  863. copy_a(g, a, a1);
  864. ch1 += phase1_down(g, a);
  865. k = number_of_crossings_a(g, a);
  866. if (k < ks) {
  867. /* reduced crossings, save the new state */
  868. ks = k;
  869. copy_a(g, a, as);
  870. }
  871. ch1 += phase1_up(g, a);
  872. k = number_of_crossings_a(g, a);
  873. if (k < ks) {
  874. ks = k;
  875. copy_a(g, a, as);
  876. }
  877. cht += ch1;
  878. printf("bc_n(++): current crossings phase1 is %d (%d:%d) ch1=%d cht=%d\n", ks, n1, n2, ch1, cht);
  879. fflush(stdout);
  880. /* update status text line */
  881. memset(charbuffer, 0, 64);
  882. snprintf(charbuffer, (64 - 1), "phase 1 crossings is now %d", ks);
  883. update_status_text_cross(charbuffer);
  884. if (ks == 0) {
  885. break;
  886. }
  887. /* check if number of crossings changed */
  888. r1 = r2;
  889. r2 = r3;
  890. r3 = ks;
  891. if (r1 == r2) {
  892. if (r2 == r3) {
  893. break;
  894. }
  895. }
  896. }
  897. while (++n1 < it1 && (equal_a(g, a, a1) == 0 /* FALSE */ ));
  898. /* if matrices differ, save state */
  899. if (equal_a(g, a, as) == 0 /* FALSE */ ) {
  900. copy_a(g, as, a);
  901. }
  902. if (ks > 0) {
  903. /* Phase2 */
  904. n2 = 0;
  905. cht += ch1;
  906. do {
  907. ch2 = 0;
  908. copy_a(g, a, a2);
  909. ch2 += phase2_down(g, a);
  910. n1 = 0;
  911. do {
  912. ch1 = 0;
  913. copy_a(g, a, a1);
  914. ch1 += phase1_down(g, a);
  915. k = number_of_crossings_a(g, a);
  916. if (k < ks) {
  917. ks = k;
  918. copy_a(g, a, as);
  919. }
  920. ch1 += phase1_up(g, a);
  921. k = number_of_crossings_a(g, a);
  922. if (k < ks) {
  923. ks = k;
  924. copy_a(g, a, as);
  925. }
  926. if (ks == 0) {
  927. break;
  928. }
  929. /* check if number of crossings changed */
  930. rr1 = rr2;
  931. rr2 = rr3;
  932. rr3 = ks;
  933. if (rr1 == rr2) {
  934. if (rr2 == rr3) {
  935. break;
  936. }
  937. }
  938. }
  939. while (++n1 < it1 && equal_a(g, a, a1) == 0 /* FALSE */ );
  940. ch2 += phase2_up(g, a);
  941. n1 = 0;
  942. do {
  943. copy_a(g, a, a1);
  944. ch1 += phase1_up(g, a);
  945. k = number_of_crossings_a(g, a);
  946. if (k < ks) {
  947. ks = k;
  948. copy_a(g, a, as);
  949. }
  950. ch1 += phase1_down(g, a);
  951. k = number_of_crossings_a(g, a);
  952. if (k < ks) {
  953. ks = k;
  954. copy_a(g, a, as);
  955. }
  956. cht += ch1;
  957. printf("bc_n(++): current crossings phase2 is %d (%d:%d) ch1=%d ch2=%d cht=%d\n", ks, n1, n2, ch1, ch2, cht);
  958. fflush(stdout);
  959. /* update status text line */
  960. memset(charbuffer, 0, 64);
  961. snprintf(charbuffer, (64 - 1), "phase 2 crossings is now %d", ks);
  962. update_status_text_cross(charbuffer);
  963. if (ks == 0) {
  964. break;
  965. }
  966. /* check if number of crossings changed */
  967. rr1 = rr2;
  968. rr2 = rr3;
  969. rr3 = ks;
  970. if (rr1 == rr2) {
  971. if (rr2 == rr3) {
  972. break;
  973. }
  974. }
  975. }
  976. while (++n1 < it1 && equal_a(g, a, a1) == 0 /* FALSE */ );
  977. cht += ch1;
  978. cht += ch2;
  979. if (ks == 0) {
  980. break;
  981. }
  982. /* check if number of crossings changed */
  983. r1 = r2;
  984. r2 = r3;
  985. r3 = ks;
  986. if (r1 == r2) {
  987. if (r2 == r3) {
  988. break;
  989. }
  990. }
  991. }
  992. while (++n2 < it2 && equal_a(g, a, a2) == 0 /* FALSE */ );
  993. }
  994. }
  995. /* sugiyama final crossings */
  996. g->sugi_fcrossings = ks;
  997. /* sugiyama changes made */
  998. g->sugi_changes = cht;
  999. printf("bc_n(++): final crossings is %d after %d (%s) changes made\n", ks, cht, humansize(cht));
  1000. fflush(stdout);
  1001. /* update status text line */
  1002. memset(charbuffer, 0, 64);
  1003. snprintf(charbuffer, (64 - 1), "final crossings is now %d", ks);
  1004. update_status_text_cross(charbuffer);
  1005. for (i = 0; i < g->maxlevel; i += 2) {
  1006. /* set new node positions for 2 levels */
  1007. store_new_positions(g, as[i], i);
  1008. }
  1009. if (i == g->maxlevel) {
  1010. store_new_positions(g, as[g->maxlevel - 1], (g->maxlevel - 1));
  1011. }
  1012. for (i = 0; i < g->maxlevel; i++) {
  1013. if (a[i]) {
  1014. a[i]->b = dp_free(a[i]->b);
  1015. if (a[i]->b) {
  1016. }
  1017. a[i]->mi0 = dp_free(a[i]->mi0);
  1018. if (a[i]->mi0) {
  1019. }
  1020. a[i]->m0i = dp_free(a[i]->m0i);
  1021. if (a[i]->m0i) {
  1022. }
  1023. a[i]->bits = dp_free(a[i]->bits);
  1024. if (a[i]->bits) {
  1025. }
  1026. }
  1027. if (a1[i]) {
  1028. a1[i]->b = dp_free(a1[i]->b);
  1029. if (a1[i]->b) {
  1030. }
  1031. a1[i]->mi0 = dp_free(a1[i]->mi0);
  1032. if (a1[i]->mi0) {
  1033. }
  1034. a1[i]->m0i = dp_free(a1[i]->m0i);
  1035. if (a1[i]->m0i) {
  1036. }
  1037. a1[i]->bits = dp_free(a1[i]->bits);
  1038. if (a1[i]->bits) {
  1039. }
  1040. }
  1041. if (a2[i]) {
  1042. a2[i]->b = dp_free(a2[i]->b);
  1043. if (a2[i]->b) {
  1044. }
  1045. a2[i]->mi0 = dp_free(a2[i]->mi0);
  1046. if (a2[i]->mi0) {
  1047. }
  1048. a2[i]->m0i = dp_free(a2[i]->m0i);
  1049. if (a2[i]->m0i) {
  1050. }
  1051. a2[i]->bits = dp_free(a2[i]->bits);
  1052. if (a2[i]->bits) {
  1053. }
  1054. }
  1055. if (as[i]) {
  1056. as[i]->b = dp_free(as[i]->b);
  1057. if (as[i]->b) {
  1058. }
  1059. as[i]->mi0 = dp_free(as[i]->mi0);
  1060. if (as[i]->mi0) {
  1061. }
  1062. as[i]->m0i = dp_free(as[i]->m0i);
  1063. if (as[i]->m0i) {
  1064. }
  1065. as[i]->bits = dp_free(as[i]->bits);
  1066. if (as[i]->bits) {
  1067. }
  1068. }
  1069. }
  1070. for (i = 0; i < g->maxlevel; i++) {
  1071. a[i] = dp_free(a[i]);
  1072. if (a[i]) {
  1073. }
  1074. a1[i] = dp_free(a1[i]);
  1075. if (a1[i]) {
  1076. }
  1077. a2[i] = dp_free(a2[i]);
  1078. if (a2[i]) {
  1079. }
  1080. as[i] = dp_free(as[i]);
  1081. if (as[i]) {
  1082. }
  1083. }
  1084. a = dp_free(a);
  1085. if (a) {
  1086. }
  1087. a1 = dp_free(a1);
  1088. if (a1) {
  1089. }
  1090. a2 = dp_free(a2);
  1091. if (a2) {
  1092. }
  1093. as = dp_free(as);
  1094. if (as) {
  1095. }
  1096. return;
  1097. }
  1098. /*
  1099. This algorithm is for routing hierarchies of elements. A "good route" is
  1100. one that has a minimum number of link crossings. An algorithm that was
  1101. truly optimal (for minimizing link crossings) would be combinatorial and
  1102. therefore cost prohibitive; therefore, this algorithm uses a heuristic
  1103. approach that finds a route with close to the minimum number of crossings
  1104. in a reasonable amount of time.
  1105. This algorithm assumes that all the elements form a directed acyclic graph
  1106. (DAG), which means (1) that links flow one way between elements and (2) for
  1107. any given node there is no way to get back to the node if, starting at the
  1108. node, you traverse the links going from node to node. This algorithm also
  1109. assumes that AT MOST only ONE link may exist between a pair of nodes.
  1110. -------------------------------------------------------------------------------
  1111. OVERVIEW OF ALGORITHM
  1112. All elements that do not have any parents are placed in the first row (row 0).
  1113. Elements are assigned to rows, where the row number for each child is equal to
  1114. the [maximum(row number of all its parents) + 1]. Crossovers are determined
  1115. by examining links between elements on adjacent rows, so if a parent is in a
  1116. row that is not adjacent to its child's row, "dummy" nodes are created on the
  1117. rows in between the parent and child, and the parent and child are connected
  1118. via these dummy nodes.
  1119. Once the elements (now called nodes) are assigned to individual rows, the
  1120. rows are sorted (repeatedly) in order to minimize link crossings. The
  1121. sort criteria involves attempting to both center children under parents and
  1122. to center parents over children. The sort orders are then tweaked by swapping
  1123. nodes that have the same sort value.
  1124. After the column orders are finalized, the nodes are spread out so they are
  1125. more or less centered above their children and below their parents. When
  1126. centering children below parents, a row of children is sorted by which node
  1127. has the greatest number of parents. These get first choice of where to be
  1128. placed under the parents (actually, dummy nodes get first preference, then
  1129. all of the others). Centering parents above children is analogous.
  1130. When done with node placement, there may be some empty columns, and the
  1131. numbering scheme may not start at 0. Therefore, the empty columns must
  1132. be eliminated and every node needs its column renumbered, starting at 0.
  1133. Then you are done.
  1134. -------------------------------------------------------------------------------
  1135. REALIZATION MATRIX
  1136. When it comes to both sorting nodes and horizontally spacing the nodes, two
  1137. adjacent rows are always involved. For example, if we are sorting row[i]
  1138. based on the children of row[i]'s nodes, then row[i+1] is also involved
  1139. at this step. These two rows are called the "i-th realization", and form
  1140. the "i-th realization matrix". A realization matrix shows the parent-child
  1141. relationships between adjacent rows, with the parents on the rows and the
  1142. children on the columns. If there is a parent-child relationship, a 1 is
  1143. stored in the matrix at the position, else a 0 is stored.
  1144. An example:
  1145. A B C D
  1146. \ \ / \ / / |
  1147. \ /\ / \ / |
  1148. /\ / \ / \ |
  1149. / /\ /\ \ |
  1150. // \ / \ \|
  1151. E F G H
  1152. E F G H
  1153. A 0 1 1 0 In this example, parent 'A' has children 'F' and 'G',
  1154. B 1 0 0 1 parent 'B' has children 'E' and 'H',
  1155. C 1 1 0 0 parent 'C' has children 'E' and 'F',
  1156. D 0 0 0 1 and parent 'D' has child 'H'.
  1157. -------------------------------------------------------------------------------
  1158. ROW AND COLUMN BARYCENTERS
  1159. Two other important concepts are the "row barycenter" and the "column
  1160. barycenter" for a node. The "row barycenter" is the basically the average
  1161. of the positions of a node's children. The "column barycenter" is the average
  1162. of the positions of a node's parents. These numbers tell us where a node
  1163. would like to be positioned in its row, depending whether we are positioning
  1164. relative to children or parents.
  1165. For example, using the above realization matrix, we can calculate the row
  1166. barycenters for A, B, C, and D, and the column barycenters for E, F, G, and H.
  1167. Since the row barycenter of a node is equal to the sum of the positions of
  1168. the node's children divided by the number of children of the node, the row
  1169. barycenter for A is (1 + 2)/2 = 1.5. This assumes that we start numbering
  1170. rows and columns at 0. Similarly, the column barycenter of a node is equal
  1171. to the sum of the positions of the node's parents divided by the number of
  1172. parents of the node. So, the column barycenter of F is (0 + 2)/2 = 1.0.
  1173. The complete example is as follows:
  1174. Row
  1175. | E F G H | Barys
  1176. ------+--------------------+-----
  1177. A | 0 1 1 0 | 1.5
  1178. B | 1 0 0 1 | 1.5
  1179. C | 1 1 0 0 | 0.5
  1180. D | 0 0 0 1 | 3.0
  1181. ------+--------------------+-----
  1182. Col | 1.5 1.0 0.0 2.0 |
  1183. Barys | |
  1184. If we were to sort the child nodes here by their column barycenters, the new
  1185. order would be G, F, E, H. If we were to sort the parent nodes here by their
  1186. row barycenters, then the order would be C, A, B, D (if two or more nodes have
  1187. the same value, be sure to keep the same precedence that already exists
  1188. between them, e.g., make sure that order after sorting is not C, B, A, D).
  1189. If a node has no parents then it can't have a column barycenter. This case
  1190. should never happen, as all nodes that have no parents should be in the first
  1191. level of the hierarchy, and these nodes would only be represented in
  1192. realization matrix 0, and they would only have row barycenters.
  1193. If a node has no children then it can't have a row barycenter. In this case,
  1194. while sorting based on row barycenters, sort AROUND these nodes, i.e., do
  1195. not change their positions at all. For example, if we had the following:
  1196. Row
  1197. | W X Y Z | Barys
  1198. ------+--------------------+-----
  1199. Q | 0 1 1 1 | 2.0
  1200. R | 0 0 0 0 | ???
  1201. S | 1 0 0 0 | 0.0
  1202. T | 0 1 0 1 | 2.0
  1203. ------+--------------------+-----
  1204. Col | 2.0 1.5 0.0 1.5 |
  1205. Barys | |
  1206. and we were to sort by row barycenters, the resulting order should be S, R,
  1207. Q, T. Notice how R stayed in its position, and even though Q and T had the
  1208. same barycentric value, Q stayed before T.
  1209. The whole reason for sorting rows and columns by their barycenters is to
  1210. decrease the number of crossovers.
  1211. -------------------------------------------------------------------------------
  1212. CROSSOVERS
  1213. The realization matrix is also used to count the number of crossovers between
  1214. two adjacent rows of nodes. For each row, starting with the second row, if
  1215. a row element has a 1, then sum up all of the matrix elements that are above
  1216. AND to the right of this element. Looking again at the first example:
  1217. A B C D
  1218. \ \ / \ / / |
  1219. \ /\ / \ / |
  1220. /\ / \ / \ |
  1221. / /\ /\ \ |
  1222. // \ / \ \|
  1223. E F G H
  1224. Row
  1225. | E F G H | Barys
  1226. ------+--------------------+-----
  1227. A | 0 1 1 0 | 1.5
  1228. B | 1 0 0 1 | 1.5
  1229. C | 1 1 0 0 | 0.5
  1230. D | 0 0 0 1 | 3.0
  1231. ------+--------------------+-----
  1232. Col | 1.5 1.0 0.0 2.0 |
  1233. Barys | |
  1234. Starting with the second row (parent B's row), position B-E has a 1. Looking
  1235. at positions above and to the right, we see positions A-F and A-G both have
  1236. a 1, so the number of crossovers is currently = 2. Position B-H has a 1, but
  1237. there are no elements above and to the right, so crossovers is still = 2.
  1238. For parent row of C, position C-E crosses over with B-H, A-F, and A-G, so
  1239. crossovers = 5. C-F crosses over with B-H and A-G, so crossovers = 7. For
  1240. parent row D, position D-H doesn't cross over with any other link. So for
  1241. this realization matrix representing these two rows, the number of crossovers
  1242. is 7.
  1243. The total number of crossovers for the whole graph would be the sum of the
  1244. crossovers from each matrix realization.
  1245. -------------------------------------------------------------------------------
  1246. NODE CENTERING
  1247. After the nodes for each row have their final sort order, the nodes need to
  1248. be assigned to grid positions. Their initial grid position will be their
  1249. column position, by which we mean their array position in the row. From now
  1250. on, when we take a row or column barycenter, we will be using grid positions
  1251. instead of column positions.
  1252. Note: The following examples will be based on centering children with respect
  1253. to their parents' positions. Centering parents based on their children's
  1254. positions is analogous.
  1255. When positioning the nodes on a row based on their parents' positions, the
  1256. nodes must be initially sorted to see which nodes get first choice. The dummy
  1257. nodes go first, and the rest of nodes are sorted in descending order based on
  1258. the number of parents the node has. If a dummy node has a parent that has
  1259. multiple dummy nodes, all of these dummy nodes are again sorted by how close
  1260. to the center of the parent's children they are. This is a confusing
  1261. statement, best illustrated by example:
  1262. P1 P2
  1263. \ |
  1264. \ __________^__________
  1265. \| | | | |
  1266. C1 D1 D2 C2 D3
  1267. Here, parent P1 has one child, C1. Parent P2 has five children, and three of
  1268. the child nodes are dummy nodes: D1, D2, and D3. C1 is child 0 of P2, D1 is
  1269. child 1 of P2, D2 is child 2 of P2, C2 is child 3 of P2, and D3 is child 4 of
  1270. P2. The child midpoint underneath the parent is equal to
  1271. (the number of children - 1) / 2, so (5 - 1) / 2 = 2. Since the dummy nodes
  1272. go first, the initial order is D1, D2, D3, C1 (because it has 2 parents), and
  1273. finally C2. All of the dummy nodes have the same parent, so we will sort them
  1274. based on how far away they are from the parent's child midpoint. D1 is child
  1275. 1 of P2, so it is 1 away. D2 is child 2 of P2, so it is 0 away. D3 is child
  1276. 4 of P2, so it is 2 away. Therefore, the final order for choosing positions
  1277. is D2, D1, D3, C1, C2.
  1278. In a situation similar to the dummy nodes, if a non-dummy node has a only one
  1279. parent, and that parent has other children with just one parent, then these
  1280. one parent child nodes that have the same parent need additional sorting in
  1281. the exact same manner that we just did the dummy nodes.
  1282. The whole purpose behind this is so that the left most node doesn't get first
  1283. choice. If it did, we would get graphs that look like:
  1284. A A
  1285. | |
  1286. |_________ instead of _____^_____
  1287. | | | | | |
  1288. B C D B C D
  1289. Anyway, once we have a sort order for the nodes of a row, we place the nodes
  1290. in their preferred positions. Using the previous example, assume that P1
  1291. is in grid position 2 and P2 is in grid position 5. D2 gets first choice,
  1292. and its column barycenter (based now on parent grid positions, not column
  1293. positions) is 5, so we place D2 in position 5. D1 is next, its barycenter
  1294. is also 5. We can't give it 5 since that position is occupied, so we give
  1295. it the closest possible position we can, which in this case is 4. D3 is next,
  1296. and its barycenter is also 5. The closest position that we can give it is
  1297. position 7, since we must allow room for C2. C1 is next, and its barycenter
  1298. is (2 + 5)/2 = 3.5, which we round to 3. Position 3 is open, so we go ahead
  1299. and give it position 3. C2 is last, and its barycenter is 5. However, the
  1300. first position available to it based on its left neighbor is position 6, so
  1301. we assign it position 6.
  1302. -------------------------------------------------------------------------------
  1303. GOING 'UP' OR 'DOWN' THE GRAPH
  1304. "Going down the graph" means taking each realization matrix situation,
  1305. starting with Realization Matrix 0, and performing some action on it, then
  1306. going to the next realization matrix, and continuing until all of the
  1307. realization matrices have been visited.
  1308. "Going up the graph" is analogous, except you start at the bottom with the
  1309. last realization matrix and work up to Realization Matrix 0.
  1310. */
  1311. void reduce_crossings2(struct gml_graph *g, int it1v, int it2v)
  1312. {
  1313. /* number of crossing edges at level */
  1314. if (g->numce) {
  1315. g->numce = dp_free(g->numce);
  1316. if (g->numce) {
  1317. }
  1318. }
  1319. g->numce = (int *)dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  1320. /* with too complex graph data at least this message is on console before cpu get roasted. */
  1321. printf("%s(): starting barycenter algorithm for graph with %d nodes, %d edges in %d levels ... wait\n", __func__, g->nnodes,
  1322. g->nedges, g->maxlevel);
  1323. fflush(stdout);
  1324. if (g->maxlevel == 0) {
  1325. /* if graph has only 1 or more nodes */
  1326. return;
  1327. }
  1328. if (g->nnodes < 2) {
  1329. return;
  1330. }
  1331. if (g->nedges < 2) {
  1332. return;
  1333. }
  1334. bc_n(g, it1v, it2v);
  1335. return;
  1336. }
  1337. /* end */