TEST(GraphAlgorithms, BFS) { using Graph = BFSGraph; using SizeT = uint32_t; using VecPair = vector<pair<SizeT, SizeT>>; const SizeT n = 1 << 16; VecPair input; input.reserve(n); back_insert_iterator<VecPair> backInserter(input); generate_list_graph(backInserter, n); Graph graph(input.begin(), input.end(), n); auto colorPM = graph::get(color_t(), graph); auto distancePM = graph::get(distance_t(), graph); auto edgeTypePM = graph::get(edge_type_t(), graph); auto vRange = vertices(graph); for (auto vIt = vRange.first; vIt != vRange.second; ++vIt) graph::put(colorPM, *vIt, 0); std::queue<graph_traits<Graph>::vertex_descriptor> vQueue; for (auto vIt = vRange.first; vIt != vRange.second; ++vIt) { if (graph::get(colorPM, *vIt) == 0) { auto start = *vIt; vQueue.push(start); while (!vQueue.empty()) { auto src = vQueue.front(); vQueue.pop(); auto outRange = out_edges(src, graph); graph::put(colorPM, src, 2); for (auto outIt = outRange.first; outIt != outRange.second; ++outIt) { auto e = *outIt; auto tgt = target(e,graph); if (graph::get(colorPM, tgt) == 0) { graph::put(colorPM, tgt, 1); graph::put(distancePM, tgt, graph::get(distancePM, tgt) + 1); graph::put(edgeTypePM, e, 0); vQueue.push(tgt); } else if (graph::get(colorPM, tgt) == 1) graph::put(edgeTypePM, e, 1); else graph::put(edgeTypePM, e, 2); } } } }; for (auto vIt = vRange.first; vIt != vRange.second; ++vIt) { EXPECT_EQ(2,graph::get(colorPM, *vIt)); EXPECT_LT(graph::get(distancePM, *vIt), n); }; };
//function is fed with a priority queue of action-values //generates Boltzmann distribution of these action-values //and selects an action based on probabilities float selectAction(PriorityQueue<float, double>& a_queue, unsigned long iterations) { typedef std::vector<std::pair<float, double>> VecPair ; //turn priority queue into a vector of pairs VecPair vec = a_queue.saveOrderedQueueAsVector(); //sum for partition function double sum = 0; // calculate partition function by iterating over action-values for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) { sum += std::exp((iter->second) / temperature(iterations)); } //compute Boltzmann factors for action-values and enqueue to vec for (VecPair::iterator iter = vec.begin(); iter < vec.end(); ++iter) { iter->second = std::exp(iter->second / temperature(iterations)) / sum; } //calculate cumulative probability distribution for (VecPair::iterator iter = vec.begin()++, end = vec.end(); iter < end; ++iter) { //second member of pair becomes addition of its current value //and that of the index before it iter->second += (iter-1)->second; } //generate RN between 0 and 1 double rand_num = static_cast<double>(rand()) / RAND_MAX; // choose action based on random number relation to priorities within action queue for (VecPair::iterator iter = vec.begin(), end = vec.end(); iter < end; ++iter) { if (rand_num < iter->second)return iter->first; } return -10; //note that this line should never be reached }
TEST(GraphStructure, ListGraph) { using Graph = NoInternalPropertiesGraph; using SizeT = uint32_t; using VecPair = vector<pair<SizeT, SizeT>>; const SizeT n = 1 << 10; VecPair input; input.reserve(n); back_insert_iterator<VecPair> backInserter(input); generate_list_graph(backInserter, n); Graph graph(input.begin(), input.end(), n); //count # of cycles using vector vector<SizeT> cycles; for (auto p = input.begin(); p != input.end(); ++p) { if (p->first != n) { p->first = n; SizeT length = 1; auto cycleIt = p; while ((cycleIt = input.begin() + cycleIt->second) != p) { cycleIt->first = n; ++length; } cycles.push_back(length); } } sort(cycles.begin(), cycles.end()); //count # of cycles using graph data structure // assumes that the vertex_descriptor is an integral in [0,n) char* visited = new char[n]; memset(visited, 0, sizeof(char)*n); graph_traits<Graph>::vertices_size_type numVertices = num_vertices(graph); EXPECT_EQ(n, numVertices); graph_traits<Graph>::edges_size_type numEdges = 0; vector<graph_traits<Graph>::vertices_size_type> graphCycles; auto vRange = vertices(graph); for (graph_traits<Graph>::vertex_iterator vIt = vRange.first; vIt != vRange.second; ++vIt) { if (!visited[*vIt]) { visited[*vIt] = true; graph_traits<Graph>::degree_size_type degree = out_degree(*vIt, graph); EXPECT_EQ(1, degree); numEdges += degree; graph_traits<Graph>::vertices_size_type length = 1; auto outRange = adjacent_vertices(*vIt, graph); graph_traits<Graph>::vertex_descriptor curVertex; while ( (curVertex =*outRange.first) != *vIt) { ++length; visited[curVertex] = true; outRange = adjacent_vertices(curVertex, graph); degree = out_degree(curVertex, graph); EXPECT_EQ(1, degree); numEdges += degree; } graphCycles.push_back(length); } } delete[] visited; sort(graphCycles.begin(), graphCycles.end()); EXPECT_EQ(cycles.size(), graphCycles.size()); for (SizeT i = 0; i < cycles.size(); ++i) EXPECT_EQ(cycles[i], graphCycles[i]); assert(numEdges == n); EXPECT_EQ(n, num_edges(graph)); };