home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / basic / _tree_co.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  12.3 KB  |  578 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _tree_collection.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15.  
  16. // dyna_trees.c
  17.  
  18. #include <LEDA/tree_collection.h>
  19.  
  20. #define BIG MAXFLOAT
  21.  
  22.  
  23.  
  24. void dyna_trees::splay(d_vertex x) {
  25.      d_vertex y, z, zz, a, b, c, d;
  26.      double   mincost_a,
  27.           mincost_b,
  28.           mincost_c,
  29.           mincost_d,
  30.           mincost_x,
  31.           mincost_y,
  32.           mincost_z,
  33.           
  34.           cost_x,
  35.           cost_y,
  36.           cost_z;
  37.  
  38.      
  39.      while (x->parent) {
  40.       // splay-step : 
  41.  
  42.       y=x->parent; // Vater von x
  43.       z=y->parent; // Grossvater von x (oder 0)
  44.       zz = (z==0) ? 0 : z->parent; // Urgrossvater von z (oder 0)
  45.  
  46.       // 1.Fall: x hat Vater, aber keinen Grossvater
  47.  
  48.       if (z==0){ 
  49.         if (y->left==x) { 
  50.             // x wurzel des linken unterbaums  (1)
  51.             a=x->left;
  52.             b=x->right;
  53.             c=y->right;
  54.             x->parent=0;
  55.             x->right=y;
  56.             y->parent=x;
  57.             y->left=b;
  58.             if (b) b->parent=y;
  59.  
  60.             x->successor=y->successor;
  61.             y->successor=0;
  62.  
  63.             mincost_a = (a) ? a->dmin + x->dmin + y->dmin : BIG;
  64.             mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  65.             mincost_c = (c) ? c->dmin + y->dmin : BIG;
  66.             mincost_x = x->dmin + y->dmin;
  67.             mincost_y = y->dmin;
  68.             cost_x    = x->dcost + mincost_x;
  69.             cost_y    = y->dcost + mincost_y;
  70.             
  71.             mincost_x = mincost_y;
  72.             mincost_y = (mincost_b <= mincost_c) ? mincost_b : mincost_c;
  73.             if (cost_y <= mincost_y) mincost_y = cost_y;
  74.             x->dcost = cost_x - mincost_x;
  75.             y->dcost = cost_y - mincost_y;
  76.             x->dmin  = mincost_x;
  77.             y->dmin  = mincost_y - mincost_x;
  78.             if (a) a->dmin  = mincost_a - mincost_x;
  79.             if (b) b->dmin  = mincost_b - mincost_y;
  80.             if (c) c->dmin  = mincost_c - mincost_y;
  81.         }
  82.         else {
  83.             // x wurzel des rechten unterbaums (2)
  84.             a=y->left;
  85.             b=x->left;
  86.             c=x->right;
  87.             x->parent=0;
  88.             x->left=y;
  89.             y->parent=x;
  90.             y->right=b;
  91.             if (b) b->parent=y;
  92.             
  93.             x->successor=y->successor;
  94.             y->successor=0;
  95.             
  96.             mincost_a = (a) ? a->dmin + y->dmin : BIG;
  97.             mincost_b = (b) ? b->dmin + x->dmin + y->dmin : BIG;
  98.             mincost_c = (c) ? c->dmin + x->dmin + y->dmin : BIG;
  99.             mincost_x = x->dmin + y->dmin;
  100.             mincost_y = y->dmin;
  101.             cost_x    = x->dcost + mincost_x;
  102.             cost_y    = y->dcost + mincost_y;
  103.             
  104.             mincost_x = mincost_y;
  105.             mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  106.             if (cost_y <= mincost_y) mincost_y = cost_y;
  107.             x->dcost = cost_x - mincost_x;
  108.             y->dcost = cost_y - mincost_y;
  109.             x->dmin  = mincost_x;
  110.             y->dmin  = mincost_y - mincost_x;
  111.             if (a) a->dmin  = mincost_a - mincost_y;
  112.             if (b) b->dmin  = mincost_b - mincost_y;
  113.             if (c) c->dmin  = mincost_c - mincost_x;           
  114.         };
  115.         continue;
  116.       };
  117.       
  118.       // 2.Fall: x hat also Grossvater, x und parent(x) linke (rechte)
  119.       //           Soehne.
  120.       // Linke Soehne:
  121.  
  122.       if ((z->left==y)&&(y->left==x)){   //  (3)
  123.         a=x->left;
  124.         b=x->right;
  125.         c=y->right;
  126.         d=z->right;
  127.         y->left=b;
  128.         if (b) b->parent=y;
  129.         z->left=c;
  130.         if (c) c->parent=z;
  131.         x->right=y;
  132.         y->parent=x;
  133.         y->right=z;
  134.         z->parent=y;
  135.         if (zz) {
  136.             if (zz->left==z){
  137.              zz->left=x;
  138.             }
  139.             else{
  140.              zz->right=x;
  141.             };
  142.         }
  143.         else {     //  z is solid-tree-root
  144.             x->successor=z->successor;    
  145.             z->successor=0;
  146.         }; 
  147.         x->parent=zz;
  148.         
  149.         mincost_a = (a) ? a->dmin + x->dmin + y->dmin + z->dmin : BIG;
  150.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  151.         mincost_c = (c) ? c->dmin + y->dmin + z->dmin : BIG;
  152.         mincost_d = (d) ? d->dmin + z->dmin : BIG;
  153.         mincost_x =     x->dmin + y->dmin + z->dmin;
  154.         mincost_y =     y->dmin + z->dmin;
  155.         mincost_z =     z->dmin;
  156.         cost_x     = mincost_x + x->dcost;
  157.         cost_y     = mincost_y + y->dcost;
  158.         cost_z     = mincost_z + z->dcost;
  159.         
  160.         mincost_x = mincost_z;
  161.         mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  162.         if (cost_z <= mincost_z) mincost_z = cost_z;
  163.         mincost_y = (mincost_b <= mincost_z) ? mincost_b : mincost_z;
  164.         if (cost_y <= mincost_y) mincost_y = cost_y;
  165.         x->dcost = cost_x - mincost_x;
  166.         y->dcost = cost_y - mincost_y;
  167.         z->dcost = cost_z - mincost_z;
  168.         x->dmin = mincost_x;
  169.         y->dmin = mincost_y - mincost_x;
  170.         z->dmin = mincost_z - mincost_y;
  171.         if (a) a->dmin    = mincost_a - mincost_x;
  172.         if (b) b->dmin    = mincost_b - mincost_y;
  173.         if (c) c->dmin    = mincost_c - mincost_z;
  174.         if (d) d->dmin    = mincost_d - mincost_z;
  175.  
  176.         continue;
  177.       };
  178.       
  179.       // Rechte Soehne:   (4)
  180.       
  181.       if ((z->right==y)&&(y->right==x)){
  182.         a=z->left;
  183.         b=y->left;
  184.         c=x->left;
  185.         d=x->right;
  186.         z->right=b;
  187.         if (b) b->parent=z;
  188.         z->parent=y;
  189.         y->left=z;
  190.         y->right=c;
  191.         if (c) c->parent=y;
  192.         y->parent=x;
  193.         x->left=y;
  194.         if (zz) {
  195.             if (zz->left==z){
  196.              zz->left=x;
  197.             }
  198.             else{
  199.              zz->right=x;
  200.             };
  201.         }
  202.         else { 
  203.             x->successor=z->successor;
  204.             z->successor=0;
  205.         };
  206.         x->parent=zz;
  207.         
  208.         mincost_a = (a) ? a->dmin + z->dmin : BIG;
  209.         mincost_b = (b) ? b->dmin + y->dmin + z->dmin : BIG;
  210.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  211.         mincost_d = (d) ? d->dmin + x->dmin + y->dmin + z->dmin : BIG;
  212.         mincost_x =     x->dmin + y->dmin + z->dmin;
  213.         mincost_y =     y->dmin + z->dmin;
  214.         mincost_z =     z->dmin;
  215.         cost_x     = mincost_x + x->dcost;
  216.         cost_y     = mincost_y + y->dcost;
  217.         cost_z     = mincost_z + z->dcost;
  218.         
  219.         mincost_x = mincost_z;
  220.         mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  221.         if (cost_z <= mincost_z) mincost_z = cost_z;
  222.         mincost_y = (mincost_c <= mincost_z) ? mincost_c : mincost_z;
  223.         if (cost_y <= mincost_y) mincost_y = cost_y;
  224.         x->dcost = cost_x - mincost_x;
  225.         y->dcost = cost_y - mincost_y;
  226.         z->dcost = cost_z - mincost_z;
  227.         x->dmin = mincost_x;
  228.         y->dmin = mincost_y - mincost_x;
  229.         z->dmin = mincost_z - mincost_y;
  230.         if (a) a->dmin    = mincost_a - mincost_z;
  231.         if (b) b->dmin    = mincost_b - mincost_z;
  232.         if (c) c->dmin    = mincost_c - mincost_y;
  233.         if (d) d->dmin    = mincost_d - mincost_x;
  234.  
  235.         continue;
  236.       };
  237.       
  238.  
  239.       // 3.Fall: x linkes, p(x) rechtes Kind (oder umgekehrt)
  240.       // Zuerst x links, p(x) rechts:
  241.       
  242.       if ((z->right==y)&&(y->left==x)){   // (5)
  243.         a=z->left;
  244.         b=x->left;
  245.         c=x->right;
  246.         d=y->right;
  247.         z->right=b;
  248.         if (b) b->parent=z;
  249.         z->parent=x;
  250.         x->left=z;
  251.         y->left=c;
  252.         if (c) c->parent=y;
  253.         y->parent=x;
  254.         x->right=y;
  255.         if (zz) {
  256.             if (zz->left==z){
  257.              zz->left=x;
  258.             }
  259.             else{
  260.              zz->right=x;
  261.             };
  262.         } 
  263.         else {
  264.             x->successor=z->successor;
  265.             z->successor=0;
  266.         };
  267.         x->parent=zz;
  268.         
  269.         mincost_a = (a) ? a->dmin + z->dmin : BIG;
  270.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  271.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  272.         mincost_d = (d) ? d->dmin + y->dmin + z->dmin : BIG;
  273.         mincost_x =     x->dmin + y->dmin + z->dmin;
  274.         mincost_y =     y->dmin + z->dmin;
  275.         mincost_z =     z->dmin;
  276.         cost_x     = mincost_x + x->dcost;
  277.         cost_y     = mincost_y + y->dcost;
  278.         cost_z     = mincost_z + z->dcost;
  279.         
  280.         mincost_x = mincost_z;
  281.         mincost_z = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  282.         if (cost_z <= mincost_z) mincost_z = cost_z;
  283.         mincost_y = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  284.         if (cost_y <= mincost_y) mincost_y = cost_y;
  285.         x->dcost = cost_x - mincost_x;
  286.         y->dcost = cost_y - mincost_y;
  287.         z->dcost = cost_z - mincost_z;
  288.         x->dmin = mincost_x;
  289.         y->dmin = mincost_y - mincost_x;
  290.         z->dmin = mincost_z - mincost_x;
  291.         if (a) a->dmin    = mincost_a - mincost_z;
  292.         if (b) b->dmin    = mincost_b - mincost_z;
  293.         if (c) c->dmin    = mincost_c - mincost_y;
  294.         if (d) d->dmin    = mincost_d - mincost_y;
  295.  
  296.         continue;
  297.       };
  298.       
  299.       // Nun x rechts, p(x) links:
  300.       
  301.       if ((z->left==y)&&(y->right==x)){    // (6)
  302.         a=y->left;
  303.         b=x->left;
  304.         c=x->right;
  305.         d=z->right;
  306.         y->right=b;
  307.         if (b) b->parent=y;
  308.         y->parent=x;
  309.         x->left=y;
  310.         z->left=c;
  311.         if (c) c->parent=z;
  312.         z->parent=x;
  313.         x->right=z;
  314.         if (zz) {
  315.             if (zz->left==z){
  316.              zz->left=x;
  317.             }
  318.             else{
  319.              zz->right=x;
  320.             };
  321.         }
  322.         else {
  323.             x->successor=z->successor;
  324.             z->successor=0;
  325.         };
  326.         x->parent=zz;
  327.         
  328.         mincost_a = (a) ? a->dmin + y->dmin + z->dmin : BIG;
  329.         mincost_b = (b) ? b->dmin + x->dmin + y->dmin + z->dmin : BIG;
  330.         mincost_c = (c) ? c->dmin + x->dmin + y->dmin + z->dmin : BIG;
  331.         mincost_d = (d) ? d->dmin + z->dmin : BIG;
  332.         mincost_x =     x->dmin + y->dmin + z->dmin;
  333.         mincost_y =     y->dmin + z->dmin;
  334.         mincost_z =     z->dmin;
  335.         cost_x     = mincost_x + x->dcost;
  336.         cost_y     = mincost_y + y->dcost;
  337.         cost_z     = mincost_z + z->dcost;
  338.         
  339.         mincost_x = mincost_z;
  340.         mincost_z = (mincost_c <= mincost_d) ? mincost_c : mincost_d;
  341.         if (cost_z <= mincost_z) mincost_z = cost_z;
  342.         mincost_y = (mincost_a <= mincost_b) ? mincost_a : mincost_b;
  343.         if (cost_y <= mincost_y) mincost_y = cost_y;
  344.         x->dcost = cost_x - mincost_x;
  345.         y->dcost = cost_y - mincost_y;
  346.         z->dcost = cost_z - mincost_z;
  347.         x->dmin = mincost_x;
  348.         y->dmin = mincost_y - mincost_x;
  349.         z->dmin = mincost_z - mincost_x;
  350.         if (a) a->dmin    = mincost_a - mincost_y;
  351.         if (b) b->dmin    = mincost_b - mincost_y;
  352.         if (c) c->dmin    = mincost_c - mincost_z;
  353.         if (d) d->dmin    = mincost_d - mincost_z;
  354.  
  355.       };
  356.      };
  357. }
  358.  
  359.  
  360. d_vertex dyna_trees::assemble(d_vertex u, d_vertex v, d_vertex w)
  361. {
  362.      double mincost_u,
  363.         mincost_v,
  364.         mincost_w,
  365.         cost_v;
  366.  
  367.      v->left=u;
  368.      v->right=w;
  369.      if (u) u->parent=v;
  370.      if (w) w->parent=v;
  371.      
  372.      mincost_u = (u) ? u->dmin : BIG;
  373.      mincost_v =       v->dmin;
  374.      mincost_w = (w) ? w->dmin : BIG;
  375.      cost_v = mincost_v + v->dcost;
  376.      
  377.      mincost_v = (mincost_u <= mincost_w) ? mincost_u : mincost_w;
  378.      if (cost_v < mincost_v) mincost_v = cost_v;
  379.      v->dcost = cost_v - mincost_v;
  380.      v->dmin = mincost_v;
  381.      if (u) u->dmin = mincost_u - mincost_v;
  382.      if (w) w->dmin = mincost_w - mincost_v;
  383.  
  384.      return v;
  385. };
  386.  
  387.  
  388. void   dyna_trees::disassemble(d_vertex v, d_vertex& v1, d_vertex& v2) {
  389.      double mincost_v1,
  390.         mincost_v2;
  391.  
  392.  
  393.      v1=v->left;
  394.      v2=v->right;
  395.      if (v1) v1->parent=0;
  396.      if (v2) v2->parent=0;
  397.      v->left=0;
  398.      v->right=0;
  399.  
  400.      mincost_v1 = (v1) ? v1->dmin + v->dmin : BIG;
  401.      mincost_v2 = (v2) ? v2->dmin + v->dmin : BIG;
  402.  
  403.      if (v1) v1->dmin = mincost_v1;
  404.      if (v2) v2->dmin = mincost_v2;
  405.      
  406.      v->dmin += v->dcost;
  407.      v->dcost = 0;
  408. }
  409.  
  410.  
  411. d_vertex dyna_trees::makepath(void* i)
  412. {
  413.      if (first==0) {
  414.       first=last=new d_node(i);
  415.      }
  416.      else {
  417.       last->next=new d_node(i);
  418.       last=last->next;
  419.      };
  420.      return last;
  421. }
  422.  
  423.  
  424. d_vertex dyna_trees::findpath(d_vertex v)
  425. {
  426.      splay(v);
  427.      return v;
  428. }
  429.  
  430.  
  431.  
  432. d_vertex dyna_trees::findpathcost(d_path p, double& d)
  433. {
  434.      d_vertex w;
  435.      w=p;
  436.      
  437.      while( !( (w->dcost==0) && ( (w->right==0)||(w->right->dmin>0) ) ) ) {
  438.       if (w->right) {
  439.         if (w->right->dmin == 0) {
  440.              w=w->right;
  441.         } else {
  442.              if (w->dcost>0) w=w->left;
  443.         }  
  444.       }
  445.       else {
  446.         if (w->dcost>0) w=w->left;
  447.       };
  448.      };
  449.      splay(w);
  450.      d=w->dmin;
  451.      return w;
  452. }
  453.  
  454.  
  455.  
  456. d_vertex dyna_trees::findtail(d_path p)
  457. {
  458.      d_vertex w;
  459.      w=p;
  460.      
  461.      while(w->right) {
  462.       w=w->right;
  463.      };
  464.      splay(w);
  465.      return w;
  466. }
  467.  
  468.  
  469.  
  470. void dyna_trees::addpathcost(d_path p, double x)
  471. {
  472.      p->dmin += x;
  473. }
  474.  
  475.  
  476.  
  477. d_vertex dyna_trees::join(d_path p, d_path v, d_path q)
  478. {
  479.      return assemble(p, v, q);
  480. }
  481.  
  482.  
  483.  
  484. void dyna_trees::split(d_vertex v, d_vertex& v1, d_vertex& v2)
  485. {
  486.      splay(v);
  487.      disassemble(v, v1, v2);
  488. }
  489.  
  490.  
  491.  
  492. d_path dyna_trees::expose(d_vertex v)
  493. {
  494.      d_path   p,
  495.           q,
  496.           r;
  497.      d_vertex w;
  498.      
  499.      p=0;
  500.      while (v) {
  501.       w=findpath(v)->successor;
  502.       split(v,q,r);
  503.       if (q) q->successor=v;
  504.       p=join(p, v, r);
  505.       v=w;
  506.      };
  507.      p->successor=0;
  508.      return p;
  509. }
  510.  
  511.  
  512. d_vertex dyna_trees::maketree(void* i)
  513. {
  514.      copy_inf(i);
  515.  
  516.      d_vertex v;
  517.      v=makepath(i);
  518.      v->successor=0;
  519.      return v;
  520. }
  521.  
  522.  
  523. d_vertex dyna_trees::findroot(d_vertex v)
  524. {
  525.      return findtail(expose(v));
  526. }
  527.  
  528.  
  529.  
  530. d_vertex dyna_trees::findcost(d_vertex v, double& d)
  531. {
  532.      return findpathcost(expose(v),d);
  533. }
  534.  
  535.  
  536.  
  537. void dyna_trees::addcost(d_vertex v, double x)
  538. {
  539.      addpathcost(expose(v),x);
  540. }
  541.  
  542.  
  543.  
  544. void dyna_trees::link(d_vertex v, d_vertex w)
  545. {
  546.      join( (d_vertex) 0, expose(v), expose(w) )->successor=0;
  547. }
  548.  
  549.  
  550.  
  551. void dyna_trees::cut(d_vertex v) 
  552. {
  553.      d_path p,q;
  554.      
  555.      expose(v);
  556.      split(v,p,q);
  557.      v->successor=q->successor=0;
  558. }
  559.  
  560.  
  561.  
  562. dyna_trees::~dyna_trees()
  563. {
  564.      d_node *x, 
  565.         *y;
  566.       
  567.      x=first;
  568.      while(x) {
  569.       y=x->next;
  570.       delete x;
  571.       x=y;
  572.      };
  573. }
  574.  
  575.  
  576.  
  577.