Advertisement
aimon1337

Untitled

Jan 10th, 2022
865
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.70 KB | None | 0 0
  1. #include <algorithm>
  2. #include <array>
  3. #include <bitset>
  4. #include <cassert>
  5. #include <chrono>
  6. #include <cmath>
  7. #include <cstdlib>
  8. #include <cstring>
  9. #include <fstream>
  10. #include <functional>
  11. #include <iomanip>
  12. #include <iostream>
  13. #include <map>
  14. #include <numeric>
  15. #include <queue>
  16. #include <random>
  17. #include <set>
  18. #include <stdexcept>
  19. #include <stdlib.h>
  20. #include <unordered_map>
  21. #include <unordered_set>
  22. #include <utility>
  23. #include <vector>
  24. using namespace std;
  25.  
  26. template<typename A, typename B> ostream& operator<<(ostream& os, const pair<A, B>& p) { return os << '(' << p.first << ", " << p.second << ')'; }
  27. template < typename T_container, typename T = typename enable_if < !is_same<T_container, string>::value, typename T_container::value_type >::type > ostream & operator<<(ostream& os, const T_container& v) { os << '{'; string sep; for (const T& x : v) os << sep << x, sep = ", "; return os << '}'; }
  28.  
  29. void dbg_out() { cerr << endl; }
  30. template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
  31. #ifdef NEAL_DEBUG
  32. #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
  33. #else
  34. #define dbg(...)
  35. #endif
  36.  
  37. struct Node
  38. {
  39.     vector<vector<int>> curState;
  40.     int H, G, N;
  41.     string action;
  42.     Node* parent;
  43.     Node(vector<vector<int>> X, string Action, int g, int h, int n, Node* Parent)
  44.     {
  45.         this->curState = X;
  46.         this->action = Action;
  47.         this->G = g;
  48.         this->N = n;
  49.         this->H = h;
  50.         this->parent = Parent;
  51.     }
  52.     Node& operator = (const Node &b)
  53.     {
  54.         this->H = b.H;
  55.         this->G = b.G;
  56.         this->N = b.N;
  57.         this->action = b.action;
  58.         this->curState = b.curState;
  59.         this->parent = b.parent;
  60.         return *this;
  61.     }
  62. };
  63.  
  64. //ACTION = 0 -> UP; 1-> DOWN; 2 - > LEFT 3-> RIGHT
  65.  
  66. int getInversion(vector<int> arr)
  67. {
  68.     int inv_count = 0;
  69.     for (int i = 0; i < arr.size() - 1; ++i)
  70.     {
  71.         for (int j = i + 1; j < arr.size(); ++j)
  72.         {
  73.             inv_count += ((arr[i] > arr[j]) ? 1 : 0);
  74.         }
  75.     }
  76.     return inv_count;
  77. }
  78.  
  79. bool isSolvable(vector<vector<int>> curState, int N)
  80. {
  81.     int empty_row = -1;
  82.     vector<int> arr;
  83.     for (int i = 0 ; i < N; ++i)
  84.     {
  85.         for (int j = 0; j < N; ++j)
  86.         {
  87.             if (curState[i][j])
  88.                 arr.push_back(curState[i][j]);
  89.             else empty_row = i;
  90.         }
  91.     }
  92.     int inversions = getInversion(arr);
  93.     if (N % 2 == 0 && (empty_row % 2 == !(inversions % 2)))
  94.         return true;
  95.     if (N % 2 == 1 && inversions % 2 == 0)
  96.         return true;
  97.     return false;
  98. }
  99.  
  100. void printData(vector<vector<int>> curState, string outputFilePath)
  101. {
  102.     int N = curState.size();
  103.     ofstream fout(outputFilePath, ios::out | ios::app);
  104.     for (int i = 0 ; i < N; ++i)
  105.     {
  106.         for (int j = 0; j < N; ++j)
  107.         {
  108.             fout << curState[i][j] << " ";
  109.         }
  110.         fout << endl;
  111.     }
  112.     fout << endl;
  113.     fout.close();
  114. }
  115.  
  116. void getEmptyPosition(vector<vector<int>> curState, int &xPoz, int &yPoz)
  117. {
  118.     for (int i = 0; i < curState.size() ; ++i)
  119.     {
  120.         for (int j = 0; j < curState.size(); ++j)
  121.         {
  122.             if (curState[i][j] == 0)
  123.             {
  124.                 xPoz = i, yPoz = j;
  125.                 return;
  126.             }
  127.         }
  128.     }
  129. }
  130.  
  131. bool canMoveUp(vector<vector<int>> curState, int N, int xPoz, int yPoz)
  132. {
  133.     for (int i = 0; i < N; ++i)
  134.     {
  135.         if (curState[xPoz][yPoz]  == curState[0][i])
  136.             return false;
  137.     }
  138.     return true;
  139. }
  140.  
  141.  
  142. bool canMoveDown(vector<vector<int>> curState, int N, int xPoz, int yPoz)
  143. {
  144.     for (int i = 0; i < N; ++i)
  145.     {
  146.         if (curState[xPoz][yPoz]  == curState[N - 1][i])
  147.             return false;
  148.     }
  149.     return true;
  150. }
  151.  
  152.  
  153. bool canMoveLeft(vector<vector<int>> curState, int N, int xPoz, int yPoz)
  154. {
  155.     for (int i = 0; i < N; ++i)
  156.     {
  157.         if (curState[xPoz][yPoz]  == curState[i][0])
  158.             return false;
  159.     }
  160.     return true;
  161. }
  162.  
  163.  
  164. bool canMoveRight(vector<vector<int>> curState, int N, int xPoz, int yPoz)
  165. {
  166.     for (int i = 0; i < N; ++i)
  167.     {
  168.         if (curState[xPoz][yPoz]  == curState[i][N - 1])
  169.             return false;
  170.     }
  171.     return true;
  172. }
  173.  
  174. void expandState(vector<vector<int>> curState, int N, vector<vector<int>> &child1, vector<vector<int>> &child2, vector<vector<int>> &child3, vector<vector<int>> &child4)
  175. {
  176.     //child1 - up child2 - down child3 - left child4 - right
  177.     int xPoz, yPoz;
  178.     getEmptyPosition(curState, xPoz, yPoz);
  179.     if (canMoveUp(curState, N, xPoz, yPoz))
  180.     {
  181.         child1 = curState;
  182.         swap(child1[xPoz - 1][yPoz], child1[xPoz][yPoz]);
  183.  
  184.     }
  185.     if (canMoveDown(curState, N, xPoz, yPoz))
  186.     {
  187.         child2 = curState;
  188.         swap(child2[xPoz + 1][yPoz], child2[xPoz][yPoz]);
  189.     }
  190.     if (canMoveLeft(curState, N, xPoz, yPoz))
  191.     {
  192.         child3 = curState;
  193.         swap(child3[xPoz][yPoz - 1], child3[xPoz][yPoz]);
  194.     }
  195.     if (canMoveRight(curState, N, xPoz, yPoz))
  196.     {
  197.         child4 = curState;
  198.         swap(child4[xPoz][yPoz + 1], child4[xPoz][yPoz]);
  199.     }
  200. }
  201.  
  202. int manhattan_distance(vector<vector<int>>curState, vector<vector<int>> goalState, int N)
  203. {
  204.     int manhattan = 0;
  205.     for (int i = 0; i < N; ++i)
  206.     {
  207.         for (int j = 0; j < N; ++j)
  208.         {
  209.             if (i == N - 1 && j == N - 1)
  210.             {
  211.                 break;
  212.             }
  213.             for (int x = 0; x < N; ++x)
  214.             {
  215.                 for (int y = 0; y < N; ++y)
  216.                 {
  217.                     if (goalState[i][j] == curState[x][y])
  218.                         manhattan = manhattan + abs(i - x) + abs(j - y);
  219.                 }
  220.             }
  221.         }
  222.     }
  223.     return manhattan;
  224. }
  225.  
  226. void getChilds(Node curState, int N, vector<Node> &Tree, string outputFilePath, vector<vector<int>> goalState)
  227. {
  228.     vector<vector<int>> child1, child2, child3, child4;
  229.     expandState(curState.curState, N, child1, child2, child3, child4);
  230.     //dbg(child1, child2, child3, child4);
  231.     int H;
  232.     if (!child1.empty())
  233.     {
  234.         H = manhattan_distance(child1, goalState, N);
  235.         // cout << "Ajung aici?";
  236.         //printData(child1, outputFilePath);
  237.         Tree.push_back(Node(child1, "UP", curState.G + 1, H, N, &curState));
  238.     }
  239.     if (!child2.empty())
  240.     {
  241.         H = manhattan_distance(child2, goalState, N);
  242.         // cout << "Ajung aici?";
  243.         //printData(child2, outputFilePath);
  244.         Tree.push_back(Node(child2, "DOWN", curState.G + 1, H, N, &curState));
  245.     }
  246.     if (!child3.empty())
  247.     {
  248.         H = manhattan_distance(child3, goalState, N);
  249.         // cout << "Ajung aici?";
  250.         //printData(child3, outputFilePath);
  251.         Tree.push_back(Node(child3, "LEFT", curState.G + 1, H, N, &curState));
  252.     }
  253.     if (!child4.empty())
  254.     {
  255.         H = manhattan_distance(child4, goalState, N);
  256.         // cout << "Ajung aici?";
  257.         //printData(child4, outputFilePath);
  258.         Tree.push_back(Node(child4, "RIGHT", curState.G + 1, H, N, &curState));
  259.     }
  260.     //dbg(level);
  261.     // for (auto itr = Tree.begin(); itr != Tree.end(); ++itr) {
  262.     //  cout << itr->curState << "\n";
  263.     // }
  264. }
  265.  
  266. int findIndex(Node c, vector<Node> list)
  267. {
  268.     for (int i = 0; i < list.size(); ++i)
  269.     {
  270.         if (list[i].curState == c.curState)
  271.         {
  272.             return i;
  273.         }
  274.     }
  275. }
  276.  
  277. bool checkForDuplicates(Node node, vector<Node> List)
  278. {
  279.     for (auto itr = List.begin(); itr < List.end(); ++itr)
  280.     {
  281.         if (node.curState == itr->curState)
  282.             return true;
  283.     }
  284.     return false;
  285. }
  286.  
  287. bool cmp(Node A, Node B)
  288. {
  289.     return A.H + A.G < B.H + B.G;
  290. }
  291.  
  292. void aStar(Node input, vector<vector<int>> goalState, int N, string outputFilePath)
  293. {
  294.     vector<Node> openList, closedList;
  295.     openList.push_back(input);
  296.     int contor = 0;
  297.     while (!openList.empty())
  298.     {
  299.         contor++;
  300.         dbg(contor);
  301.         auto min = min_element(openList.begin(), openList.end(), cmp);
  302.         Node process = *min;
  303.         if (process.curState == goalState || process.H == 0)
  304.         {
  305.             cout << contor << endl;
  306.             printData(process.curState, outputFilePath);
  307.             // while (process.parent)
  308.             // {
  309.             //  printData(process.parent->curState, outputFilePath);
  310.             //  process = *(process.parent);
  311.             // }
  312.             return;
  313.         }
  314.         openList.erase(min);
  315.         closedList.push_back(process);
  316.         vector<Node> Tree;
  317.         getChilds(process, N, Tree, outputFilePath, goalState);
  318.         cout << Tree.size();
  319.         for (int i = 0; i < Tree.size(); ++i)
  320.         {
  321.             if (!checkForDuplicates(Tree[i], openList))
  322.             {
  323.                 openList.push_back(Tree[i]);
  324.             }
  325.             else
  326.             {
  327.                 Node curNode = openList[findIndex(Tree[i], openList)];
  328.                 if (Tree[i].G < curNode.G)
  329.                 {
  330.                     curNode = Tree[i];
  331.                 }
  332.             }
  333.         }
  334.     }
  335. }
  336.  
  337. Node readData(string filePath, int &N, vector<vector<int>> &goalState)
  338. {
  339.     vector<vector<int>> givenState;
  340.     cout << "Care este calea fisierului de intrare: ";
  341.     cin >> filePath;
  342.     ifstream fin;
  343.     fin.open(filePath, ios::in);
  344.     if (!fin)
  345.     {
  346.         cerr << "Eroare la deschiderea fisierului " << filePath;
  347.         exit(EXIT_FAILURE);
  348.     }
  349.     fin >> N;
  350.     vector<vector<int>> X(N, vector<int>(N));
  351.     goalState.resize(N, vector<int>(N));
  352.     for (int i = 0; i < N; ++i)
  353.     {
  354.         for (int j = 0; j < N; ++j)
  355.         {
  356.             fin >> X[i][j];
  357.             goalState[i][j] = (N * i + j + 1) % (N * N);
  358.         }
  359.     }
  360.     Node input(X, "None", 0, 0, N, nullptr);
  361.     int H = manhattan_distance(input.curState, goalState, N);
  362.     input.H = H;
  363.     fin.close();
  364.     return input;
  365. }
  366.  
  367.  
  368. int main()
  369. {
  370.     int N;
  371.     string inputFilePath, outputFilePath;
  372.     vector<vector<int>> goalState;
  373.     Node input = readData(inputFilePath, N, goalState);
  374.     cout << "Care este calea fisierului de iesire: "; cin >> outputFilePath;
  375.     if (isSolvable(input.curState, N))
  376.     {
  377.         aStar(input, goalState, N, outputFilePath);
  378.         return 0;
  379.     }
  380.     else
  381.     {
  382.         cerr << "Puzzle-ul introdus nu este rezolvabil!";
  383.         exit(EXIT_FAILURE);
  384.     }
  385.     // int N;
  386.     // vector<vector<int>> curState;
  387.     // string inputFilePath, outputFilePath;
  388.     // curState = readData(inputFilePath, N);
  389.     // dbg(curState);
  390.     // if (isSolvable(curState, N))
  391.     // {
  392.     //  cout << "\nCare este calea fisierului de iesire: ";
  393.     //  cin >> outputFilePath;
  394.     //  printData(curState, outputFilePath);
  395.     //  int level = 0;
  396.     //  vector<pair<vector<vector<int>>, int>> Tree;
  397.     //  Tree.push_back(make_pair(curState, level));
  398.     //  dbg(Tree);
  399.     //  getChilds(curState, N, level, Tree, outputFilePath);
  400.     //  if (checkForDuplicates(Tree) == false)
  401.     //  {
  402.     //      cout << "Au fost gasite duplicate";
  403.     //  }
  404.     //  else cout << "Nu exista duplicate";
  405.     //  return 0;
  406.     // }
  407.     // else
  408.     // {
  409.     //  cerr << "Puzzle-ul introdus nu este rezolvabil!";
  410.     //  exit(EXIT_FAILURE);
  411.     // }
  412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement