Advertisement
deanmsands3

PrimsAlgorithm.cpp

Oct 20th, 2014
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. //============================================================================
  2. // Name        : PrimsAlgorithm.cpp
  3. // Author      : Dean Sands
  4. // Version     : 0.0.1a
  5. // Copyright   : I will set your flamingos on fire.
  6. // Description : Prim's Minimum Spanning Tree Maze Creator
  7. //============================================================================
  8.  
  9.  
  10. #include <SFML/Graphics.hpp>
  11. #include <unordered_map>
  12. #include <vector>
  13. #include <deque>
  14. #include <iostream>
  15. #include <cstdlib>
  16. #include <climits>
  17. #include <chrono>
  18. #include <random>
  19. #include <algorithm>
  20. #include <set>
  21. #pragma comment(lib,"glew.lib")
  22. #pragma comment(lib,"sfml-system-d.lib")
  23. #pragma comment(lib,"sfml-window-d.lib")
  24. #pragma comment(lib,"sfml-graphics-d.lib")
  25.  
  26. #define WIDTH 40
  27. #define HEIGHT 30
  28. #define TOTAL (WIDTH*HEIGHT)
  29.  
  30. using namespace std;
  31.  
  32.  
  33. struct node{
  34.     float x;
  35.     float y;
  36.     node(float newX, float newY):x(newX),y(newY){}
  37. };
  38.  
  39.  
  40. struct edge{
  41.     node *a;
  42.     node *b;
  43.     uint64_t weight;
  44.     edge(node *newNodeA, node *newNodeB, uint64_t newWeight=0):a(newNodeA),b(newNodeB), weight(newWeight){}
  45.     bool operator() (edge *i, edge *j) { return (i->weight<j->weight);}
  46.     bool operator() (edge i, edge j) { return (i.weight<j.weight);}
  47. };
  48.  
  49.  
  50.  
  51. set<node*> knownNodes; 
  52. set<node*> unknownNodes;
  53. unordered_map<uint64_t, edge*> edgemap;
  54. deque<edge*> edgeQueue;
  55. vector<edge*> usedEdges;
  56. vector<node*> nodelist;
  57. std::mt19937_64 *generator;
  58.  
  59. node *addNode(float x, float y){
  60.     node *newNode=new node(x,y);
  61.     nodelist.push_back(newNode);
  62.     unknownNodes.insert(newNode);
  63.     return newNode;
  64. }
  65.  
  66. void connectNodes(uint64_t a,uint64_t b){
  67.     uint64_t weight;
  68.     edge *newEdge = new edge(nodelist[a],nodelist[b]);
  69.     do{
  70.         weight=(*generator)();
  71.     }while(edgemap.find(weight)!=edgemap.end());
  72.     newEdge->weight=weight;
  73.     edgemap[weight]=newEdge;
  74.     edgeQueue.push_back(newEdge);
  75. }
  76.  
  77. void createNodes(){
  78.     int x=0, y=0;
  79.     for(y=0;y<HEIGHT;y++)for(x=0;x<WIDTH;x++)addNode(x*20,y*20);
  80. }
  81.  
  82. void createEdges(){
  83.     int x=0, y=0;
  84.     //Top row
  85.     for(x=1;x<WIDTH;x++){
  86.         uint64_t myNodeIndex=y*WIDTH+x;
  87.         connectNodes(myNodeIndex-1,myNodeIndex);
  88.     }
  89.     for(y=1;y<HEIGHT;y++){
  90.         for(x=1;x<WIDTH;x++){
  91.             uint64_t myNodeIndex=y*WIDTH+x;
  92.             connectNodes(myNodeIndex-1,myNodeIndex);
  93.             connectNodes(myNodeIndex-WIDTH,myNodeIndex);
  94.         }
  95.     }
  96. }
  97. void primsAlgorithm(){
  98.     bool addA,addB;
  99.     edge *currentEdge;
  100.     node *nodeA, *nodeB;
  101.     int i=0;
  102.     while(!unknownNodes.empty()){
  103.         auto currentEdgeIter = edgeQueue.begin();
  104.         if (currentEdgeIter == edgeQueue.end()){ cout << "End of queue reached." << endl; break; }
  105.         currentEdge = *currentEdgeIter;
  106.         nodeA = currentEdge->a;
  107.         nodeB=currentEdge->b;
  108.         addA = (unknownNodes.find(nodeA) != unknownNodes.end());
  109.         addB=(unknownNodes.find(nodeB)!=unknownNodes.end());
  110.         if (!(addA || addB)) {
  111.             edgeQueue.pop_front();
  112.             continue;
  113.         }
  114.         usedEdges.push_back(currentEdge);
  115.         if(addA){unknownNodes.erase(nodeA);}
  116.         if(addB){unknownNodes.erase(nodeB);}
  117.         edgeQueue.pop_front();
  118.         i++;
  119.         std::cout<<i<<endl;
  120.     }
  121.  
  122.     while (!unknownNodes.empty()){
  123.         auto nodeIter = unknownNodes.begin();
  124.         auto nodeC = *nodeIter;
  125.         cout << "Unknown Node:" << nodeC->x << "," << nodeC->y << endl;
  126.         unknownNodes.erase(nodeIter);
  127.     }
  128. }
  129. void display(){
  130.     sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
  131.  
  132.     // run the program as long as the window is open
  133.     while (window.isOpen())
  134.     {
  135.         // check all the window's events that were triggered since the last iteration of the loop
  136.         sf::Event event;
  137.         while (window.pollEvent(event))
  138.         {
  139.             // "close requested" event: we close the window
  140.             if (event.type == sf::Event::Closed)
  141.                 window.close();
  142.             // "close requested" event: we close the window
  143.             if (event.type == sf::Event::KeyPressed)
  144.                 if (event.key.code == sf::Keyboard::Escape)
  145.                 window.close();
  146.         }
  147.  
  148.         // clear the window with black color
  149.         window.clear(sf::Color::Black);
  150.  
  151.         for(auto thisEdge:usedEdges){
  152.             sf::Vertex line[] =
  153.             {
  154.                 sf::Vertex(sf::Vector2f(thisEdge->a->x, thisEdge->a->y)),
  155.                 sf::Vertex(sf::Vector2f(thisEdge->b->x, thisEdge->b->y))
  156.             };
  157.  
  158.             window.draw(line, 2, sf::Lines);
  159.         }
  160.  
  161.         for(auto c:nodelist){
  162.             // define a circle with radius = 5
  163.             sf::CircleShape *circle=new sf::CircleShape(5);
  164.             circle->setOrigin(c->x,c->y);
  165.  
  166.             // change the number of sides (points) to 8
  167.             circle->setPointCount(8);
  168.             circle->setFillColor(sf::Color(250, 100, 50));
  169.             window.draw(*circle);
  170.             delete circle;
  171.         }
  172.  
  173.         // end the current frame
  174.         window.display();
  175.     }
  176. }
  177. void cleanup(){
  178.     // ******** //
  179.         for(auto nodeX:nodelist){
  180.             delete nodeX;
  181.         }
  182.         for(auto edgeX:edgemap){
  183.             delete edgeX.second;
  184.         }
  185. }
  186.  
  187. int main(void) {
  188.     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
  189.     generator = new std::mt19937_64(seed);
  190.     createNodes();
  191.     cout<<"nodes created."<<endl;
  192.     createEdges();
  193.     cout<<"edges created"<<endl;
  194.     sort(edgeQueue.begin(),edgeQueue.end());
  195.     cout<<"edges sorted"<<endl;
  196.     primsAlgorithm();
  197.     cout<<"edges primmed"<<endl;
  198.     display();
  199.     cout<<"edges displayed"<<endl;
  200.     cleanup();
  201.     cout<<"nodes and edges cleaned"<<endl;
  202.     return EXIT_SUCCESS;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement