COIN-OR::LEMON - Graph Library

Ticket #421: 421.diff

File 421.diff, 3.3 KB (added by Andras Kucsma, 10 years ago)

Implementation of the proposed TopologicalSort?

  • new file lemon/topological_sort.h

    diff -r 5de6a70446f6 lemon/topological_sort.h
    - +  
     1#ifndef LEMON_TOPOLOGICAL_SORT_H
     2#define LEMON_TOPOLOGICAL_SORT_H
     3
     4#include <queue>
     5#include <vector>
     6#include <cassert>
     7
     8namespace lemon {
     9
     10template <typename G>
     11std::vector<typename G::Node> TopologicalSort(const G& graph) {
     12
     13    typedef typename G::Node Node;
     14    typedef typename G::template NodeMap<int> NodeMap;
     15    typedef typename G::NodeIt NodeIt;
     16    typedef typename G::OutArcIt OutArcIt;
     17
     18    std::queue<Node> queue;
     19
     20    NodeMap deg(graph);
     21
     22    for (NodeIt vertex(graph); vertex != INVALID; ++vertex) {
     23        deg[vertex] = countInArcs(graph, vertex);
     24        if(deg[vertex] == 0) {
     25            queue.push(vertex);
     26        }
     27    }
     28
     29    std::vector<Node> sorted;
     30    while (!queue.empty()) {
     31        Node source = queue.front();
     32        queue.pop();
     33
     34        sorted.push_back(source);
     35
     36        for (OutArcIt it(graph, source); it != INVALID; ++it) {
     37            Node target = graph.target(it);
     38            assert(deg[target] >= 1); //Not a DAG otherwise
     39            --deg[target];
     40            if (deg[target] == 0) {
     41                queue.push(target);
     42            }
     43        }
     44    }
     45    return sorted;
     46}
     47
     48}
     49
     50#endif
  • test/CMakeLists.txt

    diff -r 5de6a70446f6 test/CMakeLists.txt
    a b  
    5252  random_test
    5353  suurballe_test
    5454  time_measure_test
     55  topological_sort_test
    5556  tsp_test
    5657  unionfind_test
    5758)
  • new file test/topological_sort_test.cc

    diff -r 5de6a70446f6 test/topological_sort_test.cc
    - +  
     1
     2#include <lemon/maps.h>
     3#include <lemon/list_graph.h>
     4#include <lemon/topological_sort.h>
     5
     6#include <algorithm>
     7
     8#include "test_tools.h"
     9
     10using namespace lemon;
     11
     12template<class T>
     13unsigned indexOf(const std::vector<T>& v, const T& what) {
     14    return std::find(v.begin(), v.end(), what) - v.begin();
     15}
     16
     17int main() {
     18    ListDigraph graph;
     19    typedef ListDigraph::Node Node;
     20
     21    Node maincpp = graph.addNode();
     22    Node foohpp = graph.addNode();
     23    Node foocpp = graph.addNode();
     24    Node barhpp = graph.addNode();
     25    Node barcpp = graph.addNode();
     26    Node foobarlib = graph.addNode();
     27    Node aout = graph.addNode();
     28
     29    graph.addArc(maincpp, foohpp);
     30    graph.addArc(foocpp, foohpp);
     31    graph.addArc(barcpp, barhpp);
     32    graph.addArc(barhpp, foohpp);
     33    graph.addArc(aout, foocpp);
     34    graph.addArc(aout, barcpp);
     35    graph.addArc(aout, foobarlib);
     36
     37    std::vector<Node> sorted = TopologicalSort(graph);
     38
     39    check(indexOf(sorted, maincpp) < indexOf(sorted, foohpp), "ordering error");
     40    check(indexOf(sorted, foocpp) < indexOf(sorted, foohpp), "ordering error");
     41    check(indexOf(sorted, barcpp) < indexOf(sorted, barhpp), "ordering error");
     42    check(indexOf(sorted, barhpp) < indexOf(sorted, foohpp), "ordering error");
     43    check(indexOf(sorted, aout) < indexOf(sorted, foocpp), "ordering error");
     44    check(indexOf(sorted, aout) < indexOf(sorted, barcpp), "ordering error");
     45    check(indexOf(sorted, aout) < indexOf(sorted, foobarlib), "ordering error");
     46
     47}