Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/graph/test/relaxed_heap_test.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 6.8 KB
Line 
1// Copyright 2004 The Trustees of Indiana University.
2
3// Use, modification and distribution is subject to the Boost Software
4// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7//  Authors: Douglas Gregor
8//           Andrew Lumsdaine
9#ifndef BOOST_RELAXED_HEAP_DEBUG
10#  define BOOST_RELAXED_HEAP_DEBUG 0
11#endif
12
13#include <boost/pending/relaxed_heap.hpp>
14#include <boost/test/minimal.hpp>
15#include <utility>
16#include <iostream>
17#include <vector>
18#include <boost/optional.hpp>
19#include <boost/random.hpp>
20#include <boost/lexical_cast.hpp>
21#include <boost/progress.hpp>
22
23typedef std::vector<boost::optional<double> > values_type;
24values_type values;
25
26struct less_extvalue
27{
28  typedef bool result_type;
29
30  bool operator()(unsigned x, unsigned y) const
31  {
32    assert(values[x] && values[y]);
33    return values[x] < values[y];
34  }
35};
36
37using namespace std;
38
39boost::optional<double> get_min_value()
40{
41  boost::optional<double> min_value;
42  for (unsigned i = 0; i < values.size(); ++i) {
43    if (values[i]) {
44      if (!min_value || *values[i] < *min_value) min_value = values[i];
45    }
46  }
47  return min_value;
48}
49
50void interactive_test()
51{
52  unsigned max_values;
53  cout << "Enter max number of values in the heap> ";
54  cin >> max_values;
55
56  values.resize(max_values);
57  boost::relaxed_heap<unsigned, less_extvalue> heap(max_values);
58
59  char option;
60  do {
61    cout << "Enter command> ";
62    if (cin >> option) {
63      switch (option) {
64      case 'i': case 'I':
65        {
66          unsigned index;
67          double value;
68          if (cin >> index >> value) {
69            if (index >= values.size()) cout << "Index out of range.\n";
70            else if (values[index]) cout << "Already in queue.\n";
71            else {
72              values[index] = value;
73              heap.push(index);
74              heap.dump_tree();
75            }
76          }
77        }
78        break;
79
80      case 'u': case 'U':
81        {
82          unsigned index;
83          double value;
84          if (cin >> index >> value) {
85            if (index >= values.size()) cout << "Index out of range.\n";
86            else if (!values[index]) cout << "Not in queue.\n";
87            else {
88              values[index] = value;
89              heap.update(index);
90              heap.dump_tree();
91            }
92          }
93        }
94        break;
95
96      case 'r': case 'R':
97        {
98          unsigned index;
99          if (cin >> index) {
100            if (index >= values.size()) cout << "Index out of range.\n";
101            else if (!values[index]) cout << "Not in queue.\n";
102            else {
103              heap.remove(index);
104              heap.dump_tree();
105            }
106          }
107        }
108        break;
109
110      case 't': case 'T':
111        {
112          if (boost::optional<double> min_value = get_min_value()) {
113            cout << "Top value is (" << heap.top() << ", "
114                 << *values[heap.top()] << ").\n";
115            BOOST_CHECK(*min_value == *values[heap.top()]);
116          } else {
117            cout << "Queue is empty.\n";
118            BOOST_CHECK(heap.empty());
119          }
120        }
121        break;
122
123      case 'd': case 'D':
124        {
125          if (boost::optional<double> min_value = get_min_value()) {
126            unsigned victim = heap.top();
127            double value = *values[victim];
128            cout << "Removed top value (" << victim << ", " << value << ")\n";
129            BOOST_CHECK(*min_value == value);
130
131            heap.pop();
132            heap.dump_tree();
133            values[victim].reset();
134          } else {
135            cout << "Queue is empty.\n";
136            BOOST_CHECK(heap.empty());
137          }
138        }
139        break;
140
141      case 'q': case 'Q':
142        break;
143
144      default:
145        cout << "Unknown command '" << option << "'.\n";
146      }
147    }
148  } while (cin && option != 'q' && option != 'Q');
149}
150
151void random_test(int n, int iterations, int seed)
152{
153  values.resize(n);
154  boost::relaxed_heap<unsigned, less_extvalue> heap(n);
155  boost::minstd_rand gen(seed);
156  boost::uniform_int<unsigned> rand_index(0, n-1);
157  boost::uniform_real<> rand_value(-1000.0, 1000.0);
158  boost::uniform_int<unsigned> which_option(0, 3);
159
160  cout << n << std::endl;
161
162#if BOOST_RELAXED_HEAP_DEBUG > 1
163  heap.dump_tree();
164#endif
165
166  BOOST_REQUIRE(heap.valid());
167
168#if BOOST_RELAXED_HEAP_DEBUG == 0
169  boost::progress_display progress(iterations);
170#endif
171
172  for (int iteration = 0; iteration < iterations; ++iteration) {
173#if BOOST_RELAXED_HEAP_DEBUG > 1
174    std::cout << "Iteration #" << iteration << std::endl;
175#endif
176    unsigned victim = rand_index(gen);
177    if (values[victim]) {
178      switch (which_option(gen)) {
179      case 0: case 3:
180        {
181          // Update with a smaller weight
182          boost::uniform_real<> rand_smaller((rand_value.min)(), *values[victim]);
183          values[victim] = rand_smaller(gen);
184          assert(*values[victim] >= (rand_smaller.min)());
185          assert(*values[victim] <= (rand_smaller.max)());
186
187#if BOOST_RELAXED_HEAP_DEBUG > 0
188          cout << "u " << victim << " " << *values[victim] << std::endl;
189          cout.flush();
190#endif
191          heap.update(victim);
192        }
193        break;
194
195      case 1:
196        {
197          // Delete minimum value in the queue.
198          victim = heap.top();
199          double top_value = *values[victim];
200          BOOST_CHECK(*get_min_value() == top_value);
201          if (*get_min_value() != top_value) return;
202#if BOOST_RELAXED_HEAP_DEBUG > 0
203          cout << "d" << std::endl;
204          cout.flush();
205#endif
206          heap.pop();
207          values[victim].reset();
208#if BOOST_RELAXED_HEAP_DEBUG > 1
209          cout << "(Removed " << victim << ")\n";
210#endif // BOOST_RELAXED_HEAP_DEBUG > 1
211        }
212        break;
213
214      case 2:
215        {
216          // Just remove this value from the queue completely
217          values[victim].reset();
218#if BOOST_RELAXED_HEAP_DEBUG > 0
219          cout << "r " << victim << std::endl;
220          cout.flush();
221#endif
222          heap.remove(victim);
223        }
224        break;
225
226      default:
227        cout << "Random number generator failed." << endl;
228        BOOST_CHECK(false);
229        return;
230        break;
231      }
232    } else {
233      values[victim] = rand_value(gen);
234      assert(*values[victim] >= (rand_value.min)());
235      assert(*values[victim] <= (rand_value.max)());
236
237#if BOOST_RELAXED_HEAP_DEBUG > 0
238      cout << "i " << victim << " " << *values[victim] << std::endl;
239      cout.flush();
240#endif
241      heap.push(victim);
242    }
243
244#if BOOST_RELAXED_HEAP_DEBUG > 1
245    heap.dump_tree();
246#endif // BOOST_RELAXED_HEAP_DEBUG > 1
247
248    BOOST_REQUIRE(heap.valid());
249
250#if BOOST_RELAXED_HEAP_DEBUG == 0
251    ++progress;
252#endif
253  }
254}
255
256int test_main(int argc, char* argv[])
257{
258  if (argc >= 3) {
259    int n = boost::lexical_cast<int>(argv[1]);
260    int iterations = boost::lexical_cast<int>(argv[2]);
261    int seed = (argc >= 4? boost::lexical_cast<int>(argv[3]) : 1);
262    random_test(n, iterations, seed);
263  } else interactive_test();
264  return 0;
265}
Note: See TracBrowser for help on using the repository browser.