Advertisement
machalda

PERL homework #2v2

Jun 24th, 2012
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.96 KB | None | 0 0
  1. ############################################# MODUL
  2. #!/usr/bin/perl
  3. package graflib;
  4.  
  5. # objekt grafu
  6. sub new {
  7.   my $class = shift;
  8.   my $object = {
  9.     a => shift, # parametr a
  10.     b => shift, # parametr b
  11.     c => shift, # parametr c
  12.     node_list => {}, # seznam uzlu
  13.     link_types => {}, # seznam typu hran
  14.   };
  15.   bless $object, $class;
  16.   return $object;
  17. }
  18.  
  19. # zadavani typu hran do seznamu typu hran
  20. sub link_type {
  21.   my($self, $type, $reciprocal) = @_;
  22.   $self->{link_types}{$type}{weight} = 0;
  23.   $self->{link_types}{$type}{reciprocal} = $reciprocal;
  24. }
  25.  
  26. # dodani vah do seznamu typu hran
  27. sub link_weight {
  28.   my($self, $type, $weight) = @_;
  29.   $self->{link_types}{$type}{weight} = $weight;
  30. }
  31.  
  32. # pridani konkretnich hran
  33. sub add_link {
  34.   my($self, $from, $to, $type) = @_;
  35.   my $weight = $self->{link_types}{$type}{weight};
  36.   # pridani vystupni hrany
  37.   push @{$self->{node_list}{$from}{out}{$to}}, $weight;
  38.   if ($self->{link_types}{$type}{reciprocal}) {
  39.     push @{$self->{node_list}{$to}{out}{$from}}, $weight;
  40.   }
  41.   # pridani vstupni hrany
  42.   push @{$self->{node_list}{$to}{in}{$from}}, $weight;
  43.   if ($self->{link_types}{$type}{reciprocal}) {
  44.     push @{$self->{node_list}{$from}{in}{$to}}, $weight;
  45.   }
  46. }
  47.  
  48. # pridani konkretnich uzlu
  49. sub add_node {
  50.   my($self, $name, $type) = @_;
  51.   $self->{node_list}{$name}{type} = $type;
  52.   $self->{node_list}{$name}{level} = 0;
  53.   $self->{node_list}{$name}{initial} = 0;
  54. }
  55.  
  56. # dodani hodnoty uzlu
  57. sub set_value {
  58.   my($self, $name, $level) = @_;
  59.   $self->{node_list}{$name}{level} = $level;
  60.   if ($level > 0) {$self->{node_list}{$name}{initial} = $level;}
  61. }
  62.  
  63. # sireni signalu do hran dle vzorce Xi * 1 / outdegree(i)^b
  64. # !!! vzorec nesedi s referencnimi hodnotami, nutno vynasobit sqrt(pocet vystupnich hran) !!!
  65. sub signal_wave {
  66.   my($self, $node) = @_;
  67.   my $xi = $$node->{level};
  68.   my $out_links = 0;
  69.   # pocet vystupnich hran
  70.   for my $nodes (keys %{$$node->{out}}) {
  71.     $out_links += scalar @{$$node->{out}{$nodes}};
  72.   }
  73.   # aplikace vzorce
  74.   if ($xi != 0 && $out_links != 0) {
  75.     ($xi * 1 / $out_links ** $self->{b})* sqrt($out_links); # zminena nekonzistence zadani
  76.   }
  77.   else {$xi;}
  78. }
  79.  
  80. # pruchod hranou
  81. sub throught_link {
  82.   my($self, $signal, $weight) = @_;
  83.   $signal * $weight;
  84. }
  85.  
  86. # vypocet nove hodnoty dle vzorce a*X(i) + b*Input(i) + c*Output(i)
  87. sub new_value {
  88.   my($self, $node) = @_;  
  89.   my $node = \$self->{node_list}{$node};  
  90.   my $xi = $$node->{level};
  91.   my $nodes;
  92.   my $weight;
  93.   # vypocet prichazejicich signalu
  94.   my $input = 0;  
  95.   for $nodes (keys %{$$node->{in}}) {
  96.     my $signal = $self->{node_list}{$nodes}{signal};
  97.     for my $weight (@{$$$node{in}{$nodes}}) {
  98.       $input += $self->throught_link($signal, $weight);
  99.     }
  100.   }
  101.   # vypocet poslanych signalu    
  102.   my $output = 0;
  103.   for $nodes (keys %{$$node->{out}}) {
  104.     for $weight (@{$$$node{out}{$nodes}}) {
  105.       $output += $$node->{signal};
  106.     }
  107.   }
  108.   # aplikace vzorce
  109.   return $self->{a} * $xi + $self->{b} * $input + $self->{c} * $output;
  110. }
  111.  
  112. # smazani uzlu
  113. sub delete_node {
  114.   my($self, $node) = @_;
  115.   delete $self->{node_list}{$node};
  116.   for my $nodes (keys %{$self->{node_list}}){
  117.     delete $self->{node_list}{$nodes}{in}{$node};
  118.     delete $self->{node_list}{$nodes}{out}{$node};
  119.   }
  120. }
  121. 1;
  122.  
  123. ############################################################### Main program
  124. #!/usr/bin/perl
  125. use graflib;
  126. use strict;
  127. use encoding 'UTF-8';
  128.  
  129. my $a; # parametr a
  130. my $b; # parametr b
  131. my $c; # parametr c
  132. my $i; # pocet iteraci
  133. my $t; # redukcni konstanta
  134. my $k; # zpusob kalibrace
  135.  
  136. # otevreni souboru zadaneho parametrem
  137. open FILE, "<:encoding(UTF-8)", @ARGV[0] or die "$!\n";
  138. while (<FILE>) { # hledani parametru a
  139.   @_ = split /\s+/;
  140.   my $keyword = shift @_;
  141.   if ($keyword eq "a") {$a = shift @_;}
  142. }
  143. seek FILE, 0, 0;
  144. while (<FILE>) { # hledani parametru b
  145.   @_ = split /\s+/;
  146.   my $keyword = shift @_;
  147.   if ($keyword eq "b") {$b = shift @_;}
  148. }
  149. seek FILE, 0, 0;
  150. while (<FILE>) { # hledani parametru c
  151.   @_ = split /\s+/;
  152.   my $keyword = shift @_;
  153.   if ($keyword eq "c") {$c = shift @_;}
  154. }
  155. seek FILE, 0, 0;
  156. # pouziti parametru k vytvoreni objektu
  157. my $graf = graflib->new($a,$b,$c);
  158. while (<FILE>) { # hledani poctu iteraci
  159.   @_ = split /\s+/;
  160.   my $keyword = shift @_;
  161.   if ($keyword eq "IterationsNo") {$i = shift @_;}
  162. }
  163. seek FILE, 0, 0;
  164. while (<FILE>) { # hledani redukcni konstanty
  165.   @_ = split /\s+/;
  166.   my $keyword = shift @_;
  167.   if ($keyword eq "t") {$t = shift @_;}
  168. }
  169. seek FILE, 0, 0;
  170. while (<FILE>) { # hledani zpusobu kalibrace
  171.   @_ = split /\s+/;
  172.   my $keyword = shift @_;
  173.   if ($keyword eq "Calibration") {$k = shift @_;}
  174. }
  175. seek FILE, 0, 0;
  176. while (<FILE>) { # pridani typu hran
  177.   @_ = split /\s+/;
  178.   my $keyword = shift @_;
  179.   if ($keyword eq "ltra") {$graf->link_type(@_);}
  180. }
  181. seek FILE, 0, 0;
  182. while (<FILE>) { # pridani vahy vazeb
  183.   @_ = split /\s+/;
  184.   my $keyword = shift @_;
  185.   if ($keyword eq "lw") {$graf->link_weight(@_);}
  186. }
  187. seek FILE, 0, 0;
  188. while (<FILE>) { # pridani konkretnich uzlu
  189.   @_ = split /\s+/;
  190.   my $keyword = shift @_;
  191.   if ($keyword eq "n") {$graf->add_node(@_);}
  192. }
  193. seek FILE, 0, 0;
  194. while (<FILE>) { # pridani konkretnich hran
  195.   @_ = split /\s+/;
  196.   my $keyword = shift @_;
  197.   if ($keyword eq "l") {$graf->add_link(@_);}
  198. }
  199. seek FILE, 0, 0;
  200. while (<FILE>) { # nastaveni pocatecnich hodnot
  201.   @_ = split /\s+/;
  202.   my $keyword = shift @_;
  203.   if ($keyword eq "ia") {$graf->set_value(@_);}
  204. }
  205. # zavreni souboru
  206. close FILE;
  207.  
  208. # vypsani prvniho radku s nazvy uzlu
  209. print "iter. ";
  210. for my $nodes (sort(keys %{$graf->{node_list}})) {print "$nodes ";}
  211. print "\n";
  212.  
  213. # iterovani
  214. for (my $j = 0; $j <= $i; $j++){
  215.   my $node;
  216.   my $calibsum;
  217.   my $calibsumall;
  218.   # tisk hodnot uzlu
  219.   print "$j ";
  220.   for my $nodes (sort(keys %{$graf->{node_list}})) {
  221.     printf "%.3f ", $graf->{node_list}{$nodes}{level};
  222.   }
  223.   print "\n";
  224.   # kalibrace 2: zapamatuji si sumu v pocatku aktivovanych uzlu
  225.   for my $nodes (keys %{$graf->{node_list}}) {
  226.     if ($k eq "ConservationOfTotalActivation" && $graf->{node_list}{$nodes}{initial} > 0) {
  227.       $calibsum += $graf->{node_list}{$nodes}{initial};
  228.     }
  229.   }
  230.   # vypocet signalu v uzlech
  231.   for my $nodes (keys %{$graf->{node_list}}) {
  232.     $node = \$graf->{node_list}{$nodes};
  233.     my $signal = $graf->signal_wave($node);
  234.     $graf->{node_list}{$nodes}{signal} = $signal;
  235.   }
  236.   # vypocet nove hodnoty uzlu
  237.   for my $nodes (keys %{$graf->{node_list}}) {
  238.     my $new = $graf->new_value($nodes);  
  239.     $graf->{node_list}{$nodes}{level} = $new;
  240.   }
  241.   # kalibrace 1: zmenim v pocatku aktivovane uzly na aktivacni hodnoty a pamatuji pomer
  242.   for my $nodes (keys %{$graf->{node_list}}) {
  243.     if ($k eq "ConservationOfInitialActivation" && $graf->{node_list}{$nodes}{initial} > 0) {
  244.       $calibsum += $graf->{node_list}{$nodes}{level} / $graf->{node_list}{$nodes}{initial};
  245.       $graf->{node_list}{$nodes}{level} = $graf->{node_list}{$nodes}{initial};
  246.     }
  247.   }
  248.   # kalibrace 1: vydelim vsechny uzly neaktivovane v pocatku pomerem v pocatku aktivovanych uzlu
  249.   for my $nodes (keys %{$graf->{node_list}}) {
  250.     if ($k eq "ConservationOfInitialActivation" && $graf->{node_list}{$nodes}{initial} == 0) {
  251.       if ($calibsum != 0) {
  252.         $graf->{node_list}{$nodes}{level} = $graf->{node_list}{$nodes}{level} / $calibsum;
  253.       }
  254.     }
  255.   }
  256.   # kalibrace 2: zapamatuji si sumu vsech uzlu
  257.   for my $nodes (keys %{$graf->{node_list}}) {
  258.     if ($k eq "ConservationOfTotalActivation") {
  259.       $calibsumall += $graf->{node_list}{$nodes}{level};
  260.     }
  261.   }
  262.   # kalibrace 2: vydelim vsechny uzly pomerem sumy vsech uzlu a sumy pocatecnich uzlu
  263.   for my $nodes (keys %{$graf->{node_list}}) {
  264.     if ($k eq "ConservationOfTotalActivation") {
  265.       $graf->{node_list}{$nodes}{level} = $graf->{node_list}{$nodes}{level} / ($calibsumall / $calibsum);
  266.     }
  267.   }
  268.   # redukce uzlu podle konstanty t
  269.   for my $nodes (keys %{$graf->{node_list}}) {
  270.     $graf->delete_node($nodes) unless ($graf->{node_list}{$nodes}{level} >= $t);
  271.   }
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement