3 # no warranty for this script
9 use FindBin; use lib $FindBin::Bin;
10 use WeaponEncounterProfile;
12 my ($statsfile) = @ARGV;
17 $stats = WeaponEncounterProfile->new($statsfile);
27 my @bigmatrix = map { [ @{$m->[$_]}, $v->[$_] ] } 0..$n-1;
32 # first: bring the highest value to the top
37 my $v = $bigmatrix[$j]->[$i];
38 if($v*$v > $bestval*$bestval)
44 die "lindep" if $best == -1;
47 ($bigmatrix[$i], $bigmatrix[$best]) = ($bigmatrix[$best], $bigmatrix[$i]);
52 my $r = $bigmatrix[$j]->[$i];
55 $bigmatrix[$j]->[$k] -= $bigmatrix[$i]->[$k] * $r / $bestval;
61 for my $i(reverse 0..$n-1)
63 my $bestval = $bigmatrix[$i]->[$i];
66 my $r = $bigmatrix[$j]->[$i];
69 $bigmatrix[$j]->[$k] -= $bigmatrix[$i]->[$k] * $r / $bestval;
74 # 3. Read off solutions
75 return map { $bigmatrix[$_]->[$n] / $bigmatrix[$_]->[$_] } 0..($n-1);
78 sub SolveBestSquares($$)
93 my $weight = $w->[$i]->[$j];
94 $num += $weight * $d->[$i]->[$j];
97 push @result, $num / $denom;
102 # build linear equation system
104 my @matrix = map { [ map { 0 } 1..$n ] } 1..$n;
105 my @vector = map { 0 } 1..$n;
116 $matrix[$z][$i] += $w->[$i]->[$z];
117 $matrix[$z][$z] -= $w->[$i]->[$z];
118 $vector[$z] += $w->[$i]->[$z] * $d->[$i]->[$z];
122 return LinSolve(\@matrix, \@vector);
129 while(my ($k, $v) = each %$matrix)
131 for(my ($k2, $v2) = each %$v)
139 delete $allweps{"@!#%'n Tuba"};
140 #delete $allweps{"Port-O-Launch"};
141 my @allweps = keys %allweps;
144 my @dmatrix = map { [ map { 0 } @allweps ] } @allweps;
145 my @wmatrix = map { [ map { 0 } @allweps ] } @allweps;
147 for my $i(0..@allweps - 1)
149 my $attackweapon = $allweps[$i];
152 for my $j(0..@allweps - 1)
154 my $defendweapon = $allweps[$j];
155 next if $attackweapon eq $defendweapon;
156 my $win = ($matrix->{$attackweapon}{$defendweapon} || 0);
157 my $lose = ($matrix->{$defendweapon}{$attackweapon} || 0);
158 my $c = ($win + $lose);
161 my $w = 1 - 1/($c * 0.1 + 1);
163 $dmatrix[$i][$j] = $p - (1 - $p); # antisymmetric
164 $wmatrix[$i][$j] = $w; # symmetric
171 @val = SolveBestSquares(\@dmatrix, \@wmatrix);
176 @val = map { undef } @allweps;
179 for my $i(0..@allweps - 1)
181 my $attackweapon = $allweps[$i];
182 $values{$attackweapon} = $val[$i];
190 my ($addr, $map, $data) = @_;
191 print "For server @{[$addr || 'any']} map @{[$map || 'any']}:\n";
192 my $values = Evaluate $data;
193 my $valid = defined [values %$values]->[0];
194 my @weapons_sorted = sort { $valid ? $values->{$b} <=> $values->{$a} : $a cmp $b } keys %$values;
196 for my $row(@weapons_sorted)
198 printf " %-30s %8s |", $row, $valid ? sprintf("%8.5f", $values->{$row}) : "N/A";
199 for my $col(@weapons_sorted)
201 my $win = ($data->{$row}{$col} || 0);
202 my $lose = ($data->{$col}{$row} || 0);
204 if $row ne $col and (not defined $min or $min > $win + $lose);
205 if(($row eq $col) || ($win + $lose == 0))
215 my $p = 2 * ($win / ($win + $lose) - 0.5);
216 printf " %+6.3f", $p;
222 print " Relevance: $min\n";