aimon1337

Untitled

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