Advertisement
xopsuei

force directed madness

Jan 30th, 2013
291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.17 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. #include <cstdlib>
  5. #include <ctime>
  6.  
  7. using namespace std;
  8.  
  9. typedef vector<int> vi;
  10. typedef vector<vi> vii;
  11.  
  12. struct vec {
  13.     int x, y;
  14. };
  15.  
  16. struct vecf {
  17.     double x, y;
  18. };
  19.  
  20. struct Graph {
  21.     int vertices, edges;
  22.     vector <vec> pos;
  23.     vector <vecf> disp;
  24.     vi grau, adj, loc;
  25. } g;
  26.  
  27. /*
  28.  * GRAPH STUFF
  29.  */
  30.  
  31. //gets a graph in the .gra format
  32. void get_graph(){
  33.     int vertices, edges;
  34.     cin >> vertices >> edges;
  35.     g.vertices = vertices;
  36.     g.edges = edges;
  37.  
  38.     g.grau = vi(vertices);
  39.     for(int i = 0; i < vertices; ++i){
  40.         cin >> g.grau[i];
  41.     }
  42.  
  43.     g.adj = vi(edges*2 + 1);
  44.     for(int i = 0; i < edges*2 + 1; ++i){
  45.         cin >> g.adj[i];
  46.     }
  47.  
  48.     g.loc = vi(vertices + 1);
  49.     for(int i = 0; i < vertices + 1; ++i){
  50.         cin >> g.loc[i];
  51.     }
  52.  
  53. }
  54.  
  55. //randomizes the distribution of a graph in a frame of w by l
  56. void randomize_graph(int w, int l){
  57.     srand(time(NULL));
  58.  
  59.     for(int i = 0; i < g.vertices; ++i){
  60.         g.pos[i].x = rand() % (l + 1);
  61.         g.pos[i].y = rand() % (w + 1);
  62.     }
  63. }
  64.  
  65. /*
  66.  * ALGORITHM STUFF
  67.  */
  68.  
  69.  double attraction_force(int d, int k){
  70.     return (d*d)/k;
  71.  }
  72.  
  73.  double repulsion_force(int d, int k){
  74.     return -(k*k)/d;
  75.  }
  76.  
  77. //cooling function
  78.  void cool(double& t){
  79.     t = 0.95*t;
  80.  }
  81.  
  82. /*
  83. // diference between vectors
  84. bool operator!= (const vec& a, const vec& b){
  85.     return ((a.x != b.x) or (a.y != b.y));
  86. }
  87. */
  88.  
  89. //gets frame size interations and temperature
  90. //simulates graph
  91. int main(){
  92.     int height, width, iterations;
  93.     double k, t;
  94.  
  95.     cin >> height, width >> iterations;
  96.  
  97.     t = width/10;
  98.  
  99.     //force constant
  100.     //C*sqrt(area/#vertices)
  101.     k = sqrt(height*width/g.vertices);
  102.  
  103.     for(int k = 0; k < iterations; ++k){
  104.  
  105.         //calculate repulsive forces
  106.         for(int i = 0; i < g.vertices; ++i){
  107.             g.disp[i].x = g.disp[i].y = 0;
  108.  
  109.             for(int j = 0; j < g.vertices; ++j){
  110.                 if(i != j){
  111.                     vecf d;
  112.                     d.x = g.pos[i].x - g.pos[j].x;
  113.                     d.y = g.pos[i].y - g.pos[j].y;
  114.  
  115.                     double modulus = sqrt(d.x*d.x + d.y*d.y);
  116.                     double force = repulsion_force(modulus, k);
  117.                     double mult = force / modulus;
  118.  
  119.                     g.disp[i].x = g.disp[i].x + d.x*mult;
  120.                     g.disp[i].y = g.disp[i].y + d.y*mult;                  
  121.                 }
  122.             }
  123.         }
  124.  
  125.         //calculate atractive forces
  126.         for(int i = 0; i < g.edges; ++i){
  127.             for(int j = g.loc[i]; j < g.loc[i + 1]; ++j){
  128.                 vecf d;
  129.                 d.x = g.pos[i].x - g.pos[g.adj[j]].x;
  130.                 d.y = g.pos[i].y - g.pos[g.adj[j]].y;
  131.  
  132.                 double modulus = sqrt(d.x*d.x + d.y*d.y);
  133.                 double force = attraction_force(modulus, k);
  134.                 double mult = force / modulus;
  135.  
  136.                 g.disp[i].x = g.disp[i].x + d.x*mult;
  137.                 g.disp[i].y = g.disp[i].y + d.y*mult;
  138.             }
  139.         }
  140.  
  141.         //limit displacement by temperature t
  142.         //prevent displacement outside of the frame
  143.         for(int i = 0; i < g.vertices; ++i){
  144.             double modulus = sqrt(g.disp[i].x*g.disp[i].x + g.disp[i].y*g.disp[i].y);
  145.  
  146.             double prod_x = min(g.disp[i].x, t)/modulus;
  147.             double prod_y = min(g.disp[i].y, t)/modulus;
  148.  
  149.             g.pos[i].x = g.pos[i].x + g.disp[i].x*prod_x;
  150.             g.pos[i].y = g.pos[i].y + g.disp[i].y*prod_y;
  151.  
  152.             g.pos[i].x = min(width/2 , max(-1*width/2, g.pos[i].x));
  153.             g.pos[i].y = min(height/2, max(-1*height/2, g.pos[i].y));
  154.         }
  155.  
  156.         cool(t);
  157.     }
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement