Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/Random/SRand48.cs @ 15454

Last change on this file since 15454 was 15454, checked in by rhanghof, 6 years ago

#2817

  • Extreme point bin packing does not need the occupation layer anymore
  • Changes at the fitting algorithm. Now they are packing the items as in the paper of S. Martello, D. Pisinger, D. Vigo described
File size: 5.2 KB
Line 
1/*
2 * C# port of the implementation of the srand48 random generator.
3 * First implemented in test3dbpp.c by S. Martello, D. Pisinger, D. Vigo, E. den Boef, J. Korst (2003)
4 */
5using HeuristicLab.Core;
6using System;
7using HeuristicLab.Common;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9
10namespace HeuristicLab.Problems.BinPacking.Random {
11
12  [Item("SRand", "A pseudo random number generator which creates uniformly distributed random numbers.")]
13  [StorableClass]
14  public sealed class SRand48 : Item, IRandom {
15    private object locker = new object();
16
17    [Storable]
18    private bool init = false;
19    [Storable]
20    private uint _h48;
21    [Storable]
22    private uint _l48;
23   
24
25    /// <summary>
26    /// Used by HeuristicLab.Persistence to initialize new instances during deserialization.
27    /// </summary>
28    /// <param name="deserializing">true, if the constructor is called during deserialization.</param>
29    [StorableConstructor]
30    private SRand48(bool deserializing) : base(deserializing) { }
31
32    /// <summary>
33    /// Initializes a new instance from an existing one (copy constructor).
34    /// </summary>
35    /// <param name="original">The original <see cref="SRand48"/> instance which is used to initialize the new instance.</param>
36    /// <param name="cloner">A <see cref="Cloner"/> which is used to track all already cloned objects in order to avoid cycles.</param>
37    private SRand48(SRand48 original, Cloner cloner)
38      : base(original, cloner) {
39      _h48 = original._h48;
40      _l48 = original._l48;
41      init = original.init;
42    }
43
44
45    /// <summary>
46    /// Initializes a new instance of <see cref="SRand48"/>.
47    /// </summary>
48    public SRand48() {
49      if (!init) {
50        Seed((uint)DateTime.Now.Ticks);
51        init = true;
52      }
53    }
54
55    /// <summary>
56    /// Initializes a new instance of <see cref="SRand48"/>
57    /// with the given seed <paramref name="seed"/>.
58    /// </summary>
59    /// <param name="seed">The seed with which to initialize the random number generator.</param>
60    public SRand48(uint seed) {
61      if (!init) {
62        Seed(seed);
63        init = true;
64      }
65    }
66
67    /// <summary>
68    /// Clones the current instance (deep clone).
69    /// </summary>
70    /// <param name="cloner">Dictionary of all already cloned objects. (Needed to avoid cycles.)</param>
71    /// <returns>The cloned object as <see cref="SRand48"/>.</returns>
72    public override IDeepCloneable Clone(Cloner cloner) {
73      return new SRand48(this, cloner);
74    }
75
76    /// <summary>
77    /// Gets a new random number.
78    /// </summary>
79    /// <returns>A new int random number.</returns>
80    public int Next() {
81      lock (locker) {
82        return (int)LRand48x();
83      }
84    }
85
86    /// <summary>
87    /// Gets a new random number being smaller than the given <paramref name="maxVal"/>.
88    /// </summary>
89    /// <exception cref="ArgumentException">Thrown when the given maximum value is
90    /// smaller or equal to zero.</exception>
91    /// <param name="maxVal">The maximum value of the generated random number.</param>
92    /// <returns>A new int random number.</returns>
93    public int Next(int maxVal) {
94      lock (locker) {
95        if (maxVal <= 0)
96          throw new ArgumentException("The interval [0, " + maxVal + ") is empty");
97        return (int)(LRand48x() % maxVal);
98      }
99    }
100
101    /// <summary>
102    /// Gets a new random number being in the given interval <paramref name="minVal"/> and
103    /// <paramref name="maxVal"/>.
104    /// </summary>
105    /// <param name="minVal">The minimum value of the generated random number.</param>
106    /// <param name="maxVal">The maximum value of the generated random number.</param>
107    /// <returns>A new int random number.</returns>
108    public int Next(int minVal, int maxVal) {
109      lock (locker) {
110        if (maxVal <= minVal)
111          throw new ArgumentException("The interval [" + minVal + ", " + maxVal + ") is empty");
112        return Next(maxVal - minVal + 1) + minVal;
113      }
114    }
115
116    /// <summary>
117    /// Gets a new double random variable.
118    /// </summary>
119    /// <returns></returns>
120    public double NextDouble() {
121      lock (locker) {
122        return ((double)Next()) * (1.0 / 4294967296.0);
123      }
124    }
125
126    /// <summary>
127    /// Resets the current random number generator.
128    /// </summary>
129    public void Reset() {
130      lock (locker) {
131        Seed((uint)DateTime.Now.Ticks);
132      }
133    }
134
135    /// <summary>
136    /// Resets the current random number generator with the given seed <paramref name="s"/>.
137    /// </summary>
138    /// <param name="seed">The seed with which to reset the current instance.</param>
139    public void Reset(int seed) {
140      lock (locker) {
141        Seed((uint)seed);
142      }
143    }
144
145    /// <summary>
146    /// Initializes current instance with random seed.
147    /// </summary>
148    /// <param name="seed">A starting seed.</param>
149    private void Seed(uint seed) {
150      _h48 = seed;
151      _l48 = 0x330E;
152    }
153
154    private int LRand48x() {
155      _h48 = (_h48 * 0xDEECE66D) + (_l48 * 0x5DEEC);
156      _l48 = _l48 * 0xE66D + 0xB;
157      _h48 = _h48 + (_l48 >> 16);
158      _l48 = _l48 & 0xFFFF;
159      return (int)(_h48 >> 1);
160    }
161   
162  }
163}
Note: See TracBrowser for help on using the repository browser.