Ruby勉強 -- 追記:統計的なアプローチ(のつもり)

最適解?何それ美味しいの?なコード
解を見つけたり見つけなかったりします。
探索を繰り返して良さそうな経路の評価を高くし、悪そうな経路の評価を低くしていきます。
探索は前回までの評価を元に行いますが、乱数によるフラつきをいれています。
評価、乱数パラメータのバランスで挙動が変わります。また局所解にトラップされると最短経路を見つけることができません。
いろんな代償を払いますがより一般的な問題へ適用可能なはず。(うっかりマヌケな解を出すのが人間ぽくていい)

# http://okajima.air-nifty.com/b/2010/01/post-abc6.html
class Maze
  @@directions  = [{'x'=>-1,'y'=>0},{'x'=>1,'y'=>0},{'x'=>0,'y'=>-1},{'x'=>0,'y'=>1}]
  @@trial_count = 1000
  @@swinging    = 1.0
  @@positive    = 1.05
  @@negative    = 0.99
  @@base        = 100.0
  def run
    load_map
    @@trial_count.times {|i|
      route = Array.new
      solve_map(@s['y'],@s['x'], 0, route)
    }
    if select_route(@g['y'],@g['x']) then @map.each{|line| print line.to_s + "\n" } else print "fail!\n" end
  end
  def load_map
    data = DATA.read 
    @map = []
    data.each_line {|line| @map.push line.chomp.split(//) }
    @cmap = []
    @map.each{|m| @cmap.push Array.new(m.size, @@base)}
    @map.each_with_index{|line,i| line.each_with_index{|c,j|
        @s = {'x'=>j, 'y'=>i} if c == 'S' 
        @g = {'x'=>j, 'y'=>i} if c == 'G' 
    }}
  end
  def solve_map(y,x,c,route)
    node = {'x'=>x,'y'=>y}
    # check goal
    if @map[y][x] == 'G'
      route.each_with_index{|node,i|
        @map[node['y']][node['x']] = ' '
        @cmap[node['y']][node['x']] *= @@positive*(1.0+1.0/(c*c))
      }
      return 
    end
    # new node
    if @map[y][x] == ' '
      @map[y][x] = '-' 
      route.push node
    end
    # check route
    walkable = false
    @@directions.each{|d| walkable |= @map[y+d['y']][x+d['x']] == ' '}
    if walkable then
      max_c = -10000.0
      ny=-1
      nx=-1
      @@directions.each{|d|
        rc = (rand(10000)/5000.0-1.0)*@@swinging
        if @cmap[y+d['y']][x+d['x']]+rc > max_c && (@map[y+d['y']][x+d['x']] == ' ' || @map[y+d['y']][x+d['x']] == 'G')
          max_c = @cmap[y+d['y']][x+d['x']]+rc 
          ny = y+d['y']
          nx = x+d['x']
        end
      }
      return solve_map(ny,nx,c+1,route) if nx != -1 && ny != -1
    else
      # abort
      route.each_with_index{|node,i|
        @map[node['y']][node['x']] = ' '
        @cmap[node['y']][node['x']] *= @@negative
      }
      return
    end
  end
  def select_route(y,x)
    @map[y][x] = '$' if @map[y][x] == ' '
    @@directions.each{|d| return true if @map[y+d['y']][x+d['x']] == 'S'}
    max_c = -10000.0;
    ny=-1
    nx=-1
    @@directions.each{|d|
      if (@cmap[y+d['y']][x+d['x']] > max_c && @map[y+d['y']][x+d['x']] == ' ')
         max_c = @cmap[y+d['y']][x+d['x']]
         ny = y+d['y']
         nx = x+d['x']
      end
    }
    return select_route(ny,nx)  if nx != -1 && ny != -1
    return false
  end
end
maze = Maze.new
maze.run
__END__
**************************
*S* *                    *
* * *  *  *************  *
* *   *    ************  *
*    *                   *
************** ***********
*                        *
** ***********************
*      *              G  *
*  *      *********** *  *
*    *        ******* *  *
*       *                *
**************************