home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ledar34.zip / leda-r-3_4_tar / LEDA-3.4 / src / graph / _g_random.c < prev    next >
C/C++ Source or Header  |  1996-09-03  |  13KB  |  561 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA 3.4
  4. +
  5. +  _g_random.c
  6. +
  7. +  This file is part of the LEDA research version (LEDA-R) that can be 
  8. +  used free of charge in academic research and teaching. Any commercial
  9. +  use of this software requires a license which is distributed by the
  10. +  LEDA Software GmbH, Postfach 151101, 66041 Saarbruecken, FRG
  11. +  (fax +49 681 31104).
  12. +
  13. +  Copyright (c) 1991-1996  by  Max-Planck-Institut fuer Informatik
  14. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  15. +  All rights reserved.
  16. *******************************************************************************/
  17. #include <LEDA/graph.h>
  18. #include <LEDA/ugraph.h>
  19.  
  20. //------------------------------------------------------------------------------
  21. // generators for random graphs
  22. //
  23. // by S. Naeher  (1995)
  24. //------------------------------------------------------------------------------
  25.  
  26.  
  27. // we use the global random integer source "rand_int"
  28.  
  29. void random_graph(graph& G, int n, int m)
  30. { /* random graph with n nodes and m edges */ 
  31.  
  32.   node* V = new node[n];
  33.  
  34.   G.clear();
  35.  
  36.   for(int i=0;i<n;i++) V[i] = G.new_node();
  37.  
  38.   while (m--) G.new_edge(V[rand_int(0,n-1)],V[rand_int(0,n-1)]);
  39.  
  40.   delete[] V;
  41. }
  42.  
  43.  
  44. void random_ugraph(ugraph& G, int n, int m)
  45. { int i;
  46.   node* V = new node[n];
  47.  
  48.   G.clear();
  49.  
  50.   for(i=0;i<n;i++) V[i] = G.new_node();
  51.  
  52.   while (m--) G.new_edge(V[rand_int(0,n-1)],V[rand_int(0,n-1)]);
  53. }
  54.  
  55.  
  56. void random_bigraph(graph& G,int n1,int n2,int m,list<node>& A,list<node>& B)
  57. {
  58.    int  d = m/n1; 
  59.    int  r = m%n1; 
  60.  
  61.    node* AV = new node[n1];
  62.    node* BV = new node[n2];
  63.  
  64.    A.clear();
  65.    B.clear();
  66.    G.clear();
  67.  
  68.    for(int a = 0; a < n1; a++)  A.append(AV[a] = G.new_node());
  69.    for(int b = 0; b < n2; b++)  B.append(BV[b] = G.new_node());
  70.  
  71.    node v;
  72.    int i;
  73.  
  74.    forall(v,A)
  75.      for(i=0;i<d;i++)
  76.        G.new_edge(v,BV[rand_int(0,n2-1)]);
  77.  
  78.    while (r--) G.new_edge(AV[rand_int(0,n1-1)], BV[rand_int(0,n2-1)]);
  79.  
  80.    delete[] AV;
  81.    delete[] BV;
  82. }
  83.  
  84.  
  85.  
  86.  
  87. //------------------------------------------------------------------------------
  88. // random planar graph
  89. //------------------------------------------------------------------------------
  90.  
  91. #include <LEDA/sortseq.h>
  92. #include <LEDA/prio.h>
  93. #include <math.h>
  94.  
  95. #define YNIL seq_item(nil)
  96. #define XNIL pq_item(nil)
  97.  
  98.  
  99. #define EPS  0.00001
  100. #define EPS2 0.0000000001
  101.  
  102. class POINT;
  103. class SEGMENT;
  104. typedef POINT* point;
  105. typedef SEGMENT* segment;
  106.  
  107. enum point_type {Intersection=0,Rightend=1,Leftend=2}; 
  108.  
  109. class POINT
  110. {
  111.   friend class SEGMENT;
  112.  
  113.   segment seg;
  114.   int     kind;
  115.   double  x;
  116.   double  y;
  117.  
  118.   public:
  119.  
  120.   POINT(double a,double b)  
  121.   { 
  122.     x=a; y=b; seg=0; kind=Intersection;
  123.    }
  124.  
  125.  
  126.   LEDA_MEMORY(POINT);
  127.  
  128.   friend double    get_x(point p)    { return p->x; }
  129.   friend double    get_y(point p)    { return p->y; }
  130.   friend int       get_kind(point p) { return p->kind; }
  131.   friend segment get_seg(point p)  { return p->seg; }   
  132.  
  133.   friend bool intersection(segment, segment, point&);
  134. };
  135.  
  136.  
  137.  
  138. #if defined(__GNUC__)
  139. // if I declare compare static g++ does not use it
  140. // but instantiates the default error compare template
  141. inline
  142. #else
  143. static
  144. #endif
  145. int compare(const point& p1, const point& p2)
  146. { if (p1==p2) return 0;
  147.  
  148.   double diffx = get_x(p1) - get_x(p2);
  149.   if (diffx >  EPS2 ) return  1;
  150.   if (diffx < -EPS2 ) return -1;
  151.  
  152.   int    diffk = get_kind(p1)-get_kind(p2);
  153.   if (diffk != 0) return diffk;
  154.  
  155.   double diffy = get_y(p1) - get_y(p2);
  156.   if (diffy >  EPS2 ) return  1;
  157.   if (diffy < -EPS2 ) return -1;
  158.  
  159.   return 0;
  160.  
  161. }
  162.  
  163.  
  164. class SEGMENT
  165. {
  166.   point startpoint;
  167.   point endpoint;
  168.   double  slope;
  169.   double  yshift;
  170.   node  left_node;
  171.   int   orient;
  172.   int   color;
  173.   int   name;
  174.  
  175.  
  176.   public:
  177.  
  178.   SEGMENT(point, point,int,int);     
  179.  
  180.  ~SEGMENT() { delete startpoint; delete endpoint; }     
  181.  
  182.   LEDA_MEMORY(SEGMENT);
  183.  
  184.  
  185.   friend point get_startpoint(segment seg)     { return seg->startpoint; }
  186.   friend point get_endpoint(segment seg)       { return seg->endpoint; }
  187.   friend double get_slope(segment seg)           { return seg->slope; }
  188.   friend double get_yshift(segment seg)          { return seg->yshift; }
  189.   friend node get_left_node(segment seg)         { return seg->left_node; }
  190.   friend void set_left_node(segment seg, node v) { seg->left_node = v; }
  191.  
  192.   friend bool intersection(segment, segment, point&);
  193. };
  194.  
  195.  
  196.  
  197.  
  198. SEGMENT::SEGMENT(point p1,point p2,int c, int n)    
  199.   {
  200.     left_node  = nil;
  201.     color      = c;
  202.     name       = n;
  203.  
  204.     if (compare(p1,p2) < 0)
  205.      { startpoint = p1; 
  206.        endpoint = p2; 
  207.        orient = 0;
  208.       }
  209.     else
  210.      { startpoint = p2; 
  211.        endpoint = p1; 
  212.        orient = 1;
  213.       }
  214.  
  215.     startpoint->kind = Leftend; 
  216.     endpoint->kind = Rightend; 
  217.     startpoint->seg = this; 
  218.     endpoint->seg = this;
  219.  
  220.     if (endpoint->x != startpoint->x)
  221.     {
  222.       slope = (endpoint->y - startpoint->y)/(endpoint->x - startpoint->x);
  223.       yshift = startpoint->y - slope * startpoint->x;
  224.  
  225.       startpoint->x -= EPS;
  226.       startpoint->y -= EPS * slope;
  227.       endpoint->x += EPS;
  228.       endpoint->y += EPS * slope;
  229.     }
  230.     else //vertical segment
  231.     { startpoint->y -= EPS;
  232.       endpoint->y   += EPS;
  233.      }
  234.   }
  235.  
  236.  
  237. static double x_sweep;
  238. static double y_sweep;
  239.  
  240.  
  241. static int compare(const segment& s1, const segment& s2)
  242. {
  243.   double y1 = get_slope(s1)*x_sweep+get_yshift(s1);
  244.   double y2 = get_slope(s2)*x_sweep+get_yshift(s2);
  245.  
  246.   double diff = y1-y2;
  247.   if (diff >  EPS2 ) return  1;
  248.   if (diff < -EPS2 ) return -1;
  249.  
  250.   if (get_slope(s1) == get_slope(s2)) 
  251.         return compare(get_x(get_startpoint(s1)), get_x(get_startpoint(s2)));
  252.  
  253.   if (y1 <= y_sweep+EPS2)
  254.         return compare(get_slope(s1),get_slope(s2));
  255.   else
  256.         return compare(get_slope(s2),get_slope(s1));
  257.  
  258. }
  259.  
  260.  
  261.  
  262. static priority_queue<seq_item,point> X_structure;
  263.  
  264. static sortseq<segment,pq_item> Y_structure;
  265.  
  266.  
  267. bool intersection(segment seg1,segment seg2, point& inter)
  268. {
  269.   if (seg1->slope == seg2->slope)
  270.     return false;
  271.   else
  272.   { 
  273.     double cx = (seg2->yshift - seg1->yshift) / (seg1->slope - seg2->slope);
  274.  
  275.     if (cx <= x_sweep) return false;
  276.  
  277.     if (seg1->startpoint->x > cx || seg2->startpoint->x > cx ||
  278.         seg1->endpoint->x < cx || seg2->endpoint->x < cx ) return false;
  279.  
  280.     inter = new POINT(cx,seg1->slope * cx + seg1->yshift);
  281.  
  282.     return true;
  283.   }
  284. }
  285.  
  286.  
  287.  
  288. inline pq_item Xinsert(seq_item i, point p) 
  289. { return X_structure.insert(i,p); }
  290.  
  291.  
  292. inline point Xdelete(pq_item i) 
  293. { point p = X_structure.inf(i);
  294.   X_structure.del_item(i);
  295.   return p;
  296.  }
  297.  
  298.  
  299. void random_planar_graph(graph& G, int m)
  300. { node_array<double> xcoord;
  301.   node_array<double> ycoord;
  302.   random_planar_graph(G,xcoord,ycoord,m);
  303.  }
  304.  
  305. void random_planar_graph(graph& G, node_array<double>& xcoord,
  306.                                    node_array<double>& ycoord, int n)
  307. {
  308.   point    p,inter;
  309.   segment  seg, l,lsit,lpred,lsucc,lpredpred;
  310.   pq_item  pqit,pxmin;
  311.   seq_item sitmin,sit,sitpred,sitsucc,sitpredpred;
  312.  
  313.   int MAX_X = n;
  314.   int MAX_Y = n;
  315.  
  316.  
  317.   int N = n;  // number of random segments
  318.  
  319.   xcoord.init(G,n,0);
  320.   ycoord.init(G,n,0);
  321.  
  322.  
  323.   int count=1;
  324.  
  325.   //initialization of the X-structure
  326.  
  327.   for (int i = 0; i < N; i++)
  328.    { //point p = new POINT(rand_int(0,MAX_X/3), rand_int(0,MAX_Y));
  329.      //point q = new POINT(rand_int(2*MAX_X/3,MAX_X), rand_int(0,MAX_Y));
  330.      point p = new POINT(rand_int(0,MAX_X), rand_int(0,MAX_Y));
  331.      point q = new POINT(rand_int(0,MAX_X), rand_int(0,MAX_Y));
  332.      seg = new SEGMENT(p,q,0,count++);
  333.      Xinsert(YNIL,get_startpoint(seg));
  334.    }
  335.  
  336.   // we insert a long vertical segment to make the graph connected
  337.  
  338. /*
  339.  { point p = new POINT(MAX_X/2 - 1,0);
  340.    point q = new POINT(MAX_X/2 + 1,MAX_Y);
  341.    seg = new SEGMENT(p,q,0,count++);
  342.    Xinsert(YNIL,get_startpoint(seg));
  343.   }
  344. */
  345.  
  346.  
  347.   count = 0;
  348.  
  349.   x_sweep = -MAXINT;
  350.   y_sweep = -MAXINT;
  351.  
  352.  
  353.   while( !X_structure.empty()  && G.number_of_nodes() < n)
  354.   {
  355.     pxmin = X_structure.find_min();
  356.     p = X_structure.inf(pxmin);
  357.  
  358.     sitmin = X_structure.key(pxmin);
  359.  
  360.     Xdelete(pxmin);
  361.  
  362.  
  363.  
  364.     if (sitmin == YNIL) //left endpoint
  365.     { 
  366.       l = get_seg(p); 
  367.  
  368.       x_sweep = get_x(p);
  369.       y_sweep = get_y(p);
  370.  
  371.  
  372.       sit = Y_structure.insert(l,XNIL);
  373.  
  374.       Xinsert(sit,get_endpoint(l));
  375.  
  376.       sitpred = Y_structure.pred(sit);
  377.       sitsucc = Y_structure.succ(sit);
  378.  
  379.       if (sitpred != YNIL) 
  380.       { if ((pqit = Y_structure.inf(sitpred)) != XNIL)
  381.           delete Xdelete(pqit);
  382.  
  383.         lpred = Y_structure.key(sitpred);
  384.  
  385.         Y_structure.change_inf(sitpred,XNIL);
  386.  
  387.         if (intersection(lpred,l,inter))
  388.             Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  389.       }
  390.  
  391.  
  392.       if (sitsucc != YNIL)
  393.       { lsucc = Y_structure.key(sitsucc);
  394.         if (intersection(lsucc,l,inter))
  395.            Y_structure.change_inf(sit,Xinsert(sit,inter));
  396.       }
  397.  
  398.     }
  399.     else if (get_kind(p) == Rightend)
  400.          //right endpoint
  401.          { 
  402.            x_sweep = get_x(p);
  403.            y_sweep = get_y(p);
  404.  
  405.            sit = sitmin;
  406.  
  407.            sitpred = Y_structure.pred(sit);
  408.            sitsucc = Y_structure.succ(sit);
  409.  
  410.            segment seg = Y_structure.key(sit);
  411.  
  412.            Y_structure.del_item(sit);
  413.  
  414.            delete seg;
  415.  
  416.            if((sitpred != YNIL)&&(sitsucc != YNIL))
  417.            {
  418.              lpred = Y_structure.key(sitpred);
  419.              lsucc = Y_structure.key(sitsucc);
  420.              if (intersection(lsucc,lpred,inter))
  421.                 Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  422.            }
  423.          }
  424.          else // intersection point p
  425.          { 
  426.            node w = G.new_node();
  427.            xcoord[w] = get_x(p);
  428.            ycoord[w] = get_y(p);
  429.  
  430.            count++;
  431.  
  432.            /* Let L = list of all lines intersecting in p 
  433.  
  434.               we compute sit     = L.head();
  435.               and        sitpred = L.tail();
  436.  
  437.               by scanning the Y_structure in both directions 
  438.               starting at sitmin;
  439.  
  440.            */
  441.  
  442.            /* search for sitpred upwards from sitmin: */
  443.  
  444.            Y_structure.change_inf(sitmin,XNIL);
  445.  
  446.            sitpred = Y_structure.succ(sitmin);
  447.  
  448.  
  449.            while ((pqit=Y_structure.inf(sitpred)) != XNIL)
  450.            { point q = X_structure.inf(pqit);
  451.              if (compare(p,q) != 0) break; 
  452.              X_structure.del_item(pqit);
  453.              Y_structure.change_inf(sitpred,XNIL);
  454.              sitpred = Y_structure.succ(sitpred);
  455.             }
  456.  
  457.  
  458.            /* search for sit downwards from sitmin: */
  459.  
  460.            sit = sitmin;
  461.  
  462.            seq_item sit1;
  463.            
  464.            while ((sit1=Y_structure.pred(sit)) != YNIL)
  465.            { pqit = Y_structure.inf(sit1);
  466.              if (pqit == XNIL) break;
  467.              point q = X_structure.inf(pqit);
  468.              if (compare(p,q) != 0) break; 
  469.              X_structure.del_item(pqit);
  470.              Y_structure.change_inf(sit1,XNIL);
  471.              sit = sit1;
  472.             }
  473.  
  474.  
  475.  
  476.            // insert edges to p for all segments in sit, ..., sitpred into G
  477.            // and set left node to w 
  478.  
  479.            lsit = Y_structure.key(sitpred);
  480.  
  481.            node v = get_left_node(lsit);
  482.            if (v!=nil && w!=nil) G.new_edge(v,w);
  483.            set_left_node(lsit,w);
  484.  
  485.            for(sit1=sit; sit1!=sitpred; sit1 = Y_structure.succ(sit1))
  486.            { lsit = Y_structure.key(sit1);
  487.  
  488.              v = get_left_node(lsit);
  489.              if (v!=nil && w!=nil) G.new_edge(v,w);
  490.              set_left_node(lsit,w);
  491.             }
  492.  
  493.            lsit = Y_structure.key(sit);
  494.            lpred=Y_structure.key(sitpred);
  495.            sitpredpred = Y_structure.pred(sit);
  496.            sitsucc=Y_structure.succ(sitpred);
  497.  
  498.  
  499.            if (sitpredpred != YNIL)
  500.             { 
  501.               lpredpred=Y_structure.key(sitpredpred);
  502.  
  503.               if ((pqit = Y_structure.inf(sitpredpred)) != XNIL)
  504.                 delete Xdelete(pqit);
  505.  
  506.               Y_structure.change_inf(sitpredpred,XNIL);
  507.  
  508.  
  509.               if (intersection(lpred,lpredpred,inter))
  510.                 Y_structure.change_inf(sitpredpred,
  511.                                        Xinsert(sitpredpred,inter));
  512.              }
  513.  
  514.  
  515.            if (sitsucc != YNIL)
  516.             {
  517.               lsucc=Y_structure.key(sitsucc);
  518.  
  519.               if ((pqit = Y_structure.inf(sitpred)) != XNIL)
  520.                 delete Xdelete(pqit);
  521.                  
  522.               Y_structure.change_inf(sitpred,XNIL);
  523.  
  524.               if (intersection(lsucc,lsit,inter))
  525.                   Y_structure.change_inf(sit,Xinsert(sit,inter));
  526.              }
  527.  
  528.  
  529. // reverse the subsequence sit, ... ,sitpred  in the Y_structure
  530.  
  531.            x_sweep = get_x(p);
  532.            y_sweep = get_y(p);
  533.  
  534.            Y_structure.reverse_items(sit,sitpred);
  535.  
  536.           delete p;
  537.  
  538.          } // intersection
  539.  
  540.   }
  541.  
  542.   X_structure.clear();
  543.   Y_structure.clear();
  544.  
  545.  
  546.  
  547.   // normalize x and y coordinates 
  548.  
  549.   node v;
  550.   forall_nodes(v,G) 
  551.   { xcoord[v] /= x_sweep;
  552.     ycoord[v] /= MAX_Y;
  553.    }
  554.  
  555.   Make_Connected(G);
  556.  
  557. }
  558.  
  559.  
  560.