Guest User

Reddit

a guest
May 13th, 2019
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.54 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2.  
  3. #include <iostream>
  4. #include <memory>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <utility>
  8. #include <sstream>
  9. #include <iomanip>
  10. #include <cmath>
  11.  
  12. #include "random.hpp"
  13. using Random = effolkronium::random_static;
  14.  
  15. int count = 0;
  16.  
  17. int dist(std::vector<sf::Vector2f>, std::vector<int>);
  18. double factorial(int);
  19. bool nextOrder(std::vector<int>&, sf::Text&);
  20.  
  21. // template<class T> void splice(std::vector<T>&, int);
  22. template<class T> std::vector<T> splice(std::vector<T>, int, int);
  23.  
  24. int main() {
  25.     // Setting up basic window properties
  26.     int width = 700, height = 900;
  27.     const unsigned fps = 60, depth = 32;
  28.  
  29.     sf::RenderWindow app;
  30.         app.create(sf::VideoMode(width, height, depth), "Main Window");
  31.         app.setFramerateLimit(fps);
  32.  
  33.  
  34.     // Randomly generated dots that are represent cities
  35.     int totalCities = 5;
  36.     bool isFinished = false;
  37.     std::vector<int> order;
  38.  
  39.     std::vector<sf::Vector2f> cities;
  40.     for (int i = 0; i != totalCities; ++i) {
  41.         auto xPos = Random::get(0, width);
  42.         auto yPos = Random::get(0, height/2);
  43.    
  44.         cities.push_back(sf::Vector2f(xPos, yPos));
  45.         order.push_back(i);
  46.     }
  47.  
  48.     // Tracking te best, smallest distance between two dots
  49.     int recordDist = 0;
  50.     std::vector<int> bestEver;
  51.  
  52.     int d = dist(cities, order);
  53.     recordDist = d;
  54.     std::copy(order.begin(), order.end(), std::back_inserter(bestEver));
  55.    
  56.  
  57.     // Graphical representation of cities and connections
  58.     sf::CircleShape city;
  59.         city.setRadius(8);
  60.         city.setOrigin(city.getRadius(), city.getRadius());
  61.         city.setFillColor(sf::Color::Black);
  62.  
  63.     std::vector<sf::Vector2f> actPath;
  64.     std:copy(cities.begin(), cities.end(), std::back_inserter(actPath));
  65.     for (auto& t : cities) t = sf::Vector2f(t.x, t.y+(height/2));
  66.  
  67.     sf::VertexArray lines(sf::LinesStrip, totalCities);
  68.     for (int i = 0; i != totalCities; ++i) {
  69.         lines[i].position = actPath[i];
  70.         lines[i].color = sf::Color::Black;
  71.     }
  72.  
  73.     sf::VertexArray bestLines(sf::LinesStrip, totalCities);
  74.     for (int i = 0; i != totalCities; ++i) {
  75.         int n = bestEver[i];
  76.         bestLines[i].position = cities[n];
  77.         bestLines[i].color = sf::Color::Red;
  78.     }
  79.  
  80.     // Calculating overall percentage of the process
  81.     double totalPerms = factorial(totalCities);
  82.     double percent = 0;
  83.    
  84.     sf::Font font;
  85.         font.loadFromFile("arial.ttf");
  86.     sf::Text progress;
  87.         progress.setFont(font);
  88.         progress.setCharacterSize(30);
  89.         progress.setPosition(sf::Vector2f(20, 20));
  90.         progress.setFillColor(sf::Color::Black);
  91.     sf::Text lex;
  92.         lex.setFont(font);
  93.         lex.setCharacterSize(20);
  94.         lex.setPosition(sf::Vector2f(10, height-30));
  95.         lex.setFillColor(sf::Color::Black);
  96.  
  97.     // Main draw loop
  98.     while(app.isOpen()) {
  99.         sf::Event event;
  100.         while(app.pollEvent(event)) {
  101.             if (event.type == sf::Event::Closed) app.close();
  102.         } app.clear(sf::Color(230, 230, 250));
  103.  
  104.  
  105.         // Setting up precision for displaying text on the screen from double
  106.         percent = 100*(count/totalPerms);    
  107.             std::ostringstream sob;
  108.             sob << std::fixed;
  109.             sob << std::setprecision(2);
  110.             sob << percent;
  111.         std::string txt = sob.str();
  112.         // std::cout << txt << std::endl;
  113.  
  114.         if (!isFinished) {
  115.             progress.setString(std::to_string(percent) + '%');
  116.             app.draw(lines);
  117.         }
  118.         // } else progress.setString("100%");
  119.  
  120.         std::string tmp = " ";
  121.         std::string lexo = " ";
  122.         for (auto o : order) tmp += std::to_string(o);
  123.        
  124.         lexo = tmp;
  125.         lex.setString(lexo);
  126.         app.draw(lex);
  127.  
  128.  
  129.         for (auto c : cities) {
  130.             city.setPosition(c);
  131.  
  132.             app.draw(city);
  133.             app.draw(bestLines);
  134.             app.draw(progress);
  135.         }
  136.  
  137.         // Checking all of the possible connections        
  138.         for (int i = 0; i != order.size(); ++i) {
  139.             int n = order[i];
  140.             // lines[i].position = cities[n];
  141.             lines[i].position = actPath[n];
  142.         }
  143.         for (int i = 0; i != order.size(); ++i) {
  144.             int n = bestEver[i];
  145.             bestLines[i].position = cities[n];
  146.         }
  147.  
  148.         // Tracking te best, smallest distance between two dots... Again.
  149.         int d = dist(cities, order);
  150.         if (d < recordDist) {
  151.             recordDist = d;
  152.             bestEver.resize(0);  // This is needed for std::copy in the every next iteration
  153.             std::copy(order.begin(), order.end(), std::back_inserter(bestEver));
  154.             std::cout << recordDist << std::endl;
  155.         } isFinished = nextOrder(order, lex);
  156.  
  157.         std::cout << "bestEver" << std::endl;
  158.         for (auto b : bestEver) std::cout << b << ' ';
  159.         std::cout << std::endl;
  160.  
  161.         std::cout << "order" << std::endl;
  162.         for (auto o : order) std::cout << o << ' ';
  163.         std::cout << std::endl;
  164.  
  165.         app.display();
  166.     }
  167.  
  168.     return 0;
  169. }
  170.  
  171. int dist(std::vector<sf::Vector2f> points, std::vector<int> order) {
  172.     count++;
  173.     int sum = 0;
  174.     for (int i = 0; i != order.size()-1; ++i) {
  175.         auto cityA = points[order[i]];
  176.         auto cityB = points[order[i+1]];
  177.  
  178.         int xd = abs(cityA.x - cityB.x);
  179.         int yd = abs(cityA.y - cityB.y);
  180.         int d = sqrt(xd*xd + yd*yd);
  181.  
  182.         sum += d;
  183.     }
  184.     return sum;
  185. }
  186.  
  187. double factorial(int n) {
  188.     if (n == 1) return 1;
  189.     else return n * factorial(n-1);
  190. }
  191.  
  192. // Lexicographic order of numbers
  193. bool nextOrder(std::vector<int>& vo, sf::Text& txt) {
  194.         int largI = -1;
  195.         for (int i = 0; i < vo.size()-1; i++) {
  196.             if (vo[i] < vo[i+1]) largI = i;
  197.         } if (largI == -1) return true;
  198.  
  199.         int largJ = -1;
  200.         for (int j = 0; j < vo.size(); j++) {
  201.             if (vo[largI] < vo[j]) largJ = j;
  202.         } std::swap(vo[largI], vo[largJ]);
  203.  
  204.  
  205.         std::vector<int> vc;
  206.         std::copy(vo.begin()+largI+1, vo.begin()+largI+2, std::back_inserter(vc));
  207.  
  208.         vo.erase(vo.begin()+largI+1);  
  209.         vo.insert(vo.end(), vc.begin(), vc.end());
  210.  
  211.     return false;
  212. }
  213.  
  214. // template<class T> void splice(std::vector<T>& va, int n) {
  215. //     va.assign(va.begin()+n, va.end());
  216. // }
  217.  
  218. // template<class T> std::vector<T> splice(std::vector<T> vc, int n, int nn) {
  219. //     std::vector<T> tmp;
  220. //     std::copy(vc.begin()+n, vc.begin()+nn, std::back_inserter(vc));
  221. //     return tmp;
  222. // }
Add Comment
Please, Sign In to add comment