test/heap_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 702 bdc7dfc8c054
child 948 f9e3f73e17f1
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

These two heuristics are similar, but the newer one is faster
and not only makes it possible to skip some epsilon phases, but
it can improve the performance of the other phases, as well.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@100
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@100
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
alpar@100
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@100
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@100
     8
 *
alpar@100
     9
 * Permission to use, modify and distribute this software is granted
alpar@100
    10
 * provided that this copyright notice appears in all copies. For
alpar@100
    11
 * precise terms see the accompanying LICENSE file.
alpar@100
    12
 *
alpar@100
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@100
    14
 * express or implied, and with no claim as to its suitability for any
alpar@100
    15
 * purpose.
alpar@100
    16
 *
alpar@100
    17
 */
alpar@100
    18
alpar@100
    19
#include <iostream>
alpar@100
    20
#include <fstream>
alpar@100
    21
#include <string>
alpar@100
    22
#include <vector>
alpar@100
    23
alpar@100
    24
#include <lemon/concept_check.h>
alpar@100
    25
#include <lemon/concepts/heap.h>
alpar@100
    26
deba@203
    27
#include <lemon/smart_graph.h>
deba@203
    28
#include <lemon/lgf_reader.h>
deba@203
    29
#include <lemon/dijkstra.h>
deba@203
    30
#include <lemon/maps.h>
alpar@100
    31
alpar@100
    32
#include <lemon/bin_heap.h>
kpeter@855
    33
#include <lemon/quad_heap.h>
kpeter@855
    34
#include <lemon/dheap.h>
deba@681
    35
#include <lemon/fib_heap.h>
kpeter@701
    36
#include <lemon/pairing_heap.h>
deba@681
    37
#include <lemon/radix_heap.h>
kpeter@855
    38
#include <lemon/binomial_heap.h>
deba@681
    39
#include <lemon/bucket_heap.h>
alpar@100
    40
alpar@100
    41
#include "test_tools.h"
alpar@100
    42
alpar@100
    43
using namespace lemon;
alpar@100
    44
using namespace lemon::concepts;
alpar@100
    45
deba@203
    46
typedef ListDigraph Digraph;
deba@203
    47
DIGRAPH_TYPEDEFS(Digraph);
deba@203
    48
alpar@209
    49
char test_lgf[] =
alpar@209
    50
  "@nodes\n"
alpar@209
    51
  "label\n"
alpar@209
    52
  "0\n"
alpar@209
    53
  "1\n"
alpar@209
    54
  "2\n"
alpar@209
    55
  "3\n"
alpar@209
    56
  "4\n"
alpar@209
    57
  "5\n"
alpar@209
    58
  "6\n"
alpar@209
    59
  "7\n"
alpar@209
    60
  "8\n"
alpar@209
    61
  "9\n"
alpar@209
    62
  "@arcs\n"
kpeter@212
    63
  "                label   capacity\n"
kpeter@212
    64
  "0       5       0       94\n"
kpeter@212
    65
  "3       9       1       11\n"
kpeter@212
    66
  "8       7       2       83\n"
kpeter@212
    67
  "1       2       3       94\n"
kpeter@212
    68
  "5       7       4       35\n"
kpeter@212
    69
  "7       4       5       84\n"
kpeter@212
    70
  "9       5       6       38\n"
kpeter@212
    71
  "0       4       7       96\n"
kpeter@212
    72
  "6       7       8       6\n"
kpeter@212
    73
  "3       1       9       27\n"
kpeter@212
    74
  "5       2       10      77\n"
kpeter@212
    75
  "5       6       11      69\n"
kpeter@212
    76
  "6       5       12      41\n"
kpeter@212
    77
  "4       6       13      70\n"
kpeter@212
    78
  "3       2       14      45\n"
kpeter@212
    79
  "7       9       15      93\n"
kpeter@212
    80
  "5       9       16      50\n"
kpeter@212
    81
  "9       0       17      94\n"
kpeter@212
    82
  "9       6       18      67\n"
kpeter@212
    83
  "0       9       19      86\n"
alpar@209
    84
  "@attributes\n"
deba@203
    85
  "source 3\n";
deba@203
    86
deba@203
    87
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
deba@203
    88
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
deba@203
    89
deba@203
    90
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
deba@203
    91
deba@203
    92
template <typename Heap>
deba@203
    93
void heapSortTest() {
deba@203
    94
  RangeMap<int> map(test_len, -1);
deba@203
    95
  Heap heap(map);
alpar@209
    96
deba@203
    97
  std::vector<int> v(test_len);
deba@203
    98
  for (int i = 0; i < test_len; ++i) {
deba@203
    99
    v[i] = test_seq[i];
deba@203
   100
    heap.push(i, v[i]);
deba@203
   101
  }
deba@203
   102
  std::sort(v.begin(), v.end());
deba@203
   103
  for (int i = 0; i < test_len; ++i) {
kpeter@701
   104
    check(v[i] == heap.prio(), "Wrong order in heap sort.");
deba@203
   105
    heap.pop();
deba@203
   106
  }
deba@203
   107
}
deba@203
   108
deba@203
   109
template <typename Heap>
deba@203
   110
void heapIncreaseTest() {
deba@203
   111
  RangeMap<int> map(test_len, -1);
deba@203
   112
deba@203
   113
  Heap heap(map);
alpar@209
   114
deba@203
   115
  std::vector<int> v(test_len);
deba@203
   116
  for (int i = 0; i < test_len; ++i) {
deba@203
   117
    v[i] = test_seq[i];
deba@203
   118
    heap.push(i, v[i]);
deba@203
   119
  }
deba@203
   120
  for (int i = 0; i < test_len; ++i) {
deba@203
   121
    v[i] += test_inc[i];
deba@203
   122
    heap.increase(i, v[i]);
deba@203
   123
  }
deba@203
   124
  std::sort(v.begin(), v.end());
deba@203
   125
  for (int i = 0; i < test_len; ++i) {
kpeter@701
   126
    check(v[i] == heap.prio(), "Wrong order in heap increase test.");
deba@203
   127
    heap.pop();
deba@203
   128
  }
deba@203
   129
}
deba@203
   130
deba@203
   131
template <typename Heap>
alpar@209
   132
void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
alpar@209
   133
                      Node source) {
alpar@209
   134
kpeter@257
   135
  typename Dijkstra<Digraph, IntArcMap>::template SetStandardHeap<Heap>::
deba@203
   136
    Create dijkstra(digraph, length);
deba@203
   137
deba@203
   138
  dijkstra.run(source);
deba@203
   139
deba@203
   140
  for(ArcIt a(digraph); a != INVALID; ++a) {
alpar@209
   141
    Node s = digraph.source(a);
deba@203
   142
    Node t = digraph.target(a);
deba@203
   143
    if (dijkstra.reached(s)) {
deba@203
   144
      check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
kpeter@701
   145
             "Error in shortest path tree.");
deba@203
   146
    }
deba@203
   147
  }
deba@203
   148
deba@203
   149
  for(NodeIt n(digraph); n != INVALID; ++n) {
deba@203
   150
    if ( dijkstra.reached(n) && dijkstra.predArc(n) != INVALID ) {
deba@203
   151
      Arc a = dijkstra.predArc(n);
deba@203
   152
      Node s = digraph.source(a);
deba@203
   153
      check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
kpeter@701
   154
             "Error in shortest path tree.");
deba@203
   155
    }
deba@203
   156
  }
deba@203
   157
deba@203
   158
}
deba@203
   159
alpar@100
   160
int main() {
alpar@100
   161
alpar@100
   162
  typedef int Item;
alpar@100
   163
  typedef int Prio;
deba@203
   164
  typedef RangeMap<int> ItemIntMap;
alpar@209
   165
deba@203
   166
  Digraph digraph;
deba@203
   167
  IntArcMap length(digraph);
deba@203
   168
  Node source;
alpar@100
   169
deba@203
   170
  std::istringstream input(test_lgf);
kpeter@293
   171
  digraphReader(digraph, input).
deba@203
   172
    arcMap("capacity", length).
deba@203
   173
    node("source", source).
alpar@209
   174
    run();
alpar@209
   175
kpeter@701
   176
  // BinHeap
alpar@100
   177
  {
alpar@100
   178
    typedef BinHeap<Prio, ItemIntMap> IntHeap;
alpar@100
   179
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
deba@203
   180
    heapSortTest<IntHeap>();
deba@203
   181
    heapIncreaseTest<IntHeap>();
alpar@209
   182
deba@203
   183
    typedef BinHeap<Prio, IntNodeMap > NodeHeap;
deba@203
   184
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
deba@203
   185
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
alpar@100
   186
  }
alpar@100
   187
kpeter@855
   188
  // QuadHeap
kpeter@701
   189
  {
kpeter@855
   190
    typedef QuadHeap<Prio, ItemIntMap> IntHeap;
kpeter@701
   191
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
kpeter@701
   192
    heapSortTest<IntHeap>();
kpeter@701
   193
    heapIncreaseTest<IntHeap>();
kpeter@701
   194
kpeter@855
   195
    typedef QuadHeap<Prio, IntNodeMap > NodeHeap;
kpeter@701
   196
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
kpeter@701
   197
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
kpeter@701
   198
  }
kpeter@701
   199
kpeter@855
   200
  // DHeap
kpeter@701
   201
  {
kpeter@855
   202
    typedef DHeap<Prio, ItemIntMap> IntHeap;
kpeter@701
   203
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
kpeter@701
   204
    heapSortTest<IntHeap>();
kpeter@701
   205
    heapIncreaseTest<IntHeap>();
kpeter@701
   206
kpeter@855
   207
    typedef DHeap<Prio, IntNodeMap > NodeHeap;
kpeter@701
   208
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
kpeter@701
   209
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
kpeter@701
   210
  }
kpeter@701
   211
kpeter@701
   212
  // FibHeap
deba@681
   213
  {
deba@681
   214
    typedef FibHeap<Prio, ItemIntMap> IntHeap;
deba@681
   215
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
deba@681
   216
    heapSortTest<IntHeap>();
deba@681
   217
    heapIncreaseTest<IntHeap>();
deba@681
   218
deba@681
   219
    typedef FibHeap<Prio, IntNodeMap > NodeHeap;
deba@681
   220
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
deba@681
   221
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
deba@681
   222
  }
deba@681
   223
kpeter@701
   224
  // PairingHeap
kpeter@702
   225
  {
kpeter@702
   226
    typedef PairingHeap<Prio, ItemIntMap> IntHeap;
kpeter@702
   227
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
kpeter@702
   228
    heapSortTest<IntHeap>();
kpeter@702
   229
    heapIncreaseTest<IntHeap>();
kpeter@702
   230
kpeter@702
   231
    typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
kpeter@702
   232
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
kpeter@702
   233
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
kpeter@702
   234
  }
kpeter@701
   235
kpeter@701
   236
  // RadixHeap
deba@681
   237
  {
deba@681
   238
    typedef RadixHeap<ItemIntMap> IntHeap;
deba@681
   239
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
deba@681
   240
    heapSortTest<IntHeap>();
deba@681
   241
    heapIncreaseTest<IntHeap>();
deba@681
   242
deba@681
   243
    typedef RadixHeap<IntNodeMap > NodeHeap;
deba@681
   244
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
deba@681
   245
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
deba@681
   246
  }
deba@681
   247
kpeter@855
   248
  // BinomialHeap
kpeter@701
   249
  {
kpeter@855
   250
    typedef BinomialHeap<Prio, ItemIntMap> IntHeap;
kpeter@701
   251
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
kpeter@701
   252
    heapSortTest<IntHeap>();
kpeter@701
   253
    heapIncreaseTest<IntHeap>();
kpeter@701
   254
kpeter@855
   255
    typedef BinomialHeap<Prio, IntNodeMap > NodeHeap;
kpeter@701
   256
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
kpeter@701
   257
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
kpeter@701
   258
  }
kpeter@701
   259
kpeter@701
   260
  // BucketHeap, SimpleBucketHeap
deba@681
   261
  {
deba@681
   262
    typedef BucketHeap<ItemIntMap> IntHeap;
deba@681
   263
    checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
deba@681
   264
    heapSortTest<IntHeap>();
deba@681
   265
    heapIncreaseTest<IntHeap>();
deba@681
   266
deba@681
   267
    typedef BucketHeap<IntNodeMap > NodeHeap;
deba@681
   268
    checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
deba@681
   269
    dijkstraHeapTest<NodeHeap>(digraph, length, source);
kpeter@701
   270
kpeter@701
   271
    typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
kpeter@701
   272
    heapSortTest<SimpleIntHeap>();
deba@681
   273
  }
deba@681
   274
alpar@100
   275
  return 0;
alpar@100
   276
}