chiark / gitweb /
Fixes etc. for ypp map parser and distance processor
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Thu, 27 Aug 2009 18:16:26 +0000 (19:16 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Thu, 27 Aug 2009 18:16:26 +0000 (19:16 +0100)
yarrg/yppedia-chart-parser

index 09e8fe8b1b82aa22e7140bf5b6ff3069310a499d..e1f022c171a5ee7dc7eedc11a29f10efe59e3763 100755 (executable)
@@ -81,7 +81,6 @@ sub yppedia_chart_parse () {
            $winode2island{$n}= $island;
            $widists->add_vertex($n);
            $wiarchs->add_vertex($n);
-#print "\$g->add_vertex('$n');\n";
            printf DEBUG "%2d,%-2d island %s\n", $x,$y,$island;
        } elsif (($solid,$x,$y,$dirn) =
            m/^\{\{ chart\ league((?:\ solid)?) \|(\d+)\|(\d+)\|
@@ -94,13 +93,13 @@ sub yppedia_chart_parse () {
            elsif ($dirn eq '/') { $x++; $by++; }
            else { die; }
 
-           $widists->add_weighted_edge($nn->(), nn_xy($bx,$by), 1);
-           $wiarchs->add_edge($nn->(), nn_xy($bx,$by)) if $solid;
-           $wiarchs->add_edge($nn->(), nn_xy($bx,$by)) if $solid;
-#print "\$g->add_edge('".$nn->()."','".nn_xy($bx,$by)."');\n" if $solid;
+           my $nb= nn_xy($bx,$by);
+           $widists->add_weighted_edge($nn->(), $nb, 1);
+           $wiarchs->add_edge($nn->(), $nb) if $solid;
+           $wiarchs->add_edge($nn->(), $nb) if $solid;
 
-           printf DEBUG "%2d,%-2d league %-6s %s\n", $x,$y,
-               $solid?'solid':'dotted', $dirn;
+           printf DEBUG "%2d,%-2d league %-6s %s %s\n", $x,$y,
+               $solid?'solid':'dotted', $dirn, $nb;
        } elsif (
            m/^\{\{ chart\ head \}\}$/xi
                 ) {
@@ -130,6 +129,25 @@ sub database_fetch_ocean () {
     }
 }                       
 
+sub yppedia_graphs_add_shortcuts () {
+    # We add edges between LPs we know about, as you can chart
+    # between them.  Yppedia often lacks these edges.
+    #
+    foreach my $p ($widists->vertices) {
+       my ($ax,$ay) = $p =~ m/^(\d+)\,(\d+)$/ or die;
+       my $add_shortcut= sub {
+           my $q= sprintf "%d,%d", $ax+$_[0], $ay+$_[1];
+           return unless $widists->has_vertex($q);
+           return if $widists->has_edge($p,$q);
+           printf DEBUG "%-5s league-shortcut %-5s\n", $p, $q;
+           $widists->add_weighted_edge($p,$q,1);
+       };
+       $add_shortcut->( 2,0);
+       $add_shortcut->(+1,1);
+       $add_shortcut->(-1,1);
+    }
+}
+
 sub yppedia_graphs_prune_boring () {
     # Prune the LP database by eliminating boring intermediate vertices
     foreach my $delete ($widists->vertices()) {
@@ -262,8 +280,9 @@ sub yppedia_archs_fillbynearest() {
            next unless $ccs_useful[$targetccix];
            foreach my $target ($wiarchs->
                         connected_component_by_index($targetccix)) {
+               next unless $widists->has_vertex($target);
                foreach my $source (@sourcecc) {
-                   my $target_dist= $wialldists->path_length($target,$source);
+                   my $target_dist= widist($target,$source);
                    next unless defined $target_dist;
                    next if $target_dist >= $best_dist;
                    $best_dist= $target_dist;
@@ -289,6 +308,20 @@ sub yppedia_archs_fillbynearest() {
     }
 }
 
+sub yppedia_graphs_shortest_paths () {
+    $wialldists= $widists->APSP_Floyd_Warshall();
+}
+
+sub widist ($$) {
+    my ($p,$q) = @_;
+    my $pl= $wialldists->path_length($p,$q);
+#    die "$p $q" unless defined $pl;
+#    my @pv= $wialldists->path_vertices($p,$q);
+#    if (@pv == $pl) { return $pl; }
+#   printf DEBUG "%-5s PATHLENGTH %-5s pl=%s pv=%s\n", $p,$q,$pl,join('|',@pv);
+    return $pl;
+}
+                       
 sub winode2arch ($) {
     my ($node) = @_;
     my $ccix= $wiarchs->connected_component_by_vertex($node);
@@ -342,7 +375,7 @@ sub compare_distances () {
            my $nb= $wiisland2node{$ib};
            next unless defined $nb;
            my $dbdist= $dbdists->get_edge_weight($ia,$ib);
-           my $widist= $wialldists->path_length($na,$nb);
+           my $widist= widist($na,$nb);
            if (!defined $dbdist) {
                change(sprintf "define distance %2d for %s..%s",
                       $widist, $ia,$ib);
@@ -356,17 +389,22 @@ sub compare_distances () {
 
 parse_info_serverside();
 
+print "reading database\n";
+
 db_setocean($ocean);
 db_connect();
 database_fetch_ocean();
 
-yppedia_chart_parse();
-yppedia_graphs_prune_boring();
-yppedia_graphs_check();
-yppedia_archs_sourceinfo();
-$wialldists= $widists->APSP_Floyd_Warshall();
-yppedia_archs_chart_labels();
-yppedia_archs_fillbynearest();
+print "reading yppedia chart\n";          yppedia_chart_parse();
+print "adding shortcuts\n";               yppedia_graphs_add_shortcuts();
+print "pruning bording vertices\n";       yppedia_graphs_prune_boring();
+print "checking yppedia graphs\n";        yppedia_graphs_check();
+print "setting archs from source-info\n"; yppedia_archs_sourceinfo();
+print "computing shortest paths\n";       yppedia_graphs_shortest_paths();
+print "setting archs from labels\n";      yppedia_archs_chart_labels();
+print "setting archs from nearby\n";      yppedia_archs_fillbynearest();
+
+print "comparing\n";
 
 compare_island_lists();
 compare_distances();