test/dijkstra_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 872 fa6f37d7a25b
parent 463 88ed40ad0d4f
child 956 141f9c0db4a3
child 1081 f1398882a928
child 1171 7e368d9b67f7
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
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@463
     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@632
    63
  Node s, t, n;
kpeter@286
    64
  Arc e;
kpeter@170
    65
  VType l;
kpeter@632
    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@632
    72
  concepts::ReadMap<Node,bool> nm;
kpeter@170
    73
kpeter@286
    74
  {
kpeter@286
    75
    DType dijkstra_test(G,length);
kpeter@632
    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@632
    81
    dijkstra_test.init();
kpeter@632
    82
    dijkstra_test.addSource(s);
kpeter@632
    83
    dijkstra_test.addSource(s, 1);
kpeter@632
    84
    n = dijkstra_test.processNextNode();
kpeter@632
    85
    n = const_dijkstra_test.nextNode();
kpeter@632
    86
    b = const_dijkstra_test.emptyQueue();
kpeter@632
    87
    i = const_dijkstra_test.queueSize();
kpeter@632
    88
    
kpeter@632
    89
    dijkstra_test.start();
kpeter@632
    90
    dijkstra_test.start(t);
kpeter@632
    91
    dijkstra_test.start(nm);
kpeter@632
    92
kpeter@632
    93
    l  = const_dijkstra_test.dist(t);
kpeter@632
    94
    e  = const_dijkstra_test.predArc(t);
kpeter@632
    95
    s  = const_dijkstra_test.predNode(t);
kpeter@632
    96
    b  = const_dijkstra_test.reached(t);
kpeter@632
    97
    b  = const_dijkstra_test.processed(t);
kpeter@632
    98
    d  = const_dijkstra_test.distMap();
kpeter@632
    99
    p  = const_dijkstra_test.predMap();
kpeter@632
   100
    pp = const_dijkstra_test.path(t);
kpeter@632
   101
    l  = const_dijkstra_test.currentDist(t);
kpeter@632
   102
  }
kpeter@632
   103
  {
kpeter@632
   104
    DType
kpeter@632
   105
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@632
   106
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
kpeter@632
   107
      ::SetStandardProcessedMap
kpeter@632
   108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@632
   109
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
kpeter@632
   110
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@632
   111
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@632
   112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
kpeter@632
   113
                concepts::ReadWriteMap<Node,int> >
kpeter@632
   114
      ::Create dijkstra_test(G,length);
kpeter@632
   115
kpeter@632
   116
    LengthMap length_map;
kpeter@632
   117
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@632
   118
    concepts::ReadWriteMap<Node,VType> dist_map;
kpeter@632
   119
    concepts::WriteMap<Node,bool> processed_map;
kpeter@632
   120
    concepts::ReadWriteMap<Node,int> heap_cross_ref;
kpeter@632
   121
    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
kpeter@632
   122
    
kpeter@632
   123
    dijkstra_test
kpeter@632
   124
      .lengthMap(length_map)
kpeter@632
   125
      .predMap(pred_map)
kpeter@632
   126
      .distMap(dist_map)
kpeter@632
   127
      .processedMap(processed_map)
kpeter@632
   128
      .heap(heap, heap_cross_ref);
kpeter@632
   129
kpeter@632
   130
    dijkstra_test.run(s);
kpeter@632
   131
    dijkstra_test.run(s,t);
kpeter@632
   132
kpeter@632
   133
    dijkstra_test.addSource(s);
kpeter@632
   134
    dijkstra_test.addSource(s, 1);
kpeter@632
   135
    n = dijkstra_test.processNextNode();
kpeter@632
   136
    n = dijkstra_test.nextNode();
kpeter@632
   137
    b = dijkstra_test.emptyQueue();
kpeter@632
   138
    i = dijkstra_test.queueSize();
kpeter@632
   139
    
kpeter@632
   140
    dijkstra_test.start();
kpeter@632
   141
    dijkstra_test.start(t);
kpeter@632
   142
    dijkstra_test.start(nm);
kpeter@632
   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@632
   148
    b  = dijkstra_test.processed(t);
kpeter@286
   149
    pp = dijkstra_test.path(t);
kpeter@632
   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
}