test/dijkstra_test.cc
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 732 bb70ad62c95f
parent 440 88ed40ad0d4f
child 761 f1398882a928
child 796 7e368d9b67f7
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@170
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@170
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
kpeter@170
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@170
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@170
     8
 *
kpeter@170
     9
 * Permission to use, modify and distribute this software is granted
kpeter@170
    10
 * provided that this copyright notice appears in all copies. For
kpeter@170
    11
 * precise terms see the accompanying LICENSE file.
kpeter@170
    12
 *
kpeter@170
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@170
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@170
    15
 * purpose.
kpeter@170
    16
 *
kpeter@170
    17
 */
kpeter@170
    18
kpeter@170
    19
#include <lemon/concepts/digraph.h>
kpeter@170
    20
#include <lemon/smart_graph.h>
kpeter@170
    21
#include <lemon/list_graph.h>
deba@228
    22
#include <lemon/lgf_reader.h>
kpeter@170
    23
#include <lemon/dijkstra.h>
kpeter@170
    24
#include <lemon/path.h>
kpeter@286
    25
#include <lemon/bin_heap.h>
kpeter@170
    26
kpeter@171
    27
#include "graph_test.h"
kpeter@170
    28
#include "test_tools.h"
kpeter@170
    29
kpeter@170
    30
using namespace lemon;
kpeter@170
    31
deba@228
    32
char test_lgf[] =
deba@228
    33
  "@nodes\n"
deba@228
    34
  "label\n"
deba@228
    35
  "0\n"
deba@228
    36
  "1\n"
deba@228
    37
  "2\n"
deba@228
    38
  "3\n"
deba@228
    39
  "4\n"
deba@228
    40
  "@arcs\n"
deba@228
    41
  "     label length\n"
deba@228
    42
  "0 1  0     1\n"
deba@228
    43
  "1 2  1     1\n"
deba@228
    44
  "2 3  2     1\n"
deba@228
    45
  "0 3  4     5\n"
deba@228
    46
  "0 3  5     10\n"
deba@228
    47
  "0 3  6     7\n"
deba@228
    48
  "4 2  7     1\n"
deba@228
    49
  "@attributes\n"
deba@228
    50
  "source 0\n"
deba@228
    51
  "target 3\n";
deba@228
    52
alpar@209
    53
void checkDijkstraCompile()
kpeter@170
    54
{
kpeter@170
    55
  typedef int VType;
kpeter@170
    56
  typedef concepts::Digraph Digraph;
kpeter@170
    57
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
kpeter@170
    58
  typedef Dijkstra<Digraph, LengthMap> DType;
kpeter@286
    59
  typedef Digraph::Node Node;
kpeter@286
    60
  typedef Digraph::Arc Arc;
alpar@209
    61
kpeter@170
    62
  Digraph G;
kpeter@577
    63
  Node s, t, n;
kpeter@286
    64
  Arc e;
kpeter@170
    65
  VType l;
kpeter@577
    66
  int i;
kpeter@170
    67
  bool b;
kpeter@170
    68
  DType::DistMap d(G);
kpeter@170
    69
  DType::PredMap p(G);
kpeter@170
    70
  LengthMap length;
kpeter@286
    71
  Path<Digraph> pp;
kpeter@577
    72
  concepts::ReadMap<Node,bool> nm;
kpeter@170
    73
kpeter@286
    74
  {
kpeter@286
    75
    DType dijkstra_test(G,length);
kpeter@577
    76
    const DType& const_dijkstra_test = dijkstra_test;
kpeter@170
    77
kpeter@286
    78
    dijkstra_test.run(s);
kpeter@286
    79
    dijkstra_test.run(s,t);
kpeter@170
    80
kpeter@577
    81
    dijkstra_test.init();
kpeter@577
    82
    dijkstra_test.addSource(s);
kpeter@577
    83
    dijkstra_test.addSource(s, 1);
kpeter@577
    84
    n = dijkstra_test.processNextNode();
kpeter@577
    85
    n = const_dijkstra_test.nextNode();
kpeter@577
    86
    b = const_dijkstra_test.emptyQueue();
kpeter@577
    87
    i = const_dijkstra_test.queueSize();
kpeter@577
    88
    
kpeter@577
    89
    dijkstra_test.start();
kpeter@577
    90
    dijkstra_test.start(t);
kpeter@577
    91
    dijkstra_test.start(nm);
kpeter@577
    92
kpeter@577
    93
    l  = const_dijkstra_test.dist(t);
kpeter@577
    94
    e  = const_dijkstra_test.predArc(t);
kpeter@577
    95
    s  = const_dijkstra_test.predNode(t);
kpeter@577
    96
    b  = const_dijkstra_test.reached(t);
kpeter@577
    97
    b  = const_dijkstra_test.processed(t);
kpeter@577
    98
    d  = const_dijkstra_test.distMap();
kpeter@577
    99
    p  = const_dijkstra_test.predMap();
kpeter@577
   100
    pp = const_dijkstra_test.path(t);
kpeter@577
   101
    l  = const_dijkstra_test.currentDist(t);
kpeter@577
   102
  }
kpeter@577
   103
  {
kpeter@577
   104
    DType
kpeter@577
   105
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@577
   106
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
kpeter@577
   107
      ::SetStandardProcessedMap
kpeter@577
   108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@577
   109
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
kpeter@577
   110
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@577
   111
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@577
   112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
kpeter@577
   113
                concepts::ReadWriteMap<Node,int> >
kpeter@577
   114
      ::Create dijkstra_test(G,length);
kpeter@577
   115
kpeter@577
   116
    LengthMap length_map;
kpeter@577
   117
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@577
   118
    concepts::ReadWriteMap<Node,VType> dist_map;
kpeter@577
   119
    concepts::WriteMap<Node,bool> processed_map;
kpeter@577
   120
    concepts::ReadWriteMap<Node,int> heap_cross_ref;
kpeter@577
   121
    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
kpeter@577
   122
    
kpeter@577
   123
    dijkstra_test
kpeter@577
   124
      .lengthMap(length_map)
kpeter@577
   125
      .predMap(pred_map)
kpeter@577
   126
      .distMap(dist_map)
kpeter@577
   127
      .processedMap(processed_map)
kpeter@577
   128
      .heap(heap, heap_cross_ref);
kpeter@577
   129
kpeter@577
   130
    dijkstra_test.run(s);
kpeter@577
   131
    dijkstra_test.run(s,t);
kpeter@577
   132
kpeter@577
   133
    dijkstra_test.addSource(s);
kpeter@577
   134
    dijkstra_test.addSource(s, 1);
kpeter@577
   135
    n = dijkstra_test.processNextNode();
kpeter@577
   136
    n = dijkstra_test.nextNode();
kpeter@577
   137
    b = dijkstra_test.emptyQueue();
kpeter@577
   138
    i = dijkstra_test.queueSize();
kpeter@577
   139
    
kpeter@577
   140
    dijkstra_test.start();
kpeter@577
   141
    dijkstra_test.start(t);
kpeter@577
   142
    dijkstra_test.start(nm);
kpeter@577
   143
kpeter@286
   144
    l  = dijkstra_test.dist(t);
kpeter@286
   145
    e  = dijkstra_test.predArc(t);
kpeter@286
   146
    s  = dijkstra_test.predNode(t);
kpeter@286
   147
    b  = dijkstra_test.reached(t);
kpeter@577
   148
    b  = dijkstra_test.processed(t);
kpeter@286
   149
    pp = dijkstra_test.path(t);
kpeter@577
   150
    l  = dijkstra_test.currentDist(t);
kpeter@286
   151
  }
kpeter@286
   152
kpeter@170
   153
}
kpeter@170
   154
alpar@209
   155
void checkDijkstraFunctionCompile()
kpeter@170
   156
{
kpeter@170
   157
  typedef int VType;
kpeter@170
   158
  typedef concepts::Digraph Digraph;
kpeter@170
   159
  typedef Digraph::Arc Arc;
kpeter@170
   160
  typedef Digraph::Node Node;
kpeter@170
   161
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
alpar@209
   162
kpeter@170
   163
  Digraph g;
kpeter@278
   164
  bool b;
kpeter@278
   165
  dijkstra(g,LengthMap()).run(Node());
kpeter@278
   166
  b=dijkstra(g,LengthMap()).run(Node(),Node());
kpeter@170
   167
  dijkstra(g,LengthMap())
kpeter@278
   168
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   169
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   170
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@170
   171
    .run(Node());
kpeter@278
   172
  b=dijkstra(g,LengthMap())
kpeter@278
   173
    .predMap(concepts::ReadWriteMap<Node,Arc>())
kpeter@278
   174
    .distMap(concepts::ReadWriteMap<Node,VType>())
kpeter@278
   175
    .processedMap(concepts::WriteMap<Node,bool>())
kpeter@278
   176
    .path(concepts::Path<Digraph>())
kpeter@278
   177
    .dist(VType())
kpeter@278
   178
    .run(Node(),Node());
kpeter@170
   179
}
kpeter@170
   180
kpeter@170
   181
template <class Digraph>
alpar@209
   182
void checkDijkstra() {
kpeter@170
   183
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
kpeter@170
   184
  typedef typename Digraph::template ArcMap<int> LengthMap;
kpeter@170
   185
kpeter@170
   186
  Digraph G;
kpeter@170
   187
  Node s, t;
kpeter@170
   188
  LengthMap length(G);
alpar@209
   189
deba@228
   190
  std::istringstream input(test_lgf);
kpeter@293
   191
  digraphReader(G, input).
deba@228
   192
    arcMap("length", length).
deba@228
   193
    node("source", s).
deba@228
   194
    node("target", t).
deba@228
   195
    run();
alpar@209
   196
alpar@209
   197
  Dijkstra<Digraph, LengthMap>
alpar@209
   198
        dijkstra_test(G, length);
kpeter@170
   199
  dijkstra_test.run(s);
alpar@209
   200
deba@228
   201
  check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
kpeter@170
   202
kpeter@170
   203
  Path<Digraph> p = dijkstra_test.path(t);
kpeter@278
   204
  check(p.length()==3,"path() found a wrong path.");
kpeter@170
   205
  check(checkPath(G, p),"path() found a wrong path.");
kpeter@170
   206
  check(pathSource(G, p) == s,"path() found a wrong path.");
kpeter@170
   207
  check(pathTarget(G, p) == t,"path() found a wrong path.");
alpar@209
   208
kpeter@170
   209
  for(ArcIt e(G); e!=INVALID; ++e) {
kpeter@170
   210
    Node u=G.source(e);
kpeter@170
   211
    Node v=G.target(e);
alpar@210
   212
    check( !dijkstra_test.reached(u) ||
alpar@210
   213
           (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
kpeter@278
   214
           "Wrong output. dist(target)-dist(source)-arc_length=" <<
alpar@210
   215
           dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
kpeter@170
   216
  }
kpeter@170
   217
deba@228
   218
  for(NodeIt v(G); v!=INVALID; ++v) {
deba@228
   219
    if (dijkstra_test.reached(v)) {
deba@228
   220
      check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
deba@228
   221
      if (dijkstra_test.predArc(v)!=INVALID ) {
deba@228
   222
        Arc e=dijkstra_test.predArc(v);
deba@228
   223
        Node u=G.source(e);
deba@228
   224
        check(u==dijkstra_test.predNode(v),"Wrong tree.");
deba@228
   225
        check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
deba@228
   226
              "Wrong distance! Difference: " <<
deba@228
   227
              std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
deba@228
   228
      }
kpeter@170
   229
    }
kpeter@170
   230
  }
alpar@209
   231
kpeter@170
   232
  {
kpeter@170
   233
    NullMap<Node,Arc> myPredMap;
kpeter@170
   234
    dijkstra(G,length).predMap(myPredMap).run(s);
kpeter@170
   235
  }
kpeter@170
   236
}
kpeter@170
   237
kpeter@170
   238
int main() {
kpeter@170
   239
  checkDijkstra<ListDigraph>();
kpeter@170
   240
  checkDijkstra<SmartDigraph>();
kpeter@170
   241
  return 0;
kpeter@170
   242
}