_g_random.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:12k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _g_random.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/graph.h>
  12. #include <LEDA/ugraph.h>
  13. // we use the global random integer source "rand_int"
  14. void random_graph(graph& G, int n, int m)
  15. { /* random graph with n nodes and m edges */ 
  16.   int i;
  17.   node* V = new node[n];
  18.   G.clear();
  19.   for(i=0;i<n;i++) V[i] = G.new_node();
  20.  
  21.   while (m--) G.new_edge(V[rand_int(0,n-1)],V[rand_int(0,n-1)]);
  22. }
  23. void random_ugraph(ugraph& G, int n, int m)
  24. { int i;
  25.   node* V = new node[n];
  26.   G.clear();
  27.   for(i=0;i<n;i++) V[i] = G.new_node();
  28.   while (m--) G.new_edge(V[rand_int(0,n-1)],V[rand_int(0,n-1)]);
  29. }
  30. void random_bigraph(graph& G,int n1,int n2,int m,list<node>& A,list<node>& B)
  31. {
  32.    int  d = m/n1; 
  33.    int  r = m%n1; 
  34.    node* AV = new node[n1];
  35.    node* BV = new node[n2];
  36.    A.clear();
  37.    B.clear();
  38.    G.clear();
  39.    for(int a = 0; a < n1; a++)  A.append(AV[a] = G.new_node());
  40.    for(int b = 0; b < n2; b++)  B.append(BV[b] = G.new_node());
  41.    node v;
  42.    int i;
  43.    forall(v,A)
  44.      for(i=0;i<d;i++)
  45.        G.new_edge(v,BV[rand_int(0,n2-1)]);
  46.    while (r--) G.new_edge(AV[rand_int(0,n1-1)], BV[rand_int(0,n2-1)]);
  47. }
  48. //------------------------------------------------------------------------------
  49. // random planar graph
  50. //------------------------------------------------------------------------------
  51. #include <LEDA/sortseq.h>
  52. #include <LEDA/prio.h>
  53. #include <math.h>
  54. #define EPS  0.00001
  55. #define EPS2 0.0000000001
  56. class POINT;
  57. class SEGMENT;
  58. typedef POINT* point;
  59. typedef SEGMENT* segment;
  60. enum point_type {Intersection=0,Rightend=1,Leftend=2}; 
  61. class POINT
  62. {
  63.   friend class SEGMENT;
  64.   segment seg;
  65.   int     kind;
  66.   double  x;
  67.   double  y;
  68.   public:
  69.   POINT(double a,double b)  
  70.   { 
  71.     x=a; y=b; seg=0; kind=Intersection;
  72.    }
  73.   LEDA_MEMORY(POINT);
  74.   friend double    get_x(point p)    { return p->x; }
  75.   friend double    get_y(point p)    { return p->y; }
  76.   friend int       get_kind(point p) { return p->kind; }
  77.   friend segment get_seg(point p)  { return p->seg; }   
  78.   friend bool intersection(segment, segment, point&);
  79. };
  80. #if defined(__GNUC__)
  81. // if I declare compare static g++ does not use it
  82. // but instantiates the default error compare template
  83. inline
  84. #else
  85. static
  86. #endif
  87. int compare(const point& p1, const point& p2)
  88. { if (p1==p2) return 0;
  89.   double diffx = get_x(p1) - get_x(p2);
  90.   if (diffx >  EPS2 ) return  1;
  91.   if (diffx < -EPS2 ) return -1;
  92.   int    diffk = get_kind(p1)-get_kind(p2);
  93.   if (diffk != 0) return diffk;
  94.   double diffy = get_y(p1) - get_y(p2);
  95.   if (diffy >  EPS2 ) return  1;
  96.   if (diffy < -EPS2 ) return -1;
  97.   return 0;
  98. }
  99. class SEGMENT
  100. {
  101.   point startpoint;
  102.   point endpoint;
  103.   double  slope;
  104.   double  yshift;
  105.   node  left_node;
  106.   int   orient;
  107.   int   color;
  108.   int   name;
  109.   public:
  110.   SEGMENT(point, point,int,int);     
  111.  ~SEGMENT() { delete startpoint; delete endpoint; }     
  112.   LEDA_MEMORY(SEGMENT);
  113.   friend point get_startpoint(segment seg)     { return seg->startpoint; }
  114.   friend point get_endpoint(segment seg)       { return seg->endpoint; }
  115.   friend double get_slope(segment seg)           { return seg->slope; }
  116.   friend double get_yshift(segment seg)          { return seg->yshift; }
  117.   friend node get_left_node(segment seg)         { return seg->left_node; }
  118.   friend void set_left_node(segment seg, node v) { seg->left_node = v; }
  119.   friend bool intersection(segment, segment, point&);
  120. };
  121. SEGMENT::SEGMENT(point p1,point p2,int c, int n)    
  122.   {
  123.     left_node  = nil;
  124.     color      = c;
  125.     name       = n;
  126.     if (compare(p1,p2) < 0)
  127.      { startpoint = p1; 
  128.        endpoint = p2; 
  129.        orient = 0;
  130.       }
  131.     else
  132.      { startpoint = p2; 
  133.        endpoint = p1; 
  134.        orient = 1;
  135.       }
  136.     startpoint->kind = Leftend; 
  137.     endpoint->kind = Rightend; 
  138.     startpoint->seg = this; 
  139.     endpoint->seg = this;
  140.     if (endpoint->x != startpoint->x)
  141.     {
  142.       slope = (endpoint->y - startpoint->y)/(endpoint->x - startpoint->x);
  143.       yshift = startpoint->y - slope * startpoint->x;
  144.       startpoint->x -= EPS;
  145.       startpoint->y -= EPS * slope;
  146.       endpoint->x += EPS;
  147.       endpoint->y += EPS * slope;
  148.     }
  149.     else //vertical segment
  150.     { startpoint->y -= EPS;
  151.       endpoint->y   += EPS;
  152.      }
  153.   }
  154. static double x_sweep;
  155. static double y_sweep;
  156. static int compare(const segment& s1, const segment& s2)
  157. {
  158.   double y1 = get_slope(s1)*x_sweep+get_yshift(s1);
  159.   double y2 = get_slope(s2)*x_sweep+get_yshift(s2);
  160.   double diff = y1-y2;
  161.   if (diff >  EPS2 ) return  1;
  162.   if (diff < -EPS2 ) return -1;
  163.   if (get_slope(s1) == get_slope(s2)) 
  164.         return compare(get_x(get_startpoint(s1)), get_x(get_startpoint(s2)));
  165.   if (y1 <= y_sweep+EPS2)
  166.         return compare(get_slope(s1),get_slope(s2));
  167.   else
  168.         return compare(get_slope(s2),get_slope(s1));
  169. }
  170. static priority_queue<seq_item,point> X_structure;
  171. static sortseq<segment,pq_item> Y_structure;
  172. bool intersection(segment seg1,segment seg2, point& inter)
  173. {
  174.   if (seg1->slope == seg2->slope)
  175.     return false;
  176.   else
  177.   { 
  178.     double cx = (seg2->yshift - seg1->yshift) / (seg1->slope - seg2->slope);
  179.  
  180.     if (cx <= x_sweep) return false;
  181.     if (seg1->startpoint->x > cx || seg2->startpoint->x > cx ||
  182.         seg1->endpoint->x < cx || seg2->endpoint->x < cx ) return false;
  183.     inter = new POINT(cx,seg1->slope * cx + seg1->yshift);
  184.     return true;
  185.   }
  186. }
  187. inline pq_item Xinsert(seq_item i, point p) 
  188. { return X_structure.insert(i,p); }
  189. inline point Xdelete(pq_item i) 
  190. { point p = X_structure.inf(i);
  191.   X_structure.del_item(i);
  192.   return p;
  193.  }
  194. void random_planar_graph(graph& G, int m)
  195. { node_array<double> xcoord;
  196.   node_array<double> ycoord;
  197.   random_planar_graph(G,xcoord,ycoord,m);
  198.  }
  199. void random_planar_graph(graph& G, node_array<double>& xcoord,
  200.                                    node_array<double>& ycoord, int n)
  201. {
  202.   point    p,inter;
  203.   segment  seg, l,lsit,lpred,lsucc,lpredpred;
  204.   pq_item  pqit,pxmin;
  205.   seq_item sitmin,sit,sitpred,sitsucc,sitpredpred;
  206.   int MAX_X = 1000;
  207.   int MAX_Y = 1000;
  208.   int N = int(2.5*sqrt(n)); // number of random segments
  209.   xcoord.init(G,n,0);
  210.   ycoord.init(G,n,0);
  211.   int count=1;
  212.  
  213.   //initialization of the X-structure
  214.   for (int i = 0; i < N; i++)
  215.    { point p = new POINT(rand_int(0,MAX_X/3), rand_int(0,MAX_Y));
  216.      point q = new POINT(rand_int(2*MAX_X/3,MAX_X), rand_int(0,MAX_Y));
  217.      seg = new SEGMENT(p,q,0,count++);
  218.      Xinsert(nil,get_startpoint(seg));
  219.    }
  220.   // we insert a long vertical segment to make the graph connecte
  221.  { point p = new POINT(MAX_X/2 - 1,0);
  222.    point q = new POINT(MAX_X/2 + 1,MAX_Y);
  223.    seg = new SEGMENT(p,q,0,count++);
  224.    Xinsert(nil,get_startpoint(seg));
  225.   }
  226.   count = 0;
  227.   x_sweep = -MAXINT;
  228.   y_sweep = -MAXINT;
  229.   while( !X_structure.empty() && G.number_of_nodes() < n)
  230.   {
  231.     pxmin = X_structure.find_min();
  232.     p = X_structure.inf(pxmin);
  233.     sitmin = X_structure.key(pxmin);
  234.     Xdelete(pxmin);
  235.     if (sitmin == nil) //left endpoint
  236.     { 
  237.       l = get_seg(p); 
  238.       x_sweep = get_x(p);
  239.       y_sweep = get_y(p);
  240.       sit = Y_structure.insert(l,nil);
  241.       Xinsert(sit,get_endpoint(l));
  242.       sitpred = Y_structure.pred(sit);
  243.       sitsucc = Y_structure.succ(sit);
  244.       if (sitpred != nil) 
  245.       { if ((pqit = Y_structure.inf(sitpred)) != nil)
  246.           delete Xdelete(pqit);
  247.         lpred = Y_structure.key(sitpred);
  248.         Y_structure.change_inf(sitpred,nil);
  249.         if (intersection(lpred,l,inter))
  250.             Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  251.       }
  252.       if (sitsucc != nil)
  253.       { lsucc = Y_structure.key(sitsucc);
  254.         if (intersection(lsucc,l,inter))
  255.            Y_structure.change_inf(sit,Xinsert(sit,inter));
  256.       }
  257.     }
  258.     else if (get_kind(p) == Rightend)
  259.          //right endpoint
  260.          { 
  261.            x_sweep = get_x(p);
  262.            y_sweep = get_y(p);
  263.            sit = sitmin;
  264.            sitpred = Y_structure.pred(sit);
  265.            sitsucc = Y_structure.succ(sit);
  266.            segment seg = Y_structure.key(sit);
  267.            Y_structure.del_item(sit);
  268.            delete seg;
  269.            if((sitpred != nil)&&(sitsucc != nil))
  270.            {
  271.              lpred = Y_structure.key(sitpred);
  272.              lsucc = Y_structure.key(sitsucc);
  273.              if (intersection(lsucc,lpred,inter))
  274.                 Y_structure.change_inf(sitpred,Xinsert(sitpred,inter));
  275.            }
  276.          }
  277.          else // intersection point p
  278.          { 
  279.            node w = G.new_node();
  280.            xcoord[w] = get_x(p);
  281.            ycoord[w] = get_y(p);
  282.            count++;
  283.            /* Let L = list of all lines intersecting in p 
  284.  
  285.               we compute sit     = L.head();
  286.               and        sitpred = L.tail();
  287.               by scanning the Y_structure in both directions 
  288.               starting at sitmin;
  289.            */
  290.            /* search for sitpred upwards from sitmin: */
  291.            Y_structure.change_inf(sitmin,nil);
  292.            sitpred = Y_structure.succ(sitmin);
  293.            while ((pqit=Y_structure.inf(sitpred)) != nil)
  294.            { point q = X_structure.inf(pqit);
  295.              if (compare(p,q) != 0) break; 
  296.              X_structure.del_item(pqit);
  297.              Y_structure.change_inf(sitpred,nil);
  298.              sitpred = Y_structure.succ(sitpred);
  299.             }
  300.            /* search for sit downwards from sitmin: */
  301.            sit = sitmin;
  302.            seq_item sit1;
  303.            
  304.            while ((sit1=Y_structure.pred(sit)) != nil)
  305.            { pqit = Y_structure.inf(sit1);
  306.              if (pqit == nil) break;
  307.              point q = X_structure.inf(pqit);
  308.              if (compare(p,q) != 0) break; 
  309.              X_structure.del_item(pqit);
  310.              Y_structure.change_inf(sit1,nil);
  311.              sit = sit1;
  312.             }
  313.            // insert edges to p for all segments in sit, ..., sitpred into G
  314.            // and set left node to w 
  315.            lsit = Y_structure.key(sitpred);
  316.            node v = get_left_node(lsit);
  317.            if (v!=nil) G.new_edge(v,w);
  318.            set_left_node(lsit,w);
  319.            for(sit1=sit; sit1!=sitpred; sit1 = Y_structure.succ(sit1))
  320.            { lsit = Y_structure.key(sit1);
  321.              v = get_left_node(lsit);
  322.              if (v!=nil) G.new_edge(v,w);
  323.              set_left_node(lsit,w);
  324.             }
  325.            lsit = Y_structure.key(sit);
  326.            lpred=Y_structure.key(sitpred);
  327.            sitpredpred = Y_structure.pred(sit);
  328.            sitsucc=Y_structure.succ(sitpred);
  329.            if (sitpredpred != nil)
  330.             { 
  331.               lpredpred=Y_structure.key(sitpredpred);
  332.               if ((pqit = Y_structure.inf(sitpredpred)) != nil)
  333.                 delete Xdelete(pqit);
  334.               Y_structure.change_inf(sitpredpred,nil);
  335.               if (intersection(lpred,lpredpred,inter))
  336.                 Y_structure.change_inf(sitpredpred,
  337.                                        Xinsert(sitpredpred,inter));
  338.              }
  339.            if (sitsucc != nil)
  340.             {
  341.               lsucc=Y_structure.key(sitsucc);
  342.               if ((pqit = Y_structure.inf(sitpred)) != nil)
  343.                 delete Xdelete(pqit);
  344.                  
  345.               Y_structure.change_inf(sitpred,nil);
  346.               if (intersection(lsucc,lsit,inter))
  347.                   Y_structure.change_inf(sit,Xinsert(sit,inter));
  348.              }
  349. // reverse the subsequence sit, ... ,sitpred  in the Y_structure
  350.            x_sweep = get_x(p);
  351.            y_sweep = get_y(p);
  352.            Y_structure.reverse_items(sit,sitpred);
  353.           delete p;
  354.          } // intersection
  355.   }
  356.   X_structure.clear();
  357.   Y_structure.clear();
  358.   // normalize x and y coordinates 
  359.   node v;
  360.   forall_nodes(v,G) 
  361.   { xcoord[v] /= (x_sweep + MAX_X/12);
  362.     ycoord[v] /= MAX_Y;
  363.    }
  364. }