this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.org>
5 *
6 * Copyright:
7 * Christian Schulte, 2008
8 *
9 * This file is part of Gecode, the generic constraint
10 * development environment:
11 * http://www.gecode.org
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining
14 * a copy of this software and associated documentation files (the
15 * "Software"), to deal in the Software without restriction, including
16 * without limitation the rights to use, copy, modify, merge, publish,
17 * distribute, sublicense, and/or sell copies of the Software, and to
18 * permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 *
32 */
33
34#include <ctime>
35
36namespace Gecode {
37
38 /**
39 * \brief Random number generator
40 * \ingroup TaskModel
41 */
42 class Rnd : public SharedHandle {
43 private:
44 /// Implementation of generator
45 class IMP : public SharedHandle::Object {
46 protected:
47 /// Mutex for locking
48 GECODE_KERNEL_EXPORT static Support::Mutex m;
49 /// The actual generator
50 Support::RandomGenerator rg;
51 public:
52 /// Initialize generator with seed \a s
53 IMP(unsigned int s);
54 /// Return seed
55 unsigned int seed(void) const;
56 /// Set seed to \a s
57 void seed(unsigned int s);
58 /// Returns a random integer from the interval \f$[0\ldots n)\f$
59 unsigned int operator ()(unsigned int n);
60 /// Returns a random integer from the interval \f$[0\ldots n)\f$
61 int operator ()(int n);
62 /// Returns a random integer from the interval \f$[0\ldots n)\f$
63 unsigned long long int operator ()(unsigned long long int n);
64 /// Returns a random integer from the interval \f$[0\ldots n)\f$
65 long long int operator ()(long long int n);
66 /// Delete implemenentation
67 virtual ~IMP(void);
68 };
69 /// Set the current seed to \a s (initializes if needed)
70 void _seed(unsigned int s);
71 public:
72 /// Default constructor that does not initialize the generator
73 GECODE_KERNEL_EXPORT
74 Rnd(void);
75 /// Initialize from generator \a r
76 GECODE_KERNEL_EXPORT
77 Rnd(const Rnd& r);
78 /// Assignment operator
79 GECODE_KERNEL_EXPORT
80 Rnd& operator =(const Rnd& r);
81 /// Destructor
82 GECODE_KERNEL_EXPORT
83 ~Rnd(void);
84 /// Initialize with seed \a s
85 GECODE_KERNEL_EXPORT
86 Rnd(unsigned int s);
87 /// Set the current seed to \a s (initializes if needed)
88 GECODE_KERNEL_EXPORT
89 void seed(unsigned int s);
90 /// Set current seed based on time (initializes if needed)
91 GECODE_KERNEL_EXPORT
92 void time(void);
93 /// Set current seed to hardware-based random number (initializes if needed)
94 GECODE_KERNEL_EXPORT
95 void hw(void);
96 /// Return current seed
97 unsigned int seed(void) const;
98 /// Returns a random integer from the interval \f$[0\ldots n)\f$
99 unsigned int operator ()(unsigned int n);
100 /// Returns a random integer from the interval \f$[0\ldots n)\f$
101 int operator ()(int n);
102 /// Returns a random integer from the interval \f$[0\ldots n)\f$
103 unsigned long long int operator ()(unsigned long long int n);
104 /// Returns a random integer from the interval \f$[0\ldots n)\f$
105 long long int operator ()(long long int n);
106 };
107
108 forceinline unsigned int
109 Rnd::IMP::seed(void) const {
110 unsigned int s;
111 const_cast<Rnd::IMP&>(*this).m.acquire();
112 s = rg.seed();
113 const_cast<Rnd::IMP&>(*this).m.release();
114 return s;
115 }
116 forceinline void
117 Rnd::IMP::seed(unsigned int s) {
118 m.acquire();
119 rg.seed(s);
120 m.release();
121 }
122 forceinline unsigned int
123 Rnd::IMP::operator ()(unsigned int n) {
124 unsigned int r;
125 m.acquire();
126 r=rg(n);
127 m.release();
128 return r;
129 }
130 forceinline int
131 Rnd::IMP::operator ()(int n) {
132 int r;
133 m.acquire();
134 r=rg(n);
135 m.release();
136 return r;
137 }
138 forceinline unsigned long long int
139 Rnd::IMP::operator ()(unsigned long long int n) {
140 unsigned long long int r;
141 m.acquire();
142 r=rg(n);
143 m.release();
144 return r;
145 }
146 forceinline long long int
147 Rnd::IMP::operator ()(long long int n) {
148 long long int r;
149 m.acquire();
150 r=rg(n);
151 m.release();
152 return r;
153 }
154
155 forceinline unsigned int
156 Rnd::seed(void) const {
157 const IMP* i = static_cast<const IMP*>(object());
158 return i->seed();
159 }
160 forceinline unsigned int
161 Rnd::operator ()(unsigned int n) {
162 IMP* i = static_cast<IMP*>(object());
163 return (*i)(n);
164 }
165 forceinline int
166 Rnd::operator ()(int n) {
167 IMP* i = static_cast<IMP*>(object());
168 return (*i)(n);
169 }
170 forceinline unsigned long long int
171 Rnd::operator ()(unsigned long long int n) {
172 IMP* i = static_cast<IMP*>(object());
173 return (*i)(n);
174 }
175 forceinline long long int
176 Rnd::operator ()(long long int n) {
177 IMP* i = static_cast<IMP*>(object());
178 return (*i)(n);
179 }
180
181}
182
183// STATISTICS: kernel-other