sugi3.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /*
  2. * Copyright 2021
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * These are the four essential freedoms with GNU GPL software:
  18. * 1: freedom to run the program, for any purpose
  19. * 2: freedom to study how the program works, and change it to make it do what you wish
  20. * 3: freedom to redistribute copies to help your Free Software friends
  21. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  22. * , ,
  23. * / \
  24. * ((__-^^-,-^^-__))
  25. * `-_---' `---_-'
  26. * `--|o` 'o|--'
  27. * \ ` /
  28. * ): :(
  29. * :o_o:
  30. * "-"
  31. *
  32. * SPDX-License-Identifier: GPL-3.0+
  33. * License-Filename: LICENSE
  34. */
  35. #include "config.h"
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <math.h> /* for fabs() */
  40. #include "main.h"
  41. #include "hier.h"
  42. #include "uniqnode.h"
  43. #include "sugi.h"
  44. #include "dpmem.h"
  45. /* updated qsort() to stable qsort() see https://nullprogram.com/blog/2014/08/29/ */
  46. /* how much double values may differ when seen as same */
  47. #define LOWVAL (0.01)
  48. /* set to 1 for debug output */
  49. static int s3debug = 0;
  50. /* max level */
  51. static int gmaxlevel = 0;
  52. struct vertex {
  53. int id; /* uniq node number */
  54. int level; /* rel. y level */
  55. int *child; /* outgoing edges */
  56. int no_of_child; /* number of outgoing edges */
  57. int *parent; /* incoming edges */
  58. int no_of_parent; /* number of incoming edges */
  59. double barydown; /* barycenter value */
  60. double baryup; /* barycenter value */
  61. int x; /* final rel. x pos */
  62. int y; /* final rel. y pos */
  63. int qsortpos; /* position for qsort */
  64. };
  65. /* node data arrays */
  66. static struct vertex **tree = NULL;
  67. /* extra crossings check */
  68. static int doublecheck = 0;
  69. /* */
  70. static int nooflevels = 4;
  71. /* nodes at level */
  72. static struct gml_nlist **glevelnodes = NULL;
  73. static struct gml_nlist **glevelnodesend = NULL;
  74. /* number of nodes at level */
  75. static int *nglevelnodes = NULL;
  76. /* bool going down */
  77. static int down = 0;
  78. /* */
  79. #define BARY(x) (down ? x->barydown : x->baryup)
  80. #define UN_BARY(x) (down ? x->baryup : x->barydown)
  81. static int mediancomp(const void *a, const void *b)
  82. {
  83. int *x = (int *)a;
  84. int *y = (int *)b;
  85. if (*x == *y) {
  86. return (0);
  87. }
  88. if (*x > *y) {
  89. return (1);
  90. }
  91. return (-1);
  92. }
  93. /* compare bary values */
  94. static int comparevalue(const void *a, const void *b)
  95. {
  96. struct vertex *x = (struct vertex *)a;
  97. struct vertex *y = (struct vertex *)b;
  98. /* if (BARY(x) == BARY(y)) */
  99. if (fabs(BARY(x) - BARY(y)) <= LOWVAL) {
  100. /* using pos. this changes the qsort() into stable qsort() */
  101. return (y->qsortpos - x->qsortpos);
  102. }
  103. if (BARY(x) > BARY(y)) {
  104. return (1);
  105. }
  106. return (-1);
  107. }
  108. /* a=child/parent numbers, b=id of node, c=no_of_child/parents */
  109. static int *intchr(int *a, int b, int c)
  110. {
  111. int i = 0;
  112. /* find pos. of node id in b in child/parent nodes */
  113. while (i < c) {
  114. if (b == a[i]) {
  115. return (a + i);
  116. }
  117. i++;
  118. }
  119. /* notfound shouldnothappen */
  120. return ((int *)0);
  121. }
  122. /* how many nodes at level */
  123. static int levellength(int level)
  124. {
  125. if (level < 0) {
  126. printf("%s(): level %d out of range\n", __func__, level);
  127. fflush(stdout);
  128. return (0);
  129. }
  130. if (level > gmaxlevel) {
  131. printf("%s(): level %d out of range\n", __func__, level);
  132. fflush(stdout);
  133. return (0);
  134. }
  135. return (nglevelnodes[level]);
  136. }
  137. /* median barycenter value of one node.
  138. * often the average is used of the positions of connecting nodes.
  139. * the median value is the middle number in a sorted list of positions:
  140. * example: 1 2 6 7 12
  141. * the median is the number 6 in the middle.
  142. * the average is 1+2+6+7+12/5 = 5.6
  143. * some tools have options to changed the way this barycenter is determined for different layouts.
  144. * qsort() is not stable sort which means that equal values can be swapped.
  145. * turn qsort into stable qsort adding position data.
  146. */
  147. static void medianvalue(struct vertex *a)
  148. {
  149. int la = 0;
  150. int ll = 0;
  151. int i = 0;
  152. int j = 0;
  153. double left = 0;
  154. double right = 0;
  155. double m = 0.0;
  156. int *orders = NULL;
  157. struct vertex *adjacent = NULL;
  158. if (a == NULL) {
  159. return;
  160. }
  161. /* get next level */
  162. if (down) {
  163. la = (a[0].level + 1);
  164. adjacent = tree[la];
  165. ll = levellength(adjacent[0].level);
  166. } else {
  167. la = (a[0].level - 1);
  168. if (la < 0) {
  169. printf("%s(): la=%d is out of range\n", __func__, la);
  170. fflush(stdout);
  171. return;
  172. }
  173. adjacent = tree[la];
  174. ll = levellength(adjacent[0].level);
  175. }
  176. /* no nodes at adj. */
  177. if (ll == 0) {
  178. if (down) {
  179. a->barydown = (-1.0);
  180. } else {
  181. a->baryup = (-1);
  182. }
  183. return;
  184. }
  185. orders = dp_calloc(1, ((ll + 1) * sizeof(int)));
  186. #define RELATIVE(x) (down ? x->child : x->parent)
  187. #define LENGTH(x) (down ? x->no_of_child : x->no_of_parent)
  188. j = 0;
  189. for (i = 1; i <= ll; i++) {
  190. /* find pos. of node id in b in child/parent nodes */
  191. if (intchr(RELATIVE(a), adjacent[i - 1].id, LENGTH(a))) {
  192. orders[j] = i;
  193. j++;
  194. }
  195. }
  196. if (s3debug) {
  197. printf("%s(): %d nmemb\n", __func__, j);
  198. }
  199. /* sort if more then 1 item to sort */
  200. if (j > 1) {
  201. /* to make this stable qsort() it needs extra position data field */
  202. qsort(orders, j, sizeof(int), mediancomp);
  203. }
  204. if (j == 0) {
  205. if (down) {
  206. a->barydown = (-1.0);
  207. } else {
  208. a->baryup = (-1.0);
  209. }
  210. orders = dp_free(orders);
  211. if (orders) {
  212. }
  213. return;
  214. }
  215. if (j % 2) {
  216. if (down) {
  217. a->barydown = ((double)orders[(j - 1) / 2]);
  218. } else {
  219. a->baryup = ((double)orders[(j - 1) / 2]);
  220. }
  221. orders = dp_free(orders);
  222. if (orders) {
  223. }
  224. return;
  225. }
  226. if (j == 2) {
  227. if (down) {
  228. a->barydown = (((double)orders[0] + (double)orders[1]) / 2.0);
  229. } else {
  230. a->baryup = (((double)orders[0] + (double)orders[1]) / 2.0);
  231. }
  232. orders = dp_free(orders);
  233. if (orders) {
  234. }
  235. return;
  236. }
  237. left = (double)orders[j / 2 - 1] - (double)orders[0];
  238. right = (double)orders[j - 1] - (double)orders[j / 2];
  239. m = 1.0 * ((double)orders[j / 2 - 1] * right + 1.0 * (double)orders[j / 2] * left) / (left + right);
  240. if (down) {
  241. a->barydown = m;
  242. } else {
  243. a->baryup = m;
  244. }
  245. orders = dp_free(orders);
  246. if (orders) {
  247. }
  248. return;
  249. }
  250. /* */
  251. static int twovertcross(struct vertex *a, struct vertex *b, int *sorted, int k)
  252. {
  253. int i = 0;
  254. int j = 0;
  255. int sum = 0;
  256. int *c = NULL;
  257. int *d = NULL;
  258. if (s3debug) {
  259. printf("node %d has %d children, node %d has %d children\n", a->id, a->no_of_child, b->id, b->no_of_child);
  260. }
  261. if (a->no_of_child == 0) {
  262. return (0);
  263. }
  264. if (b->no_of_child == 0) {
  265. return (0);
  266. }
  267. for (i = 0; i < a->no_of_child; i++) {
  268. for (j = 0; j < b->no_of_child; j++) {
  269. c = intchr(sorted, a->child[i], k);
  270. d = intchr(sorted, b->child[j], k);
  271. if ((c - sorted) > (d - sorted)) {
  272. sum++;
  273. }
  274. }
  275. }
  276. return sum;
  277. }
  278. /* */
  279. static int levelcross(struct vertex *a)
  280. {
  281. int lb = 0;
  282. int i = 0;
  283. int j = 0;
  284. int t = 0;
  285. int k = 0;
  286. int sum = 0;
  287. struct vertex *b = NULL;
  288. int *sorted = NULL;
  289. if ((a[0].level != 0) && ((down == 0) || (doublecheck != 0))) {
  290. lb = a[0].level - 1;
  291. if (lb < 0) {
  292. printf("%s(): lb is %d out of range\n", __func__, lb);
  293. fflush(stdout);
  294. return (0);
  295. }
  296. b = tree[lb];
  297. if (b == NULL) {
  298. printf("%s(): tree[%d] is null\n", __func__, lb);
  299. fflush(stdout);
  300. return (0);
  301. }
  302. k = levellength(a[0].level);
  303. sorted = (int *)dp_calloc(1, ((k + 2) * sizeof(int)));
  304. /* */
  305. for (i = 0; i < k; i++) {
  306. sorted[i] = a[i].id;
  307. }
  308. t = levellength(b[0].level);
  309. for (i = 0; i < t - 1; i++) {
  310. for (j = i + 1; j < t; j++) {
  311. sum += twovertcross(b + i, b + j, sorted, k);
  312. }
  313. }
  314. sorted = dp_free(sorted);
  315. if (sorted) {
  316. }
  317. if (s3debug) {
  318. printf("%s(): sum(1) is %d\n", __func__, sum);
  319. }
  320. return (sum);
  321. }
  322. if ((a[0].level < (nooflevels - 1)) && ((down != 0) || (doublecheck != 0))) {
  323. lb = a[0].level + 1;
  324. b = tree[lb];
  325. k = levellength(b[0].level);
  326. sorted = (int *)dp_calloc(1, ((k + 2) * sizeof(int)));
  327. /* */
  328. for (i = 0; i < k; i++) {
  329. sorted[i] = b[i].id;
  330. }
  331. t = levellength(a[0].level);
  332. for (i = 0; i < t - 1; i++) {
  333. for (j = i + 1; j < t; j++) {
  334. sum += twovertcross(a + i, a + j, sorted, k);
  335. }
  336. }
  337. sorted = dp_free(sorted);
  338. if (sorted) {
  339. }
  340. if (s3debug) {
  341. printf("%s(): sum(2) is %d\n", __func__, sum);
  342. }
  343. return (sum);
  344. }
  345. if (s3debug || 1) {
  346. printf("%s(): sum(3) is %d out of range\n", __func__, sum);
  347. }
  348. return (sum);
  349. }
  350. /* check eq bary values in t nodes at this level */
  351. static int equals(struct vertex *a, int t)
  352. {
  353. int res = 0;
  354. int i = 0;
  355. struct vertex *temp = NULL;
  356. temp = dp_calloc(1, sizeof(struct vertex));
  357. /* */
  358. for (i = 0; i < t - 1; i++) {
  359. /* if (BARY((a+i)) == BARY((a+i+1))) */
  360. if (fabs(BARY((a + i)) - BARY((a + i + 1))) <= LOWVAL) {
  361. memcpy(temp, a + i, sizeof(struct vertex));
  362. memcpy(a + i, a + i + 1, sizeof(struct vertex));
  363. memcpy(a + i + 1, temp, sizeof(struct vertex));
  364. /* indicate that changes were made */
  365. res++;
  366. if (s3debug) {
  367. printf("%s(): swap\n", __func__);
  368. }
  369. }
  370. }
  371. temp = dp_free(temp);
  372. if (temp) {
  373. }
  374. /* return 0 if no changes made, <>0 if changed */
  375. return (res);
  376. }
  377. /* sort between level a and level b */
  378. static void mediansort(struct gml_graph *g, struct vertex *a, struct vertex *b)
  379. {
  380. int t = 0;
  381. int tb = 0;
  382. int i = 0;
  383. int p = 0;
  384. int la = 0;
  385. int ld = 0;
  386. struct vertex *dummy = NULL;
  387. struct vertex *dummy2 = NULL;
  388. struct vertex *temp = NULL;
  389. if (a == NULL) { /* shouldnothappen */
  390. return;
  391. }
  392. if (b == NULL) { /* shouldnothappen */
  393. return;
  394. }
  395. if (a[0].level == b[0].level) {
  396. printf("%s(): a %p and b %p have same level %d out of range\n", __func__, (void *)a, (void *)b, a[0].level);
  397. fflush(stdout);
  398. return;
  399. }
  400. if (a[0].level < 0 || a[0].level > gmaxlevel) {
  401. printf("%s(): level-a %d out of range 0...%d\n", __func__, a[0].level, gmaxlevel);
  402. fflush(stdout);
  403. return;
  404. }
  405. if (b[0].level < 0 || b[0].level > gmaxlevel) {
  406. printf("%s(): level-b %d out of range 0...%d\n", __func__, b[0].level, gmaxlevel);
  407. fflush(stdout);
  408. return;
  409. }
  410. /* how many nodes at level of a */
  411. t = levellength(a[0].level);
  412. if (t == 0) {
  413. /* this can happen but shouldnot XXX fixme */
  414. return;
  415. printf("%s(): a-level 0 nodes at level %d\n", __func__, a[0].level);
  416. }
  417. /* how many nodes at level of b */
  418. tb = levellength(b[0].level);
  419. if (tb == 0) {
  420. /* this can happen but shouldnot XXX fixme */
  421. return;
  422. printf("%s(): b-level 0 nodes at level %d\n", __func__, b[0].level);
  423. }
  424. /* XXX */
  425. if (a[0].level >= b[0].level) {
  426. down = 0;
  427. } else {
  428. down = 1;
  429. }
  430. if (s3debug || 0) {
  431. printf("%s(): level-a=%d has %d nodes, level-b=%d has %d nodes, down=%d\n", __func__, a[0].level, t, b[0].level, tb, down);
  432. }
  433. /* buffer for test result */
  434. dummy = dp_calloc(1, ((t + 1) * sizeof(struct vertex)));
  435. dummy2 = dummy;
  436. /* calc node median of every node at level a */
  437. for (i = 0; i < t; i++) {
  438. medianvalue(a + i);
  439. if (s3debug || 0) {
  440. /* print node bary value */
  441. if (down) {
  442. printf("%s(): barydown=%f node %d\n", __func__, (a + i)->barydown, (a + i)->id);
  443. } else {
  444. printf("%s(): baryup=%f node %d\n", __func__, (a + i)->baryup, (a + i)->id);
  445. }
  446. }
  447. }
  448. /* copy a to dummy as backup */
  449. memcpy(dummy, a, ((t + 1) * sizeof(struct vertex)));
  450. if (s3debug || 0) {
  451. printf("%s(): sorting %d nmemb\n", __func__, t);
  452. }
  453. /* sort on barycenter value if more then 1 member */
  454. if (t > 1) {
  455. /* set pos to change qsort() into stable qsort */
  456. for (i = 0; i < t; i++) {
  457. tree[a[0].level]->qsortpos = i;
  458. }
  459. qsort(tree[a[0].level], t, sizeof(struct vertex), comparevalue);
  460. }
  461. la = levelcross(a);
  462. ld = levelcross(dummy);
  463. if (s3debug || 0) {
  464. printf("%s(): crossings level-a=%d is %d in a versus %d in dummy\n", __func__, a[0].level, la, ld);
  465. }
  466. /* save this crossing count */
  467. g->numce[a[0].level] = la;
  468. if (la == 0) {
  469. dummy2 = dp_free(dummy2);
  470. if (dummy2) {
  471. }
  472. return;
  473. }
  474. /* if crossings in a > in dummy, use dummy backup */
  475. if (la > ld) {
  476. /* dummy bacup is better: less crossings */
  477. temp = a;
  478. /* copy dummy to a */
  479. memcpy(a, dummy, ((t + 1) * sizeof(struct vertex))); /* tree[a[0].level] = dummy; */
  480. a = dummy;
  481. dummy = temp;
  482. /* save this crossing count */
  483. g->numce[a[0].level] = ld;
  484. if (ld == 0) {
  485. dummy2 = dp_free(dummy2);
  486. if (dummy2) {
  487. }
  488. return;
  489. }
  490. }
  491. for (p = 0; p < 15; p++) {
  492. /* copy a to dummy as backup */
  493. memcpy(dummy, a, ((t + 1) * sizeof(struct vertex)));
  494. /* swap nodes with same barycenter */
  495. if (equals(a, t) == 0) {
  496. /* no changes made to node positions in this level */
  497. break;
  498. }
  499. la = levelcross(a);
  500. if (la == 0) {
  501. break;
  502. }
  503. ld = levelcross(dummy);
  504. /* save this crossing count */
  505. g->numce[a[0].level] = la;
  506. if (la >= ld) {
  507. /* dummy backup has less crossings, continue with dummy */
  508. temp = a;
  509. /* copy dummy to a */
  510. memcpy(a, dummy, ((t + 1) * sizeof(struct vertex))); /* tree[a[0].level] = dummy; */
  511. a = dummy;
  512. dummy = temp;
  513. /* save this crossing count */
  514. g->numce[a[0].level] = ld;
  515. if (ld == 0) {
  516. break;
  517. }
  518. }
  519. }
  520. dummy2 = dp_free(dummy2);
  521. if (dummy2) {
  522. }
  523. return;
  524. }
  525. /* return 0 if graph has no crossings */
  526. static int check0(struct gml_graph *g)
  527. {
  528. int sum = 0;
  529. int i = 0;
  530. for (i = 0; i < (g->maxlevel + 1); i++) {
  531. sum += g->numce[i];
  532. if (sum) {
  533. break;
  534. }
  535. }
  536. return (sum);
  537. }
  538. /* create lists of nodes per level */
  539. static void cp_make_levelnodes(struct gml_graph *g)
  540. {
  541. struct gml_nlist *lnll = NULL;
  542. struct gml_nlist *newl = NULL;
  543. int i = 0;
  544. glevelnodes = dp_calloc(1, (g->maxlevel + 1) * sizeof(struct gml_nlist *));
  545. glevelnodesend = dp_calloc(1, (g->maxlevel + 1) * sizeof(struct gml_nlist *));
  546. nglevelnodes = dp_calloc(1, (g->maxlevel + 1) * sizeof(int));
  547. lnll = g->nodelist;
  548. while (lnll) {
  549. /* rel. y level set by dfs/bfs */
  550. i = lnll->node->rely;
  551. newl = dp_calloc(1, sizeof(struct gml_nlist));
  552. newl->node = lnll->node;
  553. if (glevelnodes[i] == NULL) {
  554. glevelnodes[i] = newl;
  555. glevelnodesend[i] = newl;
  556. } else {
  557. glevelnodesend[i]->next = newl;
  558. glevelnodesend[i] = newl;
  559. }
  560. /* number of nodes at this level */
  561. nglevelnodes[i]++;
  562. lnll = lnll->next;
  563. }
  564. /* extra check */
  565. for (i = 0; i < (g->maxlevel + 1); i++) {
  566. if (nglevelnodes[i] == 0) {
  567. /* shouldnothappen */
  568. printf("%s(): level %d has no nodes\n", __func__, i);
  569. fflush(stdout);
  570. }
  571. }
  572. return;
  573. }
  574. /* clear nodes at level */
  575. static void clr_levelnodes(struct gml_graph *g)
  576. {
  577. struct gml_nlist *lnll = NULL;
  578. struct gml_nlist *nlnext = NULL;
  579. int i = 0;
  580. if (glevelnodes == NULL) {
  581. return;
  582. }
  583. for (i = 0; i < (g->maxlevel + 1); i++) {
  584. /* lists per pos. */
  585. lnll = glevelnodes[i];
  586. while (lnll) {
  587. nlnext = lnll->next;
  588. lnll = dp_free(lnll);
  589. if (lnll) {
  590. }
  591. lnll = nlnext;
  592. }
  593. glevelnodes[i] = NULL;
  594. glevelnodesend[i] = NULL;
  595. }
  596. glevelnodes = dp_free(glevelnodes);
  597. if (glevelnodes) {
  598. }
  599. glevelnodesend = dp_free(glevelnodesend);
  600. if (glevelnodesend) {
  601. }
  602. nglevelnodes = dp_free(nglevelnodes);
  603. if (nglevelnodes) {
  604. }
  605. return;
  606. }
  607. /* copy data into tree data */
  608. static void cp_data(struct gml_graph *g)
  609. {
  610. struct gml_elist *el = NULL;
  611. struct gml_nlist *lnll = NULL;
  612. int i = 0;
  613. int count = 0;
  614. int k = 0;
  615. tree = dp_calloc(1, ((g->maxlevel + 2) * sizeof(struct vertex *)));
  616. /* create nodes on level */
  617. cp_make_levelnodes(g);
  618. for (i = 0; i < (g->maxlevel + 1); i++) {
  619. if (s3debug) {
  620. printf("%s(): level %d has %d nodes\n", __func__, i, nglevelnodes[i]);
  621. }
  622. tree[i] = dp_calloc(1, ((nglevelnodes[i] + 1) * sizeof(struct vertex)));
  623. tree[i][0].level = i;
  624. /* get list of nodes at level i */
  625. lnll = glevelnodes[i];
  626. count = 0;
  627. while (lnll) {
  628. /* set node uniq number starting at 1 */
  629. tree[i][count].id = lnll->node->nr;
  630. tree[i][count].level = lnll->node->rely;
  631. if (s3debug) {
  632. printf("%s(): node %d has %d parents, %d children\n", __func__, lnll->node->nr,
  633. lnll->node->indegree, lnll->node->outdegree);
  634. }
  635. /* set incoming edges if any */
  636. if (lnll->node->indegree) {
  637. tree[i][count].no_of_parent = lnll->node->indegree;
  638. tree[i][count].parent = dp_calloc(1, ((lnll->node->indegree + 0) * sizeof(int)));
  639. /* */
  640. k = 0;
  641. el = lnll->node->incoming_e;
  642. while (el) {
  643. /* skip hor. edges */
  644. if (el->edge->hedge == 0) {
  645. /* set number of to node */
  646. tree[i][count].parent[k] = el->edge->from_node->nr;
  647. if (el->edge->to_node->nr != lnll->node->nr) {
  648. printf("%s(): fixme(1)\n", __func__);
  649. }
  650. k++;
  651. }
  652. el = el->next;
  653. }
  654. tree[i][count].no_of_parent = k;
  655. } else {
  656. tree[i][count].no_of_parent = 0;
  657. tree[i][count].parent = NULL;
  658. }
  659. /* set outgoing edges if any */
  660. if (lnll->node->outdegree) {
  661. tree[i][count].no_of_child = lnll->node->outdegree;
  662. tree[i][count].child = dp_calloc(1, ((lnll->node->outdegree + 0) * sizeof(int)));
  663. /* */
  664. k = 0;
  665. el = lnll->node->outgoing_e;
  666. while (el) {
  667. /* skip hor. edges */
  668. if (el->edge->hedge == 0) {
  669. /* set number of from node */
  670. tree[i][count].child[k] = el->edge->to_node->nr;
  671. if (el->edge->from_node->nr != lnll->node->nr) {
  672. printf("%s(): fixme(2)\n", __func__);
  673. }
  674. k++;
  675. }
  676. el = el->next;
  677. }
  678. tree[i][count].no_of_child = k;
  679. } else {
  680. tree[i][count].no_of_child = 0;
  681. tree[i][count].child = NULL;
  682. }
  683. count++;
  684. lnll = lnll->next;
  685. }
  686. /* last entry has id 0 */
  687. tree[i][count].id = 0;
  688. } /* to next level */
  689. if (s3debug || 0) {
  690. printf("%s(): tree[i][0].level values are ", __func__);
  691. for (i = 0; i < (g->maxlevel + 1); i++) {
  692. printf("%d ", tree[i][0].level);
  693. if (tree[i][0].level == -1) {
  694. tree[i][0].level = i;
  695. }
  696. }
  697. printf("\n");
  698. }
  699. return;
  700. }
  701. /* clear data in tree data */
  702. static void clr_data(struct gml_graph *g)
  703. {
  704. int i = 0;
  705. int j = 0;
  706. if (tree == NULL) {
  707. return;
  708. }
  709. /* copy new node positions */
  710. for (i = 0; i <= g->maxlevel; i++) {
  711. if (tree[i]) {
  712. /* scan nodes at level [i] */
  713. j = 0;
  714. while (tree[i][j].id != 0) {
  715. if (tree[i][j].child) {
  716. tree[i][j].child = dp_free(tree[i][j].child);
  717. if (tree[i][j].child) {
  718. }
  719. }
  720. if (tree[i][j].parent) {
  721. tree[i][j].parent = dp_free(tree[i][j].parent);
  722. if (tree[i][j].parent) {
  723. }
  724. }
  725. /* to next x pos */
  726. j++;
  727. }
  728. tree[i] = dp_free(tree[i]);
  729. if (tree[i]) {
  730. }
  731. }
  732. }
  733. if (tree) {
  734. tree = dp_free(tree);
  735. if (tree) {
  736. }
  737. }
  738. /* clear nodes at level */
  739. clr_levelnodes(g);
  740. return;
  741. }
  742. /* start */
  743. static void barycenter_3(struct gml_graph *g, int it1v, int it2v)
  744. {
  745. int i = 0;
  746. int j = 0;
  747. int k = 0;
  748. struct gml_node *n = NULL;
  749. if (it1v) {
  750. }
  751. if (it2v) {
  752. }
  753. /* copy data */
  754. cp_data(g);
  755. /* higest level in use */
  756. i = g->maxlevel;
  757. gmaxlevel = g->maxlevel;
  758. nooflevels = g->maxlevel;
  759. /* print raw data */
  760. if (s3debug || 0) {
  761. for (i = 0; i <= g->maxlevel; i++) {
  762. /* scan nodes at level [i] */
  763. if (tree[i]) {
  764. j = 0;
  765. while (tree[i][j].id != 0) {
  766. printf("%s(): node %d has %d parents, %d children\n", __func__, tree[i][j].id,
  767. tree[i][j].no_of_parent, tree[i][j].no_of_child);
  768. /* to next x pos */
  769. j++;
  770. }
  771. }
  772. }
  773. }
  774. for (k = 0; k < 15; k++) {
  775. /* do some extra check bool */
  776. doublecheck = (k % 4) * ((k + 1) % 4);
  777. /* from top to bottom */
  778. for (j = 1; j < i; j++) {
  779. mediansort(g, tree[j], tree[j - 1]);
  780. }
  781. /* from bottom to top */
  782. for (j = i - 1; j > 0; j--) {
  783. mediansort(g, tree[j - 1], tree[j]);
  784. }
  785. if (check0(g) == 0) {
  786. /* no edge crossings */
  787. break;
  788. }
  789. /* from top to bottom */
  790. for (j = 1; j < i; j++) {
  791. mediansort(g, tree[j - 1], tree[j]);
  792. }
  793. /* from bottom to top */
  794. for (j = i - 1; j > 0; j--) {
  795. mediansort(g, tree[j], tree[j - 1]);
  796. }
  797. if (check0(g) == 0) {
  798. /* no edge crossings */
  799. break;
  800. }
  801. }
  802. /* copy new node positions */
  803. for (i = 0; i < (g->maxlevel + 1); i++) {
  804. /* scan nodes at level [i] */
  805. if (tree[i]) {
  806. j = 0;
  807. while (tree[i][j].id != 0) {
  808. tree[i][j].y = i; /* rel. y pos. */
  809. tree[i][j].x = j; /* rel. x pos. */
  810. /* find the node with this id */
  811. n = uniqnode2(g, tree[i][j].id);
  812. if (n) {
  813. if (tree[i][j].y == n->rely) {
  814. /* oke and set node rel. x pos */
  815. n->relx = tree[i][j].x;
  816. } else {
  817. /* shpuldnothappen */
  818. printf("%s(): node %d moved from level %d to level %d\n", __func__, n->nr, n->rely, tree[i][j].y);
  819. }
  820. } else {
  821. /* shpuldnothappen */
  822. printf("%s(): node id %d not found\n", __func__, tree[i][j].id);
  823. }
  824. /* to next x pos */
  825. j++;
  826. }
  827. }
  828. }
  829. /* clear data in tree */
  830. clr_data(g);
  831. return;
  832. }
  833. void reduce_crossings3(struct gml_graph *g, int it1v, int it2v)
  834. {
  835. int i = 0;
  836. int tsum = 0;
  837. /* number of crossing edges at level */
  838. if (g->numce) {
  839. g->numce = dp_free(g->numce);
  840. if (g->numce) {
  841. }
  842. }
  843. g->numce = dp_calloc(1, ((g->maxlevel + 1) * sizeof(int)));
  844. /* with too complex graph data at least this message is on console before cpu get roasted. */
  845. printf("%s(): starting barycenter algorithm for graph with %d nodes, %d edges in %d levels ... wait\n", __func__, g->nnodes,
  846. g->nedges, g->maxlevel);
  847. fflush(stdout);
  848. if (g->maxlevel == 0) {
  849. /* if graph has only 1 or more nodes */
  850. return;
  851. }
  852. if (g->nnodes < 2) {
  853. /* only 1 node, not much todo */
  854. return;
  855. }
  856. if (g->nedges < 2) {
  857. /* only 1 level, not much todo */
  858. return;
  859. }
  860. barycenter_3(g, it1v, it2v);
  861. /* (not determined) */
  862. g->sugi_icrossings = 0; /* sugiyama initial crossings */
  863. /* calc total number of crossings */
  864. for (i = 0; i < g->maxlevel; i++) {
  865. tsum += g->numce[i];
  866. }
  867. /* sugiyama final crossings */
  868. g->sugi_fcrossings = tsum;
  869. /* sugiyama changes made (not determined) */
  870. g->sugi_changes = 0;
  871. return;
  872. }
  873. /* end */