test/dijkstra_test.cc
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 440 88ed40ad0d4f
child 877 141f9c0db4a3
child 1007 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@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@585
    63
  Node s, t, n;
kpeter@286
    64
  Arc e;
kpeter@170
    65
  VType l;
kpeter@585
    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@585
    72
  concepts::ReadMap<Node,bool> nm;
kpeter@170
    73
kpeter@286
    74
  {
kpeter@286
    75
    DType dijkstra_test(G,length);
kpeter@585
    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@585
    81
    dijkstra_test.init();
kpeter@585
    82
    dijkstra_test.addSource(s);
kpeter@585
    83
    dijkstra_test.addSource(s, 1);
kpeter@585
    84
    n = dijkstra_test.processNextNode();
kpeter@585
    85
    n = const_dijkstra_test.nextNode();
kpeter@585
    86
    b = const_dijkstra_test.emptyQueue();
kpeter@585
    87
    i = const_dijkstra_test.queueSize();
kpeter@585
    88
    
kpeter@585
    89
    dijkstra_test.start();
kpeter@585
    90
    dijkstra_test.start(t);
kpeter@585
    91
    dijkstra_test.start(nm);
kpeter@585
    92
kpeter@585
    93
    l  = const_dijkstra_test.dist(t);
kpeter@585
    94
    e  = const_dijkstra_test.predArc(t);
kpeter@585
    95
    s  = const_dijkstra_test.predNode(t);
kpeter@585
    96
    b  = const_dijkstra_test.reached(t);
kpeter@585
    97
    b  = const_dijkstra_test.processed(t);
kpeter@585
    98
    d  = const_dijkstra_test.distMap();
kpeter@585
    99
    p  = const_dijkstra_test.predMap();
kpeter@585
   100
    pp = const_dijkstra_test.path(t);
kpeter@585
   101
    l  = const_dijkstra_test.currentDist(t);
kpeter@585
   102
  }
kpeter@585
   103
  {
kpeter@585
   104
    DType
kpeter@585
   105
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
kpeter@585
   106
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
kpeter@585
   107
      ::SetStandardProcessedMap
kpeter@585
   108
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
kpeter@585
   109
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
kpeter@585
   110
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@585
   111
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
kpeter@585
   112
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> >, 
kpeter@585
   113
                concepts::ReadWriteMap<Node,int> >
kpeter@585
   114
      ::Create dijkstra_test(G,length);
kpeter@585
   115
kpeter@585
   116
    LengthMap length_map;
kpeter@585
   117
    concepts::ReadWriteMap<Node,Arc> pred_map;
kpeter@585
   118
    concepts::ReadWriteMap<Node,VType> dist_map;
kpeter@585
   119
    concepts::WriteMap<Node,bool> processed_map;
kpeter@585
   120
    concepts::ReadWriteMap<Node,int> heap_cross_ref;
kpeter@585
   121
    BinHeap<VType, concepts::ReadWriteMap<Node,int> > heap(heap_cross_ref);
kpeter@585
   122
    
kpeter@585
   123
    dijkstra_test
kpeter@585
   124
      .lengthMap(length_map)
kpeter@585
   125
      .predMap(pred_map)
kpeter@585
   126
      .distMap(dist_map)
kpeter@585
   127
      .processedMap(processed_map)
kpeter@585
   128
      .heap(heap, heap_cross_ref);
kpeter@585
   129
kpeter@585
   130
    dijkstra_test.run(s);
kpeter@585
   131
    dijkstra_test.run(s,t);
kpeter@585
   132
kpeter@585
   133
    dijkstra_test.addSource(s);
kpeter@585
   134
    dijkstra_test.addSource(s, 1);
kpeter@585
   135
    n = dijkstra_test.processNextNode();
kpeter@585
   136
    n = dijkstra_test.nextNode();
kpeter@585
   137
    b = dijkstra_test.emptyQueue();
kpeter@585
   138
    i = dijkstra_test.queueSize();
kpeter@585
   139
    
kpeter@585
   140
    dijkstra_test.start();
kpeter@585
   141
    dijkstra_test.start(t);
kpeter@585
   142
    dijkstra_test.start(nm);
kpeter@585
   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@585
   148
    b  = dijkstra_test.processed(t);
kpeter@286
   149
    pp = dijkstra_test.path(t);
kpeter@585
   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
}