Advertisement
Guest User

Random Walk

a guest
Jan 19th, 2013
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 5.45 KB | None | 0 0
  1. using GLib;
  2. using Gee;
  3.  
  4. class CoordinateSystem : Object {
  5.     internal uint[] shape;
  6.    
  7.     public CoordinateSystem (uint[] shape)
  8.         requires (this.is_valid_shape (shape))
  9.     {
  10.         this.shape = shape;
  11.     }
  12.    
  13.     static inline bool is_valid_shape (uint[] shape) {
  14.         foreach (var n in shape) {
  15.             if (n < 0) return false;
  16.         }
  17.         return shape.length != 0;
  18.     }
  19.    
  20.     public inline uint dimensions {
  21.         get { return this.shape.length; }
  22.     }
  23.    
  24.     public uint size {
  25.         get {
  26.             uint result = 1;
  27.             foreach (var v in this.shape) {
  28.                 result *= v;
  29.             }
  30.             return result;
  31.         }
  32.     }
  33.    
  34.     public bool is_valid_coordinates(uint[] values) {
  35.         if (values.length == this.dimensions) {
  36.             for (var i = 0; i < values.length; ++i) {
  37.                 if (values[i] < 0 || values[i] >= this.shape[i]) return false;
  38.             }
  39.             return true;
  40.         } else {
  41.             return false;
  42.         }
  43.     }
  44.    
  45.     public new Coordinate get (uint index)
  46.         requires (index >= 0)
  47.     {
  48.         var result = new uint[this.shape.length];
  49.         for (int i = 0; i < this.shape.length; ++i) {
  50.             result[i] = index % this.shape[i];
  51.             index /= this.shape[i];
  52.         }
  53.         assert (index == 0);
  54.         return new Coordinate (this, result);
  55.     }
  56.    
  57.     public Coordinate[] get_sample (uint count)
  58.         requires (count <= this.size)
  59.     {
  60.         var result = new Coordinate[count];
  61.         var selected = new HashSet<uint> ();
  62.         uint j = 0;
  63.        
  64.         for (var i = 0; i < count; ++i) {
  65.             do {
  66.                 j = Random.int_range (0, (int32) this.size);
  67.             } while (j in selected);
  68.             selected.add (j);
  69.             result[i] = this[j];
  70.         }
  71.         return result;
  72.     }
  73. }
  74.  
  75. class Coordinate : Object {
  76.     CoordinateSystem coordinate_system;
  77.     uint[] coordinates;
  78.    
  79.     public Coordinate (CoordinateSystem coordinate_system, uint[] coordinates)
  80.         requires (coordinate_system.is_valid_coordinates (coordinates))
  81.     {
  82.         this.coordinate_system = coordinate_system;
  83.         this.coordinates = coordinates;
  84.     }
  85.    
  86.     public inline int dimensions {
  87.         get { return this.coordinates.length; }
  88.     }
  89.    
  90.     public bool equals(Coordinate other) {
  91.         if (this.coordinates.length == other.coordinates.length) {
  92.             for (var i = 0; i < this.coordinates.length; ++i) {
  93.                 if (this.coordinates[i] != other.coordinates[i]) return false;
  94.             }
  95.             return true;
  96.         } else {
  97.             return false;
  98.         }
  99.     }
  100.    
  101.     public uint hash () {
  102.         uint x = 0x345678, mult = 100003;
  103.         for (var i = 0; i < this.coordinates.length; ++i) {
  104.             x = (x ^ this.coordinates[i]) * mult;
  105.             mult += 82520 + 2 * i;
  106.         }
  107.         return x + 97531;
  108.     }
  109.    
  110.     public void move(int[] delta)
  111.         requires (delta.length == this.dimensions)
  112.     {
  113.         for (var i = 0; i < delta.length; ++i) {
  114.             this.coordinates[i] =
  115.                 (this.coordinates[i] + delta[i])
  116.                     % this.coordinate_system.shape[i];
  117.         }
  118.     }
  119. }
  120.  
  121. class Walker : Object {
  122.     public Coordinate coordinate;
  123.     public uint id;
  124.    
  125.     public Walker (Coordinate coordinate, uint id) {
  126.         this.coordinate = coordinate;
  127.         this.id = id;
  128.     }
  129.    
  130.     public void random_move() {
  131.         var delta = new int[this.coordinate.dimensions];
  132.         delta[Random.int_range (0, this.coordinate.dimensions)] =
  133.             Random.boolean () ? -1 : 1;
  134.         this.coordinate.move(delta);
  135.     }
  136. }
  137.  
  138.  
  139. class Simulation : Object {
  140.     Walker[] walkers;
  141.    
  142.     public Simulation (Walker[] walkers) {
  143.         this.walkers = walkers;
  144.     }
  145.    
  146.     public Simulation.with_randomly_placed_walkers (
  147.         CoordinateSystem coordinate_system, uint count
  148.     ) {
  149.         var walkers = new Walker[count];
  150.         var coordinates = coordinate_system.get_sample (count);
  151.         for (var i = 0; i < count; ++i) {
  152.             walkers[i] = new Walker(coordinates[i], i);
  153.         }
  154.         this (walkers);
  155.     }
  156.    
  157.     public uint size {
  158.         get { return this.walkers.length; }
  159.     }
  160.    
  161.     public void step () {
  162.         var coordinate2walkers = new HashMap<Coordinate, ArrayList<Walker> > (
  163.             Coordinate.hash, (EqualFunc) Coordinate.equals);
  164.         foreach (var walker in this.walkers) {
  165.             walker.random_move();
  166.            
  167.             var walkers = coordinate2walkers[walker.coordinate];
  168.             if (walkers == null) {
  169.                 walkers = new ArrayList<Walker> ();
  170.                 coordinate2walkers[walker.coordinate] = walkers;
  171.             }
  172.             walkers.add (walker);
  173.         }
  174.         var i = 0;
  175.         foreach (var walkers in coordinate2walkers.values) {
  176.             if (walkers.size == 1) {
  177.                 this.walkers[i++] = walkers.first ();
  178.             }
  179.         }
  180.         this.walkers.resize (i);
  181.     }
  182. }
  183.  
  184. static int main (string[] args) {
  185.     var simulation = new Simulation.with_randomly_placed_walkers (
  186.         new CoordinateSystem ({100, 100}), 500);
  187.     for (var i = 0; i < 100; ++i) {
  188.         simulation.step ();
  189.         stdout.printf ("%u walkers left in step %d\n", simulation.size, i);
  190.         if (simulation.size <= 1) break;
  191.     }
  192.     return 0;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement