home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / dev / misc / LEDA_src.lha / LEDA-3.1c-source / src / graph / _g_generate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-17  |  9.5 KB  |  460 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _g_generate.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/array.h>
  16. #include <LEDA/graph.h>
  17. #include <LEDA/ugraph.h>
  18. #include <ctype.h>
  19.  
  20. // some graph generators
  21.  
  22. void complete_graph(graph& G, int n)
  23. { node v,w;
  24.   G.clear();
  25.   while (n--) G.new_node();
  26.   forall_nodes(v,G)
  27.      forall_nodes(w,G) 
  28.         G.new_edge(v,w);
  29. }
  30.  
  31. void complete_ugraph(ugraph& G, int n)
  32. { int i,j;
  33.   node* V = new node[n];
  34.   G.clear();
  35.   for(i=0;i<n;i++) V[i] = G.new_node();
  36.   for(i=0;i<n;i++) 
  37.     for(j=i+1;j<n;j++) 
  38.        G.new_edge(V[i],V[j]);
  39. }
  40.  
  41.  
  42. void grid_graph(graph& G, int n) 
  43. { node_array<double> xcoord; 
  44.   node_array<double> ycoord;
  45.   grid_graph(G,xcoord,ycoord,n);
  46.  }
  47.  
  48. void grid_graph(graph& G, node_array<double>& xcoord, 
  49.                           node_array<double>& ycoord, int n) 
  50. {
  51.   array2<node>  A(n,n);
  52.   node v;
  53.   int N = n*n;
  54.   int x;
  55.   int y;
  56.  
  57.   double d = 1.0/(n+1);
  58.  
  59.   G.clear();
  60.  
  61.   xcoord.init(G,N,0);
  62.   ycoord.init(G,N,0);
  63.  
  64.   for(y=0; y<n; y++)
  65.     for(x=0; x<n; x++)
  66.       { A(x,y) = v = G.new_node();
  67.         xcoord[v] = (x+1)*d;
  68.         ycoord[v] = (y+1)*d;
  69.        }
  70.  
  71.   for(x=0; x<n; x++)
  72.     for(y=0; y<n; y++)
  73.        { if (x < n-1) G.new_edge(A(x,y),A(x+1,y));
  74.          if (y < n-1) G.new_edge(A(x,y),A(x,y+1));
  75.         }
  76. }
  77.  
  78.  
  79. void complete_bigraph(graph& G, int n1, int n2, list<node>& A, list<node>& B)
  80. { node v,w;
  81.  
  82.   for(int a=0; a < n1; a++)  A.append(G.new_node());
  83.   for(int b=0; b < n2; b++)  B.append(G.new_node());
  84.  
  85.   forall(v,A) 
  86.   {  forall(w,B) 
  87.        G.new_edge(v,w);
  88.    }
  89.  }
  90.  
  91. void user_graph(graph& G)
  92. { int  n = read_int("|V| = ");
  93.   int  i,j;
  94.  
  95.   node* V = new node[n];
  96.   for(j=0; j<n; j++) V[j] = G.new_node();
  97.  
  98.   for(j=0; j<n; j++) 
  99.   { list<int> il;
  100.     bool ok = false;
  101.     while (!ok)
  102.     { ok = true;
  103.       cout << "edges from [" << j << "] to: ";
  104.       il.read();
  105.       forall(i,il) 
  106.         if (i < 0 || i >= n) 
  107.         { ok=false;
  108.           cout << "illegal node " << i << "\n";
  109.          }
  110.      }
  111.     forall(i,il) G.new_edge(V[j],V[i]);
  112.   }
  113.   G.print();
  114.   if (Yes("save graph ? ")) G.write(read_string("file: "));
  115. }
  116.  
  117.  
  118.  
  119. void test_graph(graph& G)
  120.   G.clear();
  121.   char c;
  122.  
  123.   do c = read_char("graph: f(ile) r(andom) c(omplete) p(lanar) u(ser): ");
  124.   while (c!='f' && c!='r' && c!='c' && c!='p'&& c!='u');   
  125.  
  126.   switch (c) {
  127.  
  128.    case 'f' : { G.read(read_string("file: "));
  129.                 break;
  130.                }
  131.  
  132.    case 'u' : { user_graph(G);
  133.                 break;
  134.                }
  135.  
  136.    case 'c' : { complete_graph(G,read_int("|V| = "));
  137.                 break;
  138.                }
  139.  
  140.    case 'r' : { int n = read_int("|V| = ");
  141.                 int m = read_int("|E| = ");
  142.                 random_graph(G,n,m);
  143.                 break;
  144.                }
  145.  
  146.    case 'p' : { random_planar_graph(G,read_int("|V| = "));
  147.                 break;
  148.                }
  149.    }//switch
  150.  
  151. }
  152.  
  153. void test_ugraph(ugraph& G)
  154.   G.clear();
  155.   char c;
  156.  
  157.   do c = read_char("graph: f(ile) r(andom) c(omplete) p(lanar) u(ser): ");
  158.   while (c!='f' && c!='r' && c!='c' && c!='p'&& c!='u');   
  159.  
  160.   int  i;
  161.   node v;
  162.   
  163.   switch (c) {
  164.  
  165.   case 'f' : { G.read(read_string("file: "));
  166.                break;
  167.               }
  168.  
  169.    case 'u' : { int  n = read_int("|V| = ");
  170.                 int  j = 0;
  171.                 node* V = new node[n];
  172.                 loop(i,0,n-1) V[i] = G.new_node();
  173.                 forall_nodes(v,G)
  174.                   { list<int> il;
  175.                     cout << "edges from " << j++ << " to: ";
  176.                     il.read();
  177.                     forall(i,il) 
  178.                       if (i >= 0 && i < n) G.new_edge(v,V[i]);
  179.                       else cerr << "illegal node " << i << " (ignored)\n";
  180.                    }
  181.                 G.print();
  182.                 if (Yes("save graph ? ")) G.write(read_string("file: "));
  183.                 break;
  184.                }
  185.  
  186.    case 'c' : { int n = read_int("|V| = ");
  187.                 complete_graph(G,n);
  188.                 break;
  189.                }
  190.  
  191.    case 'r' : { int n = read_int("|V| = ");
  192.                 int m = read_int("|E| = ");
  193.                 random_graph(G,n,m);
  194.                 break;
  195.                }
  196.  
  197.    }//switch
  198.  
  199. }
  200.  
  201.  
  202.  
  203.  
  204.  
  205. void test_bigraph(graph& G, list<node>& A, list<node>& B)
  206. {
  207.   int  a,b,n1,n2;
  208.   char c;
  209.  
  210.   do c = read_char("bipartite graph: f(ile) r(andom) c(omplete) u(ser): ");
  211.   while (c!='f' && c!='r' && c!='c' && c!='u');   
  212.  
  213.   A.clear();
  214.   B.clear();
  215.   G.clear();
  216.  
  217.   if (c!='f') 
  218.    { n1 = read_int("|A| = ");
  219.      n2 = read_int("|B| = ");
  220.     }
  221.   
  222.   
  223.   switch (c) {
  224.  
  225.   case 'f' : { G.read(read_string("file: "));
  226.                node v;
  227.                forall_nodes(v,G) 
  228.                if (G.outdeg(v) > 0) A.append(v);
  229.                else B.append(v);
  230.  
  231.                break;
  232.               }
  233.  
  234.    case 'u' : { node* AV = new node[n1+1];
  235.                 node* BV = new node[n2+1];
  236.  
  237.                 loop(a,1,n1)  A.append(AV[a] = G.new_node());
  238.                 loop(b,1,n2)  B.append(BV[b] = G.new_node());
  239.  
  240.                 loop(a,1,n1)
  241.                   { list<int> il;
  242.                     cout << "edges from " << a << " to: ";
  243.                     il.read();
  244.                     forall(b,il) if (b<=n2) G.new_edge(AV[a],BV[b]);
  245.                                  else break;
  246.                     if (b>n2) break;
  247.                    }
  248.                 break;
  249.                }
  250.  
  251.    case 'c' : complete_bigraph(G,n1,n2,A,B);
  252.               break;
  253.  
  254.    case 'r' : { int m = read_int("|E| = ");
  255.                 random_bigraph(G,n1,n2,m,A,B);
  256.                 break;
  257.                }
  258.  
  259.        } // switch
  260.  
  261. }
  262.  
  263.  
  264.  
  265. void cmdline_graph(graph& G, int argc, char** argv)
  266.   // construct graph from cmdline arguments
  267.  
  268.   if (argc == 1)           // no arguments 
  269.      { test_graph(G);
  270.        return;
  271.       }
  272.   else 
  273.      if (argc == 2)       // one argument
  274.         { if (isdigit(argv[1][0])) 
  275.              { cout << "complete graph |V| = " << argv[1];
  276.                newline;
  277.                newline;
  278.                complete_graph(G,atoi(argv[1]));
  279.               }
  280.           else 
  281.              { cout << "reading graph from file " << argv[1];
  282.                newline;
  283.                newline;
  284.                G.read(argv[1]);
  285.               }
  286.           return;
  287.          }
  288.      else
  289.         if (argc == 3 && isdigit(argv[1][0]) && isdigit(argv[1][0])) 
  290.            { cout << "random graph |V| = " << argv[1] << "  |E| = " << argv[2];
  291.              newline;
  292.              newline;
  293.              random_graph(G,atoi(argv[1]),atoi(argv[2]));
  294.              return;
  295.             }
  296.  
  297.   error_handler(1,"cmdline_graph: illegal arguments");
  298. }
  299.  
  300.  
  301.  
  302.  
  303. //------------------------------------------------------------------------------
  304. // triangulated planar graph
  305. //------------------------------------------------------------------------------
  306.  
  307.  
  308. #include <LEDA/d_array.h>
  309.  
  310.  
  311. struct triang_point {
  312.  
  313. double x,y;
  314.  
  315. LEDA_MEMORY(triang_point)
  316.  
  317. triang_point(double a=0, double b = 0) { x = a; y = b; }
  318.  
  319. bool operator==(const triang_point& p) { return x==p.x && y==p.y; }
  320.  
  321. friend int compare(const triang_point& p, const triang_point& q)
  322. { int c = compare(p.x,q.x);
  323.   if (c==0) c = compare(p.y,q.y);
  324.   return c;
  325.  }
  326.  
  327. friend void Print(const triang_point&, ostream&) {}
  328. friend void Read(triang_point&, istream&) {}
  329.  
  330.  
  331. friend bool right_turn(const triang_point& a, const triang_point& b, const triang_point& c)
  332. { return (a.y-b.y)*(a.x-c.x)+(b.x-a.x)*(a.y-c.y) > 0; }
  333.  
  334. friend bool left_turn(const triang_point& a, const triang_point& b, const triang_point& c)
  335. { return (a.y-b.y)*(a.x-c.x)+(b.x-a.x)*(a.y-c.y) < 0; }
  336.  
  337. };
  338.  
  339.  
  340.  
  341. #if !defined(__TEMPLATE_FUNCTIONS__)
  342. LEDA_TYPE_PARAMETER(triang_point)
  343. #endif
  344.  
  345.  
  346. void triangulated_planar_graph(graph& G, node_array<double>& xcoord,
  347.                                          node_array<double>& ycoord, int n)
  348.  
  349.   list<triang_point> L;
  350.   list<triang_point> CH;
  351.   list_item last;
  352.   triang_point p,q;
  353.  
  354.   for(int i = 0; i < n; i++)
  355.  
  356.   L.append(triang_point(rrandom(),rrandom()));
  357.  
  358.   L.sort();  // sort triang_points lexicographically
  359.  
  360.  
  361.   // eliminate multiple triang_points
  362.  
  363.   list_item it;
  364.   forall_items(it,L)
  365.   { list_item it1 = L.succ(it);
  366.     while (it1 != nil && L[it1] == L[it])
  367.     { L.del(it1);
  368.       it1 = L.succ(it);
  369.      }
  370.    }
  371.  
  372.   n = L.length();
  373.  
  374.   d_array<triang_point,node> V(nil);
  375.  
  376.   xcoord.init(G,n,0);
  377.   ycoord.init(G,n,0);
  378.  
  379.   forall(p,L) 
  380.   { node v = G.new_node();
  381.     xcoord[v] = p.x;
  382.     ycoord[v] = p.y;
  383.     V[p] = v;
  384.    }
  385.  
  386.  
  387.   // initialize convex hull with first two points
  388.  
  389.   p = L.pop();
  390.   CH.append(p);
  391.  
  392.   while (L.head() == p) L.pop();
  393.   q = L.pop();
  394.   last = CH.append(q);
  395.  
  396.   G.new_edge(V[p],V[q]);
  397.  
  398.  
  399.   // scan remaining points
  400.  
  401.   forall(p,L)
  402.   {
  403.     node v = V[p];
  404.  
  405.     G.new_edge(v,V[CH[last]]);
  406.  
  407.     // compute upper tangent (p,up)
  408.  
  409.     list_item up = last;
  410.     list_item it = CH.cyclic_succ(up);
  411.  
  412.     while (left_turn(CH[it],CH[up],p))
  413.     { up = it;
  414.       it = CH.cyclic_succ(up);
  415.       G.new_edge(v,V[CH[up]]);
  416.      }
  417.  
  418.  
  419.     // compute lower tangent (p,low)
  420.  
  421.     list_item low = last;
  422.     it = CH.cyclic_pred(low);
  423.  
  424.     while (right_turn(CH[it],CH[low],p))
  425.     { low = it;
  426.       it = CH.cyclic_pred(low);
  427.       G.new_edge(v,V[CH[low]]);
  428.      }
  429.  
  430.  
  431.     // remove all points between up and low
  432.  
  433.     if (up != low)
  434.     { it = CH.cyclic_succ(low);
  435.  
  436.       while (it != up)
  437.       { CH.del(it);
  438.         it = CH.cyclic_succ(low);
  439.        }
  440.      }
  441.  
  442.     // insert new point
  443.  
  444.     last = CH.insert(p,low);
  445.  
  446.    }
  447.  
  448. }
  449.  
  450. void triangulated_planar_graph(graph& G, int m)
  451. { node_array<double> xcoord;
  452.   node_array<double> ycoord;
  453.   triangulated_planar_graph(G,xcoord,ycoord,m);
  454.  }
  455.