#!/usr/bin/perl #Derek Dreier #Computer Science Dept. University of California Riverside #1/12/00 #Last modfied 9/20/01 #Barabasi Graph Generator: #This program is a perl script implementing the Barabasi Graph generator as #outlined in the article occuring in Nature #It will run under both Linux and windows using perl's Tk library # #License agreement: Have fun with the code! And tell me what you did. use Tk; #This Perscript is setup into two parts #Part I: Creates the GUI interface #Part II: Implements the program #**********************************PART I******************************************* #**************************Set up the GUI interface********************************* #*********************************************************************************** #****************** Set up the Window Interface for the program*********************** #main window my $mw = MainWindow->new; $mw->title("Barabasi Graph Generator"); $mw->geometry("600x600+0+0"); $mw->resizable(0,0); #************************************************************************************* #********************* Set up Canvas for Drawing graphs ****************************** #canvas my $canvas = $mw->Canvas( -background => "White", -height => 400, -width => 400)->place(-x => 0, -y => 0 ); #************************************************************************************* #*********************** Global Variables ******************************************** #Entry Variables $inititer = "100"; $initnodes = "5"; $initedges = "3"; $textfile = "~/graph.ps"; $iter = 0; $restricter = 0; $corr = 0; $slope = 0; $looper = 3; $loopname = "UCN100"; $edgetype = 1; $disttype = 1; $shownodes = 1; $showgraph = 1; $XA = 0; $XB = 1; $YA = 0; $YB = 1; #************************************************************************************** #******************** Set up all the Labels for the GUI interface ******************** #Labels $mw->Label(-text=> "Iterations = ")->place(-x => 410, -y => 10); $mw->Label(-text=> "Initial Nodes =")->place(-x => 410, -y => 30); $mw->Label(-text=> "Edges added =")->place(-x => 410, -y => 50); $mw->Label(-text=> "Edges added on each iteration")->place(-x => 410, -y => 80); $mw->Label(-text=> "Probability Distribution ")->place(-x => 410, -y => 140); $mw->Label(-text=> "Iter =")->place(-x => 480, -y => 210); $mw->Label(-text=> "Graph Types:")->place(-x => 460, -y => 280); $mw->Label(-text=> "Correlation Coef =")->place(-x => 10, -y => 480); $mw->Label(-text=> "Slope =")->place(-x => 10, -y => 500); $mw->Label(-text=> "Nodes =")->place(-x => 210, -y => 472); $mw->Label(-text=> "Edges =")->place(-x => 210, -y => 500); $mw->Label(-text=> "Edges Saved in edges.txt")->place(-x => 25, -y => 530); $mw->Label(-text=> "Image saved in graph.ps")->place(-x => 220, -y => 530); $mw->Label(-text=> "Degree plot saved in degree.txt")->place(-x => 390, -y => 530); $mw->Label(-text=> "Loop Name: ")->place(-x => 140, -y => 440); #************************************************************************************ #******************* Set up all text entry boxes for GUI interface ***************** #Entry Widgets my $inititerentry = $mw->Entry(-background => "White", -textvariable => \$inititer, -width => 6 )->place(-x => 490, -y => 8); my $initnodesentry = $mw->Entry(-background => "White", -textvariable => \$initnodes, -width => 6 )->place(-x => 500, -y => 30); my $initedgesentry = $mw->Entry(-background => "White", -textvariable => \$initedges, -width => 6 )->place(-x => 500, -y => 50); my $edgesentry = $mw->Entry(-background => "White", -textvariable => \$numedges, -width => 6 )->place(-x => 260, -y => 500); my $nodessentry = $mw->Entry(-background => "White", -textvariable => \$numnodes, -width => 8 )->place(-x => 260, -y => 470); my $iterentry = $mw->Entry(-background => "White", -textvariable => \$iter, -width => 6 )->place(-x => 520, -y => 210); my $restrictentry = $mw->Entry(-background => "White", -textvariable => \$restricter, -width => 6 )->place(-x => 545, -y => 493); my $correntry = $mw->Entry(-background => "White", -textvariable => \$corr, -width => 11 )->place(-x => 125, -y => 480); my $slopeentry = $mw->Entry(-background => "White", -textvariable => \$slope, -width => 11 )->place(-x => 60, -y => 500); my $loopentry = $mw->Entry(-background => "White", -textvariable => \$looper, -width => 4 )->place(-x => 100, -y => 440); my $loopnameentry = $mw->Entry(-background => "White", -textvariable => \$loopname, -width => 12 )->place(-x => 220, -y => 440); #********************************************************************************* #******************** Set up all Buttons for GUI interface************************ #Buttons #gobutton #Calls procedure "go" #Generates the graph $gobutton = $mw->Button(-text => "Generate", -command => \&go )->place(-x => 410, -y => 250 ); #resetbutton #calls procedure "myreset" #resets all data structures $resetbutton = $mw->Button(-text => "RESET", -command => \&myreset )->place(-x => 510, -y => 250 ); #stepbutton #calls procedure "step" #makes one iteration through graph generator $stepbutton = $mw->Button(-text => "Step", -command => \&step )->place(-x => 410, -y => 210 ); #exitbutton #calls procedure "exit" #exits the program my $exitbutton = $mw->Button(-text => "Exit", -command => sub {exit})->place(-x => 550, -y => 5 ); #degreedistbutton #calls procedure "degreegraph" #Displays the log-log plot on the canvas $degreedistbutton = $mw->Button(-text => "Degree", -command => \°reegraph )->place(-x => 421, -y => 300 ); #graphbutton #calls the procedure "showthegraph" #Displays the nodes and vertex graph on the canvas $graphbutton = $mw->Button(-text => "Graph", -command => \&showthegraph )->place(-x => 520, -y => 300 ); #zoominbutton #calls the procedure "zoomin" #Zooms in on the nodes and vertex graph $zoominbutton = $mw->Button(-text => "Zoom In", -command => \&zoomin )->place(-x => 410, -y => 340 ); #zoomoutbutton #calls the procedure "zoomout" #Zooms out on the nodes and vertex graph $zoomoutbutton = $mw->Button(-text => "Zoom Out", -command => \&zoomout )->place(-x => 500, -y => 340 ); #upbutton #calls the procedure "goup" #goes up on the nodes and vertex graph $upbutton = $mw->Button(-text => "UP", -command => \&goup )->place(-x => 475, -y => 380 ); #downbutton #calls the procedure "godown" #goes down on the nodes and vertex graph $downbutton = $mw->Button(-text => "DOWN", -command => \&godown )->place(-x => 465, -y => 440 ); #leftbutton #calls the procedure "goleft" #goes left on the nodes and vertex graph $leftbutton = $mw->Button(-text => "LEFT", -command => \&goleft )->place(-x => 411, -y => 410 ); #rightbutton #calls the procedure "goright" #goes right on the nodes and vertex graph $rightbutton = $mw->Button(-text => "RIGHT", -command => \&goright )->place(-x => 525, -y => 410 ); #restrictbutton #calls procedure "restrictgraphit #shows only nodes of specific degree on nodes and vertex graph $restrictbutton = $mw->Button(-text => "Only Show nodes of degree =", -command => \&restrictgraphit )->place(-x => 340, -y => 490 ); #outgraphbutton #calls procedure createpostscript #outputs whatever is on the canvas to postscript file on hard drive $outgraphbutton = $mw->Button(-text => "Save Image:", -command => \&createpostscript )->place(-x => 250, -y => 550 ); #outdegesbutton #calls procedure outputedges #places the edges of the graph into a file. $outedgesbutton = $mw->Button(-text => "Save Edges:", -command => \&outputedges )->place(-x => 40, -y => 550 ); #resetgraphbutton #calls procedure regraph #redraws the original nodes and vertex graph $resetgraphbutton = $mw->Button(-text => "ReDraw", -command => \®raph )->place(-x => 465, -y => 410); #outdegreebutoon #calls procedure outdegree #outputs the degree values to a file $outdegreebutton = $mw->Button(-text => "OutDegree", -command => \&outdegree )->place(-x => 465, -y => 550); #loopbutton #calls procedure loopitbaby #Places the whole graph generator in a loop to create multiple graphs. $loopbutton = $mw->Button(-text => "Loop", -command => \&loopitbaby )->place(-x => 35, -y => 440); #******************************************************************************* #****************** Set up all radio buttons for GUI interface ******************* #Radio buttons my $constedgerb = $mw->Radiobutton(-text => "Constant",-value => 1, -underline => 0, -variable => \$edgetype) ->place(-x =>450 ,-y =>95); my $randomedgerb = $mw->Radiobutton(-text => "Random",-value => 2, -underline => 0, -variable => \$edgetype) ->place(-x =>450 ,-y =>115); my $unifdistrb = $mw->Radiobutton(-text => "Uniform",-value => 1, -underline => 0, -variable => \$disttype) ->place(-x =>450 ,-y =>160); my $greedydistrb = $mw->Radiobutton(-text => "Greedy",-value => 2,-underline => 1, -variable => \$disttype) ->place(-x =>450 ,-y =>180); #************************************************************************************ #*************** Set up Check boxes for GUI interface ******************************* #CheckButtons my $labelnodescb = $mw->Checkbutton(-text => "Show node Labels", -variable => \$shownodes)->place(-x => 150, -y => 410); my $showgraphcb = $mw->Checkbutton(-text => "Show Graph", -variable => \$showgraph)->place(-x => 10, -y => 410); #************************************************************************************ #********************************* MAINLOOP OF PROGRAM *********************************** #MainLoop is where the program starts MainLoop; #***************************************************************************************** #************************************ PART II ******************************************** #***************************Implementation of Program************************************* #***************************************************************************************** #Procedure myreset #This procedure clears the canvas and reinitializes variables. sub myreset{ clearcanvas(); initializeall(); } #Procedure initializeall #This procedure initializes all global variables the need initialization. sub initializeall{ $numedges = 0; $numnodes = 0; $HPIXELS = 400; $VPIXELS = 400; $XA = 0; $XB = 1; $YA = 0; $YB = 1; $Numberofnodes = 0; $iter = 0; $maxnodes = $inititer; $currentnode = 0; $alreadymadeinitnodes = 0; $numedgestoadd = 0; $smudge = 0.007; $smudge2 = 0.018; $smudge3 = 0.07; @nodes = (); @edges = (); for($i = 0; $i < $maxnodes; $i++){ $nodes[$i] = [0,0,0,0]; } srand; } #Procedure showthegraph #This procedure displays the node and edge graph on the canvas. sub showthegraph{ if ($showgraph == 1) {graphit($currentnode,0);} } #Procedure step #This procedure makes one iteration through the graph creation procedure #The only case to consider is whether the initial nodes are already #created or not. sub step{ if ($alreadymadeinitnodes){ $currentnode++; addnode($currentnode); if ($showgraph == 1) {graphit($currentnode,0);} $iter++; $numnodes = $currentnode + 1; }else{ initializeall(); makeinitialnodes(); $alreadymadeinitnodes = 1; $currentnode = $initnodes - 1; $iter++; $numnodes = $currentnode + 1; } #do not do linear regression unless you have enough nodes. if ($iter > 3){computelineofbestfit();} } #Procedure go #This is the procedure which creates the graph #This is essentially the procedure "step" above just #put into a for loop. sub go{ my $i = 0; for ($i = $iter ; $i <= $inititer; $i++){ if ($alreadymadeinitnodes){ $currentnode++; addnode($currentnode); $iter++; $numnodes = $currentnode + 1; }else{ initializeall(); makeinitialnodes(); $alreadymadeinitnodes = 1; $currentnode = $initnodes - 1; $iter++; $numnodes = $currentnode + 1; } } if ($showgraph == 1){ graphit($currentnode, 1); } computelineofbestfit(); } #Procedure computelineofbestfit #This procedure computes the least squares coefficients and #correlation coefficient for the least squares line of best #fit. sub computelineofbestfit { my $i = 0; my $sumxy = 0; my $sumx = 0; my $sumy = 0; my $sumxsq = 0; my $sumysq = 0; $intercept = 0; $corr = 0; $maxdegree = 0; $n = 0; @prepoints = (); @logpoints = (); @points = (); #find maximum degree for ($i = 0; $i < $numnodes; $i++){ if ($nodes[$i][2] > $maxdegree){ $maxdegree = $nodes[$i][2]; } } #Create array of degree versus number of nodes of that degree #initialize for ($i = 0; $i < $numnodes; $i++){ $prepoints[$i] = 0; } for ($i = 0; $i < $numnodes; $i++){ $prepoints[$nodes[$i][2]]++; } #compute $n the number of categories of degree which have at least 1 node which has that degree #we will not plot degrees which have no nodes of that degree #and make a list of points; #********Important: my algorithm is ignoring nodes of degree = 0 what would be the point anyway?***** @points = (); $n = 1; for ($i = 1; $i < $numnodes; $i++){ if ($prepoints[$i] > 0){ $points[$n][0] = $i; #degree i $points[$n][1] = $prepoints[$i]; #number of nodes of degree i $n++; } } $maxlogpointx = 0; $maxlogpointy = 0; $n--; for ($i = 1; $i <= $n; $i++){ $logpoints[$i][0] = log($points[$i][0]); $logpoints[$i][1] = log($points[$i][1]); if ($logpoints[$i][0] > $maxlogpointx){ $maxlogpointx = $logpoints[$i][0]; } if ($logpoints[$i][1] > $maxlogpointy){ $maxlogpointy = $logpoints[$i][1]; } } #compute sums for ($i = 1; $i <= $n; $i++){ $sumx += $logpoints[$i][0]; $sumy += $logpoints[$i][1]; $sumxy += $logpoints[$i][0] * $logpoints[$i][1]; $sumxsq += $logpoints[$i][0] * $logpoints[$i][0]; $sumysq += $logpoints[$i][1] * $logpoints[$i][1]; } $slope = ( ($n * $sumxy) - ($sumx) * ($sumy)) / ( ($n * $sumxsq) - ($sumx) * ($sumx) ); $intercept = (($sumxsq * $sumy) - ($sumxy * $sumx)) / (($n * $sumxsq) - ($sumx) * ($sumx)); $corr = ($n * $sumxy - $sumx * $sumy) / (sqrt($n * $sumxsq - $sumx * $sumx) * sqrt($n * $sumysq - $sumy * $sumy )); } #Procedure drawaxis #This procedure draws the axis for the linear regression graph sub drawaxis{ #xaxis drawedge(0, 0, $XB, 0,"Black"); #yaxis drawedge(0.01, 0, 0.01, $YB,"Black"); $dv = ($maxlogpointx + 1) / 10; $nv = 0; for ($tt = 0; $tt < 10; $tt++){ drawedge($nv, 0 ,$nv, 0.1,"Black"); $str = sprintf("%0.2f",$nv); if ($tt != 0){ drawtext($nv, 0.2, $str);} $nv += $dv; } $dv = ($maxlogpointy + 1) / 10; $nv = 0; for ($tt = 0; $tt < 10; $tt++){ drawedge(0, $nv, 0.1 ,$nv, "Black"); $str = sprintf("%0.2f",$nv); if ($tt != 0) {drawtext(0.2, $nv, $str); } $nv += $dv; } } #Procedure degreegraph #This procedure draws the log-log graph of log(frequency) vrs log(degree) sub degreegraph{ clearcanvas(); $XA = 0; $XB = $maxlogpointx+1; $YA = 0; $YB = $maxlogpointy+1; drawaxis(); my $i = 1; for ($i = 1; $i <= $n; $i++){ drawplotpoint($logpoints[$i][0] + 0.1, $logpoints[$i][1] + 0.1 , "Red"); } drawedge($XA + 0.1, $slope * $XA + $intercept + 0.1, $XB + 0.1, $slope * $XB + $intercept + 0.1, "Blue"); $XA = 0; $XB = 1; $YA = 0; $YB = 1; } sub restrictgraphit{ clearcanvas(); my $i = 0; my $j = 0; #First draw all the nodes for ($i = 0; $i < $numnodes; $i++){ if (($showgraph == 1) && ($nodes[$i][2] == int($restricter) )){ drawnode($nodes[$i][0], $nodes[$i][1], "Black"); drawtext($nodes[$i][0], $nodes[$i][1], "$i"); } } #draw edges for ($i = 0; $i < $numnodes; $i++){ for $j (0 .. $#{$edges[$i]} ){ if ( ($showgraph == 1) && ($nodes[$i][2] == int($restricter) )){ drawedge($nodes[$i][0], $nodes[$i][1], $nodes[$edges[$i][$j]][0], $nodes[$edges[$i][$j]][1], "Blue"); } } } } #Procedure graphit #This procedure graphs the node and edge graph onto the canvas. sub graphit{ clearcanvas(); my $i = 0; my $j = 0; #First draw all the nodes for ($i = 0; $i <= $_[0]; $i++){ drawnode($nodes[$i][0], $nodes[$i][1], "Black"); if ($shownodes == 1){ drawtext($nodes[$i][0], $nodes[$i][1], "$i"); } } #Second draw all the edges, however if the 2nd paramater passed is 0 we want to color #the last set of edges red so we can see how the last node connected if ($_[1] == 0){ #color the last set of edges for animation step for ($i = 0; $i <= $_[0]; $i++){ for $j (0 .. $#{$edges[$i]} ){ if ($i < $_[0]){ drawedge($nodes[$i][0], $nodes[$i][1], $nodes[$edges[$i][$j]][0], $nodes[$edges[$i][$j]][1], "Blue"); }else{ drawedge($nodes[$i][0], $nodes[$i][1], $nodes[$edges[$i][$j]][0], $nodes[$edges[$i][$j]][1], "Green"); } } } }else{ for ($i = 0; $i <= $_[0]; $i++){ for $j (0 .. $#{$edges[$i]} ){ drawedge($nodes[$i][0], $nodes[$i][1], $nodes[$edges[$i][$j]][0], $nodes[$edges[$i][$j]][1], "Blue"); } } } } #Procedure makeinitialnodes #This procedure draws the initial nodes to the canvas sub makeinitialnodes{ my $i = 0; clearcanvas(); for($i = 0; $i < $initnodes; $i++){ $nodes[$i] = [rand,rand,0,0]; if ($showgraph == 1){ drawnode($nodes[$i][0], $nodes[$i][1], "Black"); if ($shownodes == 1){ drawtext($nodes[$i][0], $nodes[$i][1], "$i"); } } } } #Procedure addnode(numberofnodes) #This procedure is called during the graph creation process. When an new #node needs to be added to the graph, this procedure is called and it connects #edges accordingly to the current graph. sub addnode{ my $i = 0; #make a new node and initialize it $nodes[$_[0]] = [rand, rand, 0, 0]; #find out how many edges to add if ($edgetype == 1){ #add a constant number of edges $numedgestoadd = $initedges; }else{ #add from 0 to $initedges number of edges $numedgestoadd = int(rand($initedges+1)); } #Now add the edges for ($i = 1; $i <= $numedgestoadd; $i++){ $itisanewedge = 0; do{ #decide whether to add a new edge with uniform dist or greedy if ($disttype == 1){ #uniform $newneighbor = choosenodeuniformly($_[0]); }else{ #random $newneighbor = choosenodegreedily($_[0]); } #now check to make sure we have not already created this edge $itisanewedge = verifyedge($_[0],$newneighbor); #if it is a new edge at it to our edge list if ($itisanewedge == 1){ addedge($_[0], $newneighbor); addedge($newneighbor, $_[0]); $numedges++; } } until ($itisanewedge == 1); } } #Procedure addedge(node1, node2) #This procedure is called by the procedure "addnode", this procedure adds an edge #to the current graph and updates the edge list. The edge added is (node1, node2) sub addedge{ my $nd = $_[0]; my $ngh = $_[1]; #increment number of edges for that node $nodes[$nd][2]++; push( @{$edges[$nd]}, $ngh); } #Procedure verifyedge(node1, node2) #This procedure verifies whether an edge exists in the current graph or not. #if the edge does not already exist it returns 1, else it returns 0. #the edge tested is edge (node1, node2) sub verifyedge{ my $found = 1; my $i = 0; for $i ( 0 .. $#{$edges[$_[0]]} ){ if ( $_[1] == $edges[ $_[0] ] [$i]) { $found = 0; } } return $found; } #Procedure choosenodeuniformly(numberofnodes) #This procedure chooses a node in the existing graph to connect to using the #uniform distribution. sub choosenodeuniformly{ return int(rand($_[0])); } #Procedure choosenodedegreedily(numberofnodes); sub choosenodegreedily{ #nodes with higher connectivity get a better chance of getting connected #sum the degree up of all nodes so far in value $sum my $sum = 0; my $i = 0; for($i = 0; $i < $_[0] ; $i++){ $sum += $nodes[$i][2]; $sum++; } #now $sum holds the value of the sum: deg(node[i]) + 1 where i runs through #the number of nodes. The 1 is added to give each node a nonzero probability #of getting chosen. If a node has zero degree it will have zero probability #of getting chosen unless we add this extra 1. The probability function #being used is Probability of node i getting chosen = # deg(node(i)) / SUM(deg(node(1..Numberofnodes)) #randomvalue picks a value from 1 to $sum #this value is used to choose which node to connect to. my $randomvalue = int(rand($sum)+1); #now we find out which category $randomvalue lies in $i = 0; if ($sum != 0){ my $category = $nodes[0][2]; while($randomvalue > $category){ $i++; $category += $nodes[$i][2]; $category++; } } return $i; } #Procedure screenx #This procedure translates real points to screen coordinates for x-axis sub screenx{ return int($HPIXELS / ($XB - $XA) * ($_[0] - $XA) ); } #Procedure screeny #This procedure translates real points to screen coordinates for y-axis sub screeny{ return int($VPIXELS / ($YA - $YB) * ($_[0] - $YB) ); } #Draws a pixel to the canvas #form is: pixel(x, y, color); sub pixel{ $canvas->createLine($_[0],$_[1],$_[0]+1,$_[1]+1, -fill => $_[2]); } #Procedure drawnode(x,y,color) #This procedure draws a node to the canvas for the node and edge graph. sub drawnode{ $canvas->createOval(screenx($_[0]-$smudge), screeny($_[1]-$smudge), screenx($_[0]+$smudge), screeny($_[1]+$smudge), -fill => $_[2]); } #Procedrue drawplotpoint(x,y,color) #This procedure draws a point to the screen used for the log-log line of best fit plot. sub drawplotpoint{ $canvas->createOval(screenx($_[0]-$smudge2), screeny($_[1]-$smudge2), screenx($_[0]+$smudge2), screeny($_[1]+$smudge2), -fill => $_[2]); } #Procedure clearcanvas #This procedure erases the canvas. sub clearcanvas{ $canvas->delete("all"); } #Procedure drawedge(x1,y1, x2,y2,color) #This procedure draws and edge sub drawedge{ $canvas->createLine(screenx($_[0]), screeny($_[1]), screenx($_[2]), screeny($_[3]), -fill => $_[4]); } #Procedure drawtext(x,y,stringoftext) #This procedure draws the text at (x,y) on the canvas. sub drawtext{ $canvas->createText(screenx($_[0]), screeny($_[1]-0.03), -text => "$_[2]"); } #Procedure createpostscript #This procedure outputs what is on the canvas sub createpostscript{ $postscript = $canvas->postscript(); $canvas->postscript(-file => "./graph.ps"); } #These next set of procedures are self explanatory. They let you move in, out, left, right, etc #around the canvas. sub goup{ clearcanvas(); $YA += $smudge; $YB += $smudge; graphit($currentnode, 1); } sub godown{ clearcanvas(); $YA -= $smudge; $YB -= $smudge; graphit($currentnode, 1); } sub goleft{ clearcanvas(); $XA += $smudge; $XB += $smudge; graphit($currentnode, 1); } sub goright{ clearcanvas(); $XA -= $smudge; $XB -= $smudge; graphit($currentnode, 1); } sub regraph{ clearcanvas(); $XA = 0; $XB = 1; $YA = 0; $YB = 1; graphit($currentnode, 1); } sub zoomin{ clearcanvas(); $XA += $smudge3; $XB -= $smudge3; $YA += $smudge3; $YB -= $smudge3; graphit($currentnode, 1); } sub zoomout{ clearcanvas(); $XA -= $smudge3; $XB += $smudge3; $YA -= $smudge3; $YB += $smudge3; graphit($currentnode, 1); } #Procedure outputedges #This procedure outputs the edges of the graph to a text file #The form is node1 space node2 newline #where node1 and node2 form an edge in the graph. sub outputedges{ my $i = 0; my $k = 0; $filename = ">./" . "edges.txt"; open(OUT, $filename); for ($i = 0; $i < $numnodes; $i++){ $k = 0; while ($edges[$i][$k] != NULL){ if ($i < $edges[$i][$k]) {print OUT "$i $edges[$i][$k]\n";} $k++; } } close(OUT); } #Procedure outdegree #This procedure outputs the points of the log-log plot to a file. sub outdegree{ my $i = 0; $filename = ">./" . "degree.txt"; open(OUT, $filename); for ($i = 1; $i <= $n; $i++){ print OUT "$logpoints[$i][0] $logpoints[$i][1]\n"; } close(OUT); } #************************The next procedure are used for looping the ************* #************************graph generator to create multiple graphs *************** #Procedure loopitbaby #This procedure loops the graph generator so that many graphs of a particular #type can be created and saved for use of statistical analysis. sub loopitbaby{ my $lpnum = 0; my $avgcorr = 0; my $avgslope = 0; open(MOUT, ">master$loopname.txt"); print MOUT "file: master$loopname\n"; print MOUT "Initial number of nodes = $initnodes\n"; print MOUT "Number of iterations $looper\n"; if (disttype == 0){ print MOUT "Uniform Distribution\n"; }else{ print MOUT "Greedy Distribution\n"; } if (edgetype == 0){ print MOUT "Constant edges added = $initedges\n"; }else{ print MOUT "Random edges added, range = $initedges\n"; } print MOUT "Slope Correlation #nodes #edges\n"; print MOUT "_________________________________________________________________\n"; for ($lpnum = 1; $lpnum <= $looper; $lpnum++){ initializeall(); myreset(); go(); print MOUT "$slope $corr $numnodes $numedges\n"; $avgcorr += $corr; $avgslope += $slope; fileoutedges($lpnum); fileoutdegree($lpnum); degreegraph(); fileoutpostscript($lpnum); } print MOUT "__________________________________________\n"; $avgslope = $avgslope / $looper; $avgcorr = $avgcorr / $looper; print MOUT "Average slope = $avgslope\n"; print MOUT "Average correlation = $avgcorr\n"; close(MOUT); } sub fileoutedges{ my $i = 0; my $k = 0; $filename = ">./edges$loopname$_[0].txt" ; open(OUT, $filename); for ($i = 0; $i < $numnodes; $i++){ $k = 0; while ($edges[$i][$k] != NULL){ if ($i < $edges[$i][$k]) {print OUT "$i $edges[$i][$k]\n";} $k++; } } close(OUT); } sub fileoutdegree{ my $i = 0; $filename = ">./degree$loopname$_[0].txt"; open(OUT, $filename); for ($i = 1; $i <= $n; $i++){ print OUT "$logpoints[$i][0] $logpoints[$i][1]\n"; } close(OUT); } #Procedure fileoutpostscript #This procedure outputs what is on the canvas sub fileoutpostscript{ $postscript = $canvas->postscript(); $canvas->postscript(-file => "$loopname$_[0].ps"); }