visualizations

Programmatic visualizations
git clone git://git.laack.co/visualizations.git
Log | Files | Refs | README

algo_test.cpp (5932B)


      1 #include "../headers/prim.hpp"
      2 
      3 #include <catch2/catch_test_macros.hpp>
      4 #include <cstddef>
      5 
      6 TEST_CASE( "Small Prim algorithm", "[small prim algo]" ) {
      7     std::size_t edgeCount = 1;
      8     std::size_t vertCount = 2;
      9 
     10     float xMax = 5120;
     11     float yMax = 1440;
     12 
     13     Graph g = Graph(edgeCount, vertCount, xMax,yMax);
     14     std::unordered_set<std::size_t> visitedIndices {};
     15     std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> toVisit {};
     16     std::vector<Edge> edges = g.getEdgesOfVertexIdx(0);
     17 
     18     for(auto edge: edges) {
     19         toVisit.push(edge);
     20     }
     21 
     22     g.traverseVertexIdx(0);
     23     visitedIndices.insert(0);
     24 
     25     while (toVisit.size() != 0) {
     26         oneStepPrim(toVisit, visitedIndices, g);
     27     }
     28     // this will be true bc 2 vertices 1 edge...
     29     // our graph may have multi-edges.
     30     REQUIRE(visitedIndices.size() == 2);
     31 }
     32 
     33 
     34 bool isConnected(Graph g) {
     35 
     36     std::unordered_set<std::size_t> verticesFound {0};
     37 
     38     std::vector<std::size_t> current {};
     39 
     40     while(true) {
     41         for(auto key: verticesFound) {
     42             auto edges = g.getEdgesOfVertexIdx(key);
     43             for(auto edge: edges) {
     44                 current.push_back(edge.v1Index);
     45                 current.push_back(edge.v2Index);
     46             }
     47         }
     48         std::size_t len = verticesFound.size();
     49         for(auto idx: current) {
     50             verticesFound.insert(idx);
     51         }
     52         if (len == verticesFound.size()) {
     53             break;
     54         }
     55     }
     56 
     57     return verticesFound.size() == g.getVertexCount();
     58 }
     59 
     60 
     61 TEST_CASE( "Large Prim algorithm", "[Large prim algo]" ) {
     62     std::size_t edgeCount = 3000;
     63     std::size_t vertCount = 1000;
     64 
     65     float xMax = 5120;
     66     float yMax = 1440;
     67 
     68     Graph g = Graph(edgeCount, vertCount, xMax,yMax);
     69     std::unordered_set<std::size_t> visitedIndices {};
     70     std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> toVisit {};
     71 
     72     do {
     73         g = Graph(edgeCount, vertCount, xMax,yMax);
     74     }
     75     while(!isConnected(g));
     76 
     77 
     78     g.traverseVertexIdx(0);
     79     visitedIndices.insert(0);
     80 
     81     std::vector<Edge> edges = g.getEdgesOfVertexIdx(0);
     82 
     83     for(auto edge: edges) {
     84         toVisit.push(edge);
     85     }
     86 
     87     while (toVisit.size() != 0) {
     88         oneStepPrim(toVisit, visitedIndices, g);
     89     }
     90 
     91     REQUIRE(visitedIndices.size() == vertCount);
     92 }
     93 
     94 TEST_CASE( "Medium Prim algorithm", "[Medium prim algo]" ) {
     95     std::size_t edgeCount = 70;
     96     std::size_t vertCount = 51;
     97 
     98     float xMax = 5120;
     99     float yMax = 1440;
    100 
    101     Graph g = Graph(edgeCount, vertCount, xMax,yMax);
    102     std::unordered_set<std::size_t> visitedIndices {};
    103     std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> toVisit {};
    104 
    105     do {
    106         g = Graph(edgeCount, vertCount, xMax,yMax);
    107     }
    108     while(!isConnected(g));
    109 
    110 
    111     g.traverseVertexIdx(0);
    112     visitedIndices.insert(0);
    113 
    114     std::vector<Edge> edges = g.getEdgesOfVertexIdx(0);
    115 
    116     for(auto edge: edges) {
    117         toVisit.push(edge);
    118     }
    119 
    120     while (toVisit.size() != 0) {
    121         oneStepPrim(toVisit, visitedIndices, g);
    122     }
    123 
    124     REQUIRE(visitedIndices.size() == vertCount);
    125 }
    126 
    127 
    128 TEST_CASE( "Staircase Prim algorithm", "[Staircase prim algo]" ) {
    129     for(int i = 2; i < 30; ++i) {
    130         for(int x = i-1; x < 60; ++x) {
    131             std::size_t edgeCount = x;
    132             std::size_t vertCount = i;
    133 
    134             float xMax = 5120;
    135             float yMax = 1440;
    136 
    137             Graph g = Graph(edgeCount, vertCount, xMax,yMax);
    138             std::unordered_set<std::size_t> visitedIndices {};
    139             std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> toVisit {};
    140 
    141             do {
    142                 g = Graph(edgeCount, vertCount, xMax,yMax);
    143             }
    144             while(!isConnected(g));
    145 
    146 
    147             std::vector<Edge> edges = g.getEdgesOfVertexIdx(0);
    148             for(auto edge: edges) {
    149                 toVisit.push(edge);
    150             }
    151             g.traverseVertexIdx(0);
    152             visitedIndices.insert(0);
    153 
    154             while (toVisit.size() != 0) {
    155                 oneStepPrim(toVisit, visitedIndices, g);
    156             }
    157 
    158             REQUIRE(visitedIndices.size() == vertCount);
    159 
    160 
    161         }
    162     }
    163 }
    164 
    165 TEST_CASE( "Small Prim Test", "[Small full validation]" ) {
    166     for(int i = 0; i < 100; ++i) {
    167         std::size_t edgeCount = 10;
    168         std::size_t vertCount = 5;
    169 
    170         float xMax = 5120;
    171         float yMax = 1440;
    172 
    173         Graph g = Graph(edgeCount, vertCount, xMax,yMax);
    174         do {
    175             g = Graph(edgeCount, vertCount, xMax,yMax);
    176         }
    177         while(!isConnected(g));
    178 
    179         std::unordered_set<std::size_t> visitedIndices {};
    180         std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> toVisit {};
    181 
    182         for (auto edge : g.getEdgesOfVertexIdx(0)) toVisit.push(edge);
    183         g.traverseVertexIdx(0);
    184         visitedIndices.insert(0);
    185 
    186         std::unordered_set<std::size_t> vBefore = visitedIndices;
    187 
    188         bool havePrior = false;
    189         Edge prior = toVisit.top();
    190         std::unordered_set<std::size_t> visibleAtPrior;
    191 
    192         while (toVisit.size() != 0) {
    193             auto current = toVisit.top();
    194             if (havePrior) {
    195                 bool wasPresent = visibleAtPrior.count(current.v1Index) > 0
    196                                || visibleAtPrior.count(current.v2Index) > 0;
    197                 // anytime we use the same source node two steps in a row, the second 
    198                 // weight must be smaller.
    199                 if (wasPresent) {
    200                     REQUIRE(current.length2 >= prior.length2);
    201                 }
    202             }
    203 
    204             prior = current;
    205             visibleAtPrior = visitedIndices;
    206             havePrior = true;
    207             oneStepPrim(toVisit, visitedIndices, g);
    208             bool valid = vBefore.size() + 1 == visitedIndices.size()
    209                       || vBefore.size() == vertCount;
    210             REQUIRE(valid);
    211             vBefore = visitedIndices;
    212         }
    213         REQUIRE(visitedIndices.size() == vertCount);
    214     }
    215 }