diff --git a/README.md b/README.md index c93bf68..690b3e1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,153 @@ # ai_search_alg - Breadth-first search, Depth-first search, Best-first search and A-Star search algorithms implemented in C + + + + Breadth-first search, Depth-first search, Best-first search, A-Star search algorithms and AVL Trees implemented in C + +For explanation of the entire code and results see the (paper)[https://drive.google.com/file/d/1QkLSCXCTiIJq6H3SxUDSYmt1hnOC6S2y/view?usp=sharing] (59 pages). + +## Integer Register Processor + + +This project is about a processor with a single register that stores non-negative integer values. Only a specific set of operations can be applied to this register, which are the following: + +* Increment by one +* Decrement by one +* Double +* Halve +* Square +* Square root + +The goal of the program is to accept two values, the starting and the final state, and return the steps that need to be executed to reach this final state. + +Algorithms that solve this problem are search algorithms in Artificial Intelligence, uninformed and informed search algorithms. Specifically, the Breadth-first search, Depth-first search, Best-first search and A-Star search algorithms were implemented in C language. + +To run the program, you need to select 4 things along with the command line, the search algorithm, the initial state, the final state and finally the name of the file where the possible solution will be written (if found due to the time limit of 60 seconds). A clearer way to execute it is shown below: + +``` +REGISTERS.EXE +``` + +Where < alg > can take the values breadth, depth, best and star. + +For example: + +``` +REGISTERS.EXE depth 30000 250000 dp.txt +``` + +## Search Tree + +The algorithms mentioned above are 'built' on a tree called a search tree. The search tree is a structure that contains a set of the state space. Each node of the search tree is a state in the state space and each edge corresponds to an action. Each state can be connected to another, this connection is represented in the tree with the parent and the child table. + +The limits of the state set are from 0 to 10^9. + +## Search Frontier + +Each algorithm needs a structure that allows the storage and retrieval of elements and states from the search tree. This structure is called the search frontier and is used by the algorithms to access states. Each algorithm has different needs, for this reason, the most suitable structure was chosen with the main criterion being speed. In uninformed search algorithms, a linked list satisfies these needs as it allows the insertion and deletion of specific positions in the list. The main need here is a structure that can be used as a queue and stack. All that is needed are two pointers that point to the beginning and end of the list. But what if a value needs to be found based on criteria? A list like this does not cover this issue comfortably as it requires a thorough search from start to finish, something that as the algorithm progresses, the list grows with a consequent delay to a great extent. For informed search algorithms, the balanced tree structure was used so that the element could be found as quickly as possible. Specifically, an AVL balanced tree structure was implemented. + +## AVL TREE + +AVL trees are a special case of height-balanced trees p = 1. For a binary tree to be called height-balanced p, the difference between the heights of its two subtrees must be at most p for each node of the tree. Then, both the left and right subtrees are called p-trees. That is, for AVL trees, the difference between the height of the left and right nodes must be at most or equal to one (1). A notable advantage of these trees is that insertion, searching and deletion from a balanced AVL tree with n nodes can be done in the worst case in time proportional to 𝑂(log2 𝑛). This means that its behavior is approximately that of a perfectly balanced binary search tree (ΜιĪƒĪ…ĪÎģÎŽĪ‚, 2022, pp. 271–273). + +Each node of the AVL tree also carries a balance factor. When a subtree of the node contains more nodes than the other, the notional balance of the tree 'tilts', i.e. the subtree has more weight than the other, causing similar behavior to a simple binary search tree. + +## Breadth First Search + +!["Breadth first search algorithm showing its frontier"](img/breadth.png) + +The breadth-first algorithm first examines the states that are at the same depth of the tree and only when it has examined all of them, it continues to examine the states that are at the next depth of the tree. One could say that the search resembles waves that start from the first left level of the tree to the right and then continue to the next lower depth (ΒΛΑΧΑΒΑÎŖ et al., 2020). + +The search frontier is a linked list that starts from the first NULL node and adds new nodes after it. This list will be used as a FIFO (First In First Out) queue structure, as the main key of the algorithm is to place new states at the back and extract elements from the front. Thus, no new state will be expanded unless those that are at a smaller depth are expanded first. + + + +## Depth First Search + +!["Depth fisrt search"](img/depth.png) + +As its name suggests, the Depth First Search algorithm chooses to expand the state that is deepest in the tree and specifically chooses the leftmost one first. + +The search frontier in the Depth First Search algorithm is used as a stack. This means that the last state entered into the frontier is the first to be extracted. This creates the behavior in the algorithm, as it expands the nodes and adds them to the frontier, the next one that will be extracted for expansion will always be the leftmost one at the next depth. + + +## Greedy Best First Search + + +The heuristic mechanism is a strategy based on the knowledge of the problem in order to solve it quickly. For the Best First Search algorithm, the heuristic function is used to calculate the remaining distance from the current node, i.e. ℎ = |𝑐đ‘ĸ𝑟𝑟𝑒𝑛𝑡𝑆𝑡𝑎𝑡𝑒 → 𝐷𝑎𝑡𝑎 − 𝑓𝑖𝑛𝑎𝑙_𝑆𝑡𝑎𝑡𝑒| and the lowest value is selected. This assumes that it is closer to the goal as it is an estimate of the actual distance without including any possible obstacles. + + +## A * (Star) + +!["a star distance"](img/paradektos.png) + +The A* search algorithm is optimal, which means that it will always find the solution with the lowest cost. This algorithm belongs to the same category as Best First Search. The difference is that the cost that has been traveled from the beginning to the current state is added to the heuristic value, i.e.: 𝑓(𝑆) = 𝑔(𝑆) + ℎ(𝑆) where 𝑔(𝑆) is the distance from the beginning to the current state and ℎ(𝑆) is a heuristic function as in the Best First Search algorithm.  +In order for the algorithm to be optimal in terms of cost, it must be admissible, i.e. it must never overestimate the cost. In this case, using the same heuristic function from the Best First Search algorithm, the cost is overestimated. Suppose that the initial state is 25 and the final state is 5. If this heuristic function were used, it would calculate the estimate ℎ = 25 − 5 = 20 while the actual cost to reach 5 is 6, by performing only one action of this square root √25 = 5 âˆļ 𝑐𝑜𝑠𝑡 = 6. This does not guarantee that it will find the optimal solution. A solution to this problem is to divide the heuristic function ℎ by 4. In this way the estimate is smaller than the real cost + +## Comparative Analysis of Algorithms + +!["Stats given by the programme testing"](img/stats.png) + +The following is a comparison of the algorithms presented. For the comparison, initial and final states were selected, where the initial states are initially increased in a similar and steady manner. This is done to more easily show any differences between them. The algorithms were run on Windows 11 Home version 23H2 software. During the execution, no other application was running in order to have as much available memory and computing power as possible. The processor is an 11th generation Intel-i5 with a speed of 2.40GHz and available RAM of 15.8GB. The application is built on a x64 bit architecture. + + +### Comparing the Total Steps of Solutions + +!["Comparing Algorithm steps to solution"](img/steps_diag.png) + +Comparing the total number of steps required to solve the problem, we conclude that the Breadth First Search algorithm is the most efficient, with the smallest number of steps compared to all others. + +This is expected, as for each level of the search tree, the algorithm searches for the solution across its entire width. Therefore, any solution found will be the shortest possible in terms of the number of steps. We can say that Breadth First Search is optimal regarding the solution steps. + +Next comes the A* algorithm, which in the first test found the same distance as Breadth First Search, but then its steps increased. A* does not find solutions based on steps (number of actions) but according to the cost. There may be a short path to the final state, but if it is too costly, it tries to find a cheaper path by avoiding it. + +The worst algorithms regarding the total solution steps are the Greedy Best First Search and then Depth First Search. + +Interestingly, the number of steps in the Depth First Search solution equals the difference between the initial and final states. This is explained by the way the search tree is structured. The path it follows is that of increasing by one, as this is the leftmost action. + +In the case where the final state is behind the initial state, the algorithm will access all states until it reaches a dead end. Then, it continues to the next right node, but since we keep the accessed states, it will continue to expand states that are before the initial state. + + + +### Time Complexity Analysis + +!["Time took to find solution"](img/time_stats.png) + +In terms of the time required to find a solution, the algorithms do not differ when the solution is close to the initial state (tests 1 and 2). + +Generally, the time to find a solution increases as the distance between the initial and final states increases. This is not necessarily the case with the Breadth First Search algorithm. Although the distance between the two states increases, it does not necessarily mean that it becomes slower. This indicates a non-strong (but not weak) correlation between the solution distance and the solution time, as also shown by the correlation value of -0.223, which is close to 0 (CORREL function - Microsoft Support). + +This can be explained by the number of actions that can be applied to a state. Some actions that could "bypass" time are squaring and square root because they create a large "jump" of states. + +In conclusion, the mean value was calculated for uninformed and informed search algorithms. As it turns out, informed algorithms are on average 1.37 times faster than uninformed algorithms. It should be noted that the results from the above are limited to the sample size. + +### Cost Analysis + +!["Total cost of solution"](img/cost_stats.png) + +There is no doubt that the cost of the solution is always the cheapest in A*. + +The Depth First Search algorithm is the worst of all, due to its "blind" search method, it finds solutions with many steps. This of course also causes the high cost. + + +## Visual Studio 2022 + +Microsoft Visual Studio Community 2022 version 17.9.0 Preview 1.0 was used to write the code. Although the code was written in C, the Visual C++ 2022 compiler was used, i.e. the library scope is that of C++ and not C. This is explained because it may not be compatible with other compiler versions. + + +# GNU GENERAL PUBLIC LICENSE + + *Copyright (C) 2024 Bill Chamalidis* + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . diff --git a/REGISTERS/.vs/REGISTERS/FileContentIndex/403ea74a-3427-435f-888a-31773e77e60f.vsidx b/REGISTERS/.vs/REGISTERS/FileContentIndex/403ea74a-3427-435f-888a-31773e77e60f.vsidx new file mode 100644 index 0000000..19aa516 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/FileContentIndex/403ea74a-3427-435f-888a-31773e77e60f.vsidx differ diff --git a/REGISTERS/.vs/REGISTERS/FileContentIndex/78869303-09a2-445a-be85-6dca799770f1.vsidx b/REGISTERS/.vs/REGISTERS/FileContentIndex/78869303-09a2-445a-be85-6dca799770f1.vsidx new file mode 100644 index 0000000..e7843cf Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/FileContentIndex/78869303-09a2-445a-be85-6dca799770f1.vsidx differ diff --git a/REGISTERS/.vs/REGISTERS/FileContentIndex/d3df9fa7-6210-4b6c-b079-cf44a1a015c5.vsidx b/REGISTERS/.vs/REGISTERS/FileContentIndex/d3df9fa7-6210-4b6c-b079-cf44a1a015c5.vsidx new file mode 100644 index 0000000..453346d Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/FileContentIndex/d3df9fa7-6210-4b6c-b079-cf44a1a015c5.vsidx differ diff --git a/REGISTERS/.vs/REGISTERS/FileContentIndex/f28a2927-f4fd-413c-87f8-cd5bc1a4df3a.vsidx b/REGISTERS/.vs/REGISTERS/FileContentIndex/f28a2927-f4fd-413c-87f8-cd5bc1a4df3a.vsidx new file mode 100644 index 0000000..11d2383 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/FileContentIndex/f28a2927-f4fd-413c-87f8-cd5bc1a4df3a.vsidx differ diff --git a/REGISTERS/.vs/REGISTERS/FileContentIndex/f8c170d9-708f-4777-a9ae-0423a41f4a3a.vsidx b/REGISTERS/.vs/REGISTERS/FileContentIndex/f8c170d9-708f-4777-a9ae-0423a41f4a3a.vsidx new file mode 100644 index 0000000..2d1f31f Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/FileContentIndex/f8c170d9-708f-4777-a9ae-0423a41f4a3a.vsidx differ diff --git a/REGISTERS/.vs/REGISTERS/v17/.suo b/REGISTERS/.vs/REGISTERS/v17/.suo new file mode 100644 index 0000000..4ee438b Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/.suo differ diff --git a/REGISTERS/.vs/REGISTERS/v17/DocumentLayout.json b/REGISTERS/.vs/REGISTERS/v17/DocumentLayout.json new file mode 100644 index 0000000..9268af2 --- /dev/null +++ b/REGISTERS/.vs/REGISTERS/v17/DocumentLayout.json @@ -0,0 +1,153 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\AI_algorithms.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\register.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\register.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_List.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\Forehead_List.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\Search_Tree.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AVL_Tree.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\AVL_Tree.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_AVL.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\Forehead_AVL.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\AI_algorithms.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{55A62834-7079-4E60-B15D-39EC9AE12E78}|REGISTERS\\REGISTERS.vcxproj|solutionrelative:REGISTERS\\Search_Tree.c||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 522, + "SelectedChildIndex": 1, + "Children": [ + { + "$type": "Bookmark", + "Name": "ST:0:0:{d78612c7-9962-4b83-95d9-268046dad23a}" + }, + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "AI_algorithms.h", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.h", + "RelativeDocumentMoniker": "REGISTERS\\AI_algorithms.h", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.h", + "RelativeToolTip": "REGISTERS\\AI_algorithms.h", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAA0AAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-01-07T21:39:00.244Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "register.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\register.c", + "RelativeDocumentMoniker": "REGISTERS\\register.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\register.c", + "RelativeToolTip": "REGISTERS\\register.c", + "ViewState": "AQIAABUAAAAAAAAAAAAAAFYAAAAKAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-07T14:31:32.117Z" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "Forehead_List.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_List.c", + "RelativeDocumentMoniker": "REGISTERS\\Forehead_List.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_List.c", + "RelativeToolTip": "REGISTERS\\Forehead_List.c", + "ViewState": "AQIAAAAAAAAAAAAAAAAAAFoAAAABAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-07T12:21:02.91Z" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "AI_algorithms.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.c", + "RelativeDocumentMoniker": "REGISTERS\\AI_algorithms.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AI_algorithms.c", + "RelativeToolTip": "REGISTERS\\AI_algorithms.c", + "ViewState": "AQIAAJ8BAAAAAAAAAAAAAF4BAAAeAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-06T06:46:07.227Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "Search_Tree.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.c", + "RelativeDocumentMoniker": "REGISTERS\\Search_Tree.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.c", + "RelativeToolTip": "REGISTERS\\Search_Tree.c", + "ViewState": "AQIAAHIAAAAAAAAAAAAAABkAAAASAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-06T06:45:40.769Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "AVL_Tree.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AVL_Tree.c", + "RelativeDocumentMoniker": "REGISTERS\\AVL_Tree.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\AVL_Tree.c", + "RelativeToolTip": "REGISTERS\\AVL_Tree.c", + "ViewState": "AQIAAAYAAAAAAAAAAAAAABoAAAAIAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-04T21:46:56.206Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "Forehead_AVL.c", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_AVL.c", + "RelativeDocumentMoniker": "REGISTERS\\Forehead_AVL.c", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Forehead_AVL.c", + "RelativeToolTip": "REGISTERS\\Forehead_AVL.c", + "ViewState": "AQIAAAAAAAAAAAAAAAAAACAAAAAiAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000423|", + "WhenOpened": "2023-12-04T21:37:24.917Z" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "Search_Tree.h", + "DocumentMoniker": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.h", + "RelativeDocumentMoniker": "REGISTERS\\Search_Tree.h", + "ToolTip": "C:\\Users\\basil\\Documents\\Github\\ai_search_alg\\REGISTERS\\REGISTERS\\Search_Tree.h", + "RelativeToolTip": "REGISTERS\\Search_Tree.h", + "ViewState": "AQIAAAAAAAAAAAAAAAAAABoAAAAAAAAA", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2023-12-06T06:45:33.622Z" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/Browse.VC.db b/REGISTERS/.vs/REGISTERS/v17/Preview/Browse.VC.db new file mode 100644 index 0000000..e7757b8 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/Browse.VC.db differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/Solution.VC.db b/REGISTERS/.vs/REGISTERS/v17/Preview/Solution.VC.db new file mode 100644 index 0000000..07ea4e4 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/Solution.VC.db differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/1e3e4dad955b5419/LINKEDTREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/1e3e4dad955b5419/LINKEDTREE.ipch new file mode 100644 index 0000000..e6c5696 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/1e3e4dad955b5419/LINKEDTREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2329704ede9893cc/SEARCH_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2329704ede9893cc/SEARCH_TREE.ipch new file mode 100644 index 0000000..a5e5324 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2329704ede9893cc/SEARCH_TREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c184b57c7fda7a2/AVL_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c184b57c7fda7a2/AVL_TREE.ipch new file mode 100644 index 0000000..bd9098c Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c184b57c7fda7a2/AVL_TREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c185257c7fdb387/AVL_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c185257c7fdb387/AVL_TREE.ipch new file mode 100644 index 0000000..d689570 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/2c185257c7fdb387/AVL_TREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/4070f0fedc85e4de/REGISTER.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/4070f0fedc85e4de/REGISTER.ipch new file mode 100644 index 0000000..59f5fca Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/4070f0fedc85e4de/REGISTER.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/45b3787161d63ce4/REGISTER.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/45b3787161d63ce4/REGISTER.ipch new file mode 100644 index 0000000..9f345df Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/45b3787161d63ce4/REGISTER.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/559f83c83c2f502e/FOREHEAD_LIST.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/559f83c83c2f502e/FOREHEAD_LIST.ipch new file mode 100644 index 0000000..493b117 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/559f83c83c2f502e/FOREHEAD_LIST.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5759caeafb5c262e/AVL_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5759caeafb5c262e/AVL_TREE.ipch new file mode 100644 index 0000000..7f47c0a Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5759caeafb5c262e/AVL_TREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5bcdc6fb7e0f4e86/FOREHEAD_AVL.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5bcdc6fb7e0f4e86/FOREHEAD_AVL.ipch new file mode 100644 index 0000000..019e9d9 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/5bcdc6fb7e0f4e86/FOREHEAD_AVL.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/61172399b44b8ecf/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/61172399b44b8ecf/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..51b584b Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/61172399b44b8ecf/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7039747a30590d1d/FOREHEAD_AVL.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7039747a30590d1d/FOREHEAD_AVL.ipch new file mode 100644 index 0000000..f651875 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7039747a30590d1d/FOREHEAD_AVL.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7b2f8eaadf732076/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7b2f8eaadf732076/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..fe6e276 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7b2f8eaadf732076/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7f7be94caa364154/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7f7be94caa364154/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..08d3046 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/7f7be94caa364154/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/8cfccaf8870515a5/AVL_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/8cfccaf8870515a5/AVL_TREE.ipch new file mode 100644 index 0000000..5c36e97 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/8cfccaf8870515a5/AVL_TREE.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/912781e8cf464beb/REGISTER.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/912781e8cf464beb/REGISTER.ipch new file mode 100644 index 0000000..20da927 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/912781e8cf464beb/REGISTER.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86886d8018b03c/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86886d8018b03c/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..3d20756 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86886d8018b03c/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86936d8018c2ed/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86936d8018c2ed/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..10b95ca Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/9f86936d8018c2ed/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/a6ff32acaef33599/BST.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/a6ff32acaef33599/BST.ipch new file mode 100644 index 0000000..575640b Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/a6ff32acaef33599/BST.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/abd8831cccdb0c2d/AIALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/abd8831cccdb0c2d/AIALGORITHMS.ipch new file mode 100644 index 0000000..f99a69b Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/abd8831cccdb0c2d/AIALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/b517ee9cd7c4a21d/LINKEDLIST.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/b517ee9cd7c4a21d/LINKEDLIST.ipch new file mode 100644 index 0000000..3c5cd29 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/b517ee9cd7c4a21d/LINKEDLIST.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/c0d9a3fddf280c4/FOREHEAD_LIST.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/c0d9a3fddf280c4/FOREHEAD_LIST.ipch new file mode 100644 index 0000000..00ecdde Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/c0d9a3fddf280c4/FOREHEAD_LIST.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cd6cb3f12a17582d/REGISTER.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cd6cb3f12a17582d/REGISTER.ipch new file mode 100644 index 0000000..9ebf578 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cd6cb3f12a17582d/REGISTER.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cf34bc9d5f3a71f0/RBT.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cf34bc9d5f3a71f0/RBT.ipch new file mode 100644 index 0000000..b54f83e Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cf34bc9d5f3a71f0/RBT.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cfef4a50c93c8d3c/AI_ALGORITHMS.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cfef4a50c93c8d3c/AI_ALGORITHMS.ipch new file mode 100644 index 0000000..d212b03 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/cfef4a50c93c8d3c/AI_ALGORITHMS.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/e5f74eb72b1c80ed/LINKEDNODELIST.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/e5f74eb72b1c80ed/LINKEDNODELIST.ipch new file mode 100644 index 0000000..17acb2b Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/e5f74eb72b1c80ed/LINKEDNODELIST.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700eff2a0fdd9c2/FOREHEAD_AVL.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700eff2a0fdd9c2/FOREHEAD_AVL.ipch new file mode 100644 index 0000000..642a129 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700eff2a0fdd9c2/FOREHEAD_AVL.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700f6f2a0fde5a7/FOREHEAD_AVL.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700f6f2a0fde5a7/FOREHEAD_AVL.ipch new file mode 100644 index 0000000..cd4db41 Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/f700f6f2a0fde5a7/FOREHEAD_AVL.ipch differ diff --git a/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/fad08c4853187ab6/SEARCH_TREE.ipch b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/fad08c4853187ab6/SEARCH_TREE.ipch new file mode 100644 index 0000000..4ec71fe Binary files /dev/null and b/REGISTERS/.vs/REGISTERS/v17/Preview/ipch/AutoPCH/fad08c4853187ab6/SEARCH_TREE.ipch differ diff --git a/REGISTERS/REGISTERS.sln b/REGISTERS/REGISTERS.sln new file mode 100644 index 0000000..d9809b3 --- /dev/null +++ b/REGISTERS/REGISTERS.sln @@ -0,0 +1,31 @@ +īģŋ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34302.71 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "REGISTERS", "REGISTERS\REGISTERS.vcxproj", "{55A62834-7079-4E60-B15D-39EC9AE12E78}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Debug|x64.ActiveCfg = Debug|x64 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Debug|x64.Build.0 = Debug|x64 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Debug|x86.ActiveCfg = Debug|Win32 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Debug|x86.Build.0 = Debug|Win32 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Release|x64.ActiveCfg = Release|x64 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Release|x64.Build.0 = Release|x64 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Release|x86.ActiveCfg = Release|Win32 + {55A62834-7079-4E60-B15D-39EC9AE12E78}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1665706B-7709-4B13-9C39-FBB0137189E2} + EndGlobalSection +EndGlobal diff --git a/REGISTERS/REGISTERS/AI_algorithms.c b/REGISTERS/REGISTERS/AI_algorithms.c new file mode 100644 index 0000000..b773c8e --- /dev/null +++ b/REGISTERS/REGISTERS/AI_algorithms.c @@ -0,0 +1,523 @@ +#include +#include +#include +#include +#include + +#include "AI_algorithms.h" + +/* + * DEBUG 1: + * Shows Pop and insert actions performed by the algorithms. + * Also shows how search tree is created with values. + * Execution time becomes slow. + */ +#define DEBUG 0 +#define TIMEOUT 60 // 1 min execution time + +int get_method(char* s) +{ + int i = -1; + if (strcmp(s, "breadth") == 0) + i = breadth; + else if (strcmp(s, "depth") == 0) + i = depth; + else if (strcmp(s, "best") == 0) + i = best; + else if (strcmp(s, "astar") == 0) + i = astar; + else printf("\nINFO: No method found."); + return i; +} + +clock_t tStart; +clock_t tEnd; + +void timer_start() +{ + tStart = clock(); +} + +bool timer_tick() +{ + bool timer = true; + clock_t t = clock(); + if (t - tStart > CLOCKS_PER_SEC * TIMEOUT) + { + printf("\n = = = TIME OUT = = = "); + timer = false; + } + return timer; +} + +void timer_end() +{ + tEnd = clock(); +} + +/* + * Function: printSolution + * ---------------------------- + * Prints the steps of a solution, along with + * the count of steps and the total cost of the solution. + * + * Parameters: + * - final_state: Pointer to the final state SearchTreeNode of the solution. + * - fileout: File pointer for output (where the results will be printed). + */ +void printSolution(SearchTreeNode* final_state, FILE* fileout) +{ + if (final_state == NULL) + return; + + int count = 0, sumCost = 0, child_pos, prev = -1, intrCount = 0; + SearchTreeNode* p = final_state; + LinkedNodeList* steps; + create_LinkedList(&steps); + + /* + * Each situation that led to the solution is placed on the + * stack upside down. From the state of the solution to the + * initial. + */ + while (p != NULL) + { + steps = insert_LinkedList(steps, p); + if (get_parent(p) != NULL) + count++; + + p = get_parent(p); + } + + sumCost = final_state->totalCost; + + (void)fprintf(fileout, "%d, %d", count, sumCost); + (void)printf("\n< < PRINTING SOLUTION > >"); + + /* + * After the steps of the solution were inserted into the + * variable 'steps,' which is of linked list type, we remove + * them in reverse order from the sequence in which they were + * added like a stack. One element is removed at a time, and + * it is checked whether the SearchTreeNode has a child. If it does not + * have a child because it is the root, the iteration continues + * on the child, if it exists. The value of the previous SearchTreeNode + * from the tree is printed using the operator that was executed + * to generate the child or the solution. The iteration continues + * until the entire 'steps' list is empty. + */ + while (!isEmpty(steps)) + { + p = pop_LinkedList(&steps); + child_pos = getChildPosition(p); + if (child_pos != -1) + { + /* + * Retrieve the string representation of the instruction + * that led from the parent to the current SearchTreeNode. + */ + char* instr = get_instruction_ToString(child_pos); + + (void)fprintf(fileout, "\n%s, %d, %d", instr, + p->parent->data, get_cost_to_childi(p->parent, child_pos)); + + if (prev != child_pos) + { + if (intrCount != 0) // Avoid the first loop + (void)printf("\n\t X %d TIMES the upper function", intrCount); + + (void)printf("\n %s, %d, %d => %d", instr, + p->parent->data, get_cost_to_childi(p->parent, child_pos), p->data); + + intrCount = 1; + } + else + intrCount++; + + // Free the allocated memory from string pointer get_instruction_ToString + free(instr); + } + prev = child_pos; + } + (void)printf("\n\t X %d TIMES the upper function", intrCount); + + (void)printf("\nSteps count = %d, \tTotal Cost = %d, \tTime: %f sec", count, sumCost, (float)(tEnd - tStart)/CLOCKS_PER_SEC); + + free(steps); +} + + +void Breadth_First_Search(int init, int fin, FILE* fileout) +{ + timer_start(); + + int loopCount = 0; + SearchTreeNode* root = NULL, * currentState = NULL; + root = create_root(init); + LinkedNodeList* frontier = NULL; + + // Initialise frontier + create_LinkedList(&frontier); + const LinkedNodeList* front = frontier; + // Insert the ROOT to stack list + frontier = insert_LinkedList(frontier, root); + + // Save the states to break infinity loops, only copies the data + AVL_node* loopList; + initialize_AVL(&loopList); + + // Solution found + bool flag = false; + + printf("\n************************" + "\n* BREADTH FIRST SEARCH *" + "\n************************"); + + + while (!isEmpty(frontier) && !flag && timer_tick()) + { + // Pop the front state of the frontier (forehead search) + currentState = pop_LinkedList(&frontier); + + #if DEBUG + printf("\nPop: %d", currentState->data); + #endif + + // If the SearchTreeNode is inside the border or already checked then loop + if (!dataExists_AVL(loopList, currentState->data)) + { + // Copy Data to loopList to avoid loops + loopList = insert_avl_node(loopList, currentState->data); + + // Check the SOLUTION + if (currentState->data == fin) + { + printf("\nINFO: Solution found in Breadth!"); + flag = true; + break; + } + + // Expand children and connect to their parent + produce_childrens(currentState); + + // Put children in the !BACK! of forehead + /* + * Because the new nodes are added + * in the middle of the list (to + * the left of null), they reverse + * themselves by adding them in. + */ + for (int i = 0; i <= 5; i++) + { + if (get_childi(currentState, i) != NULL) { + + (void)insert_LinkedList(front, get_childi(currentState, i)); + + #if DEBUG + printf("\n%d new child[%d] -> %d", currentState->data, i, currentState->child[i]->data); + #endif + } + else + { + #if DEBUG + printf("\n%d nul child[%d] -> NULL", currentState->data, i); + #endif + } + } + } + loopCount++; + + traverseToFront(&frontier); + } + + timer_end(); + + printf("\nSum steps: %d", loopCount); + + // Free the memory + free(frontier); + free(loopList); + + if (!flag) + printf("\nINFO: No solutions found in Breadth"); + else + printSolution(currentState, fileout); + + free(root); +} + +void Depth_First_Search(int init, int fin, FILE* fileout) +{ + timer_start(); + + int loopCount = 0; + SearchTreeNode* root = NULL, * currentState = NULL; + root = create_root(init); + LinkedNodeList* frontier = NULL; + + // Initialise frontier + create_LinkedList(&frontier); + // Insert the ROOT to stack list + frontier = insert_LinkedList(frontier, root); + + // Save the states to break infinity loops, only copies the data + AVL_node* loopList; + initialize_AVL(&loopList); + + // Solution found + bool flag = false; + + printf("\n**********************" + "\n* DEPTH FIRST SEARCH *" + "\n**********************"); + + while (!isEmpty(frontier) && !flag && timer_tick()) + { + // Get execute the front state of the frontier (forehead search) + currentState = pop_LinkedList(&frontier); + + #if DEBUG + printf("\nPop: %d", currentState->data); + #endif + + // If the SearchTreeNode is inside the border or the value already checked then loop + if (!dataExists_AVL(loopList, currentState->data)) + { + // Copy Data to loopList to avoid loops + loopList = insert_avl_node(loopList, currentState->data); + + // Check the SOLUTION + if (currentState->data == fin) + { + printf("\nINFO: Solution found in depth!"); + flag = true; + break; + } + + // If more solutions goto loop + // . . . + + // Expand children and connect to their parent + produce_childrens(currentState); + + // Put children in the !FRONT! of forehead + for (int i = 5; i >= 0; i--) + { + if (get_childi(currentState, i) != NULL) { + + frontier = insert_LinkedList(frontier, get_childi(currentState, i)); + #if DEBUG + printf("\n%d new child[%d] -> %d", currentState->data, i, frontier->node->data); + #endif + + } + else { + #if DEBUG + printf("\n%d nul child[%d] -> NULL", currentState->data, i); + #endif + } + + + } + } + loopCount++; + + // If no new children produced or infinity-loop, the SearchTreeNode will be deleted + if (!has_children(currentState)) + nodeDeleteBranch(¤tState); + } + + timer_end(); + + printf("\nSum steps: %d", loopCount); + + // Free the memory + free(frontier); + free(loopList); + + if (!flag) + printf("\nINFO: No solutions found in depth"); + else + printSolution(currentState, fileout); + + free(root); +} + +void Best_First_Search(int init, int fin, FILE* fileout) +{ + timer_start(); + + int loopCount = 0; + SearchTreeNode* root = NULL, * currentState = NULL; + root = create_root(init); + AVLF_node* frontier = NULL; + + // Initialise frontier + initialize_AVLF(&frontier, bestFS, fin); + + // Insert the ROOT to frontier search + frontier = insert_AVLF_node(frontier, root); + + // Solution found + bool flag = false; + + printf("\n*********************" + "\n* BEST FIRST SEARCH *" + "\n*********************"); + + while (!AVLF_isEmpty(frontier) && !flag && timer_tick()) + { + // Get execute the front state of the frontier (forehead search) + currentState = Pop_min(&frontier); + + #if DEBUG + printf("\nPop: %d", currentState->data); + #endif + + // Check the SOLUTION + if (currentState->data == fin) + { + printf("\nINFO: Solution found in Best!"); + flag = true; + break; + } + + // If more solutions goto loop + // . . . + + // Expand children and connect to their parent + produce_childrens(currentState); + + // Put children in the forehead + for (int i = 5; i >= 0; i--) + { + if (get_childi(currentState, i) != NULL) { + + frontier = insert_AVLF_node(frontier, get_childi(currentState, i)); + + #if DEBUG + printf("\n%d new child[%d] -> %d, \th(%d)", currentState->data, i, + currentState->child[i]->data, heuristic(currentState->child[i])); + #endif + } + else + { + #if DEBUG + printf("\n%d nul child[%d] -> NULL", currentState->data, i); + #endif + } + } + + loopCount++; + } + + timer_end(); + + printf("\nSum steps: %d", loopCount); + + // Free the memory + free(frontier); + + if (!flag) + printf("\nINFO: No solutions found in Best"); + else + printSolution(currentState, fileout); + + free(root); +} + +void AStar_Search(int init, int fin, FILE* fileout) +{ + timer_start(); + + int loopCount = 0; + SearchTreeNode* root = NULL, * currentState = NULL; + root = create_root(init); + AVLF_node* frontier = NULL; + + // Initialise frontier + initialize_AVLF(&frontier, astarS, fin); + // Insert the ROOT to AVL forehead + frontier = insert_AVLF_node(frontier, root); + + // Save the states to break infinity loops, only copies the data + AVLF_node* innerList = NULL; + initialize_AVLF(&innerList, astarS, fin); + + // Solution found + bool flag = false; + + printf("\n*****************" + "\n* A Star SEARCH *" + "\n*****************"); + + while (!AVLF_isEmpty(frontier) && !flag && timer_tick()) + { + // Get execute the front state of the frontier (forehead search) + currentState = Pop_min(&frontier); + + #if DEBUG + printf("\nPop: %d", currentState->data); + #endif + + // If the SearchTreeNode is checked then loop + if (!dataExistAstar_AVLF(innerList, currentState)) + { + // Copy Data to loopList to avoid loops + innerList = insert_norm_AVLF_node(innerList, currentState); + + // Check the SOLUTION + if (currentState->data == fin) + { + printf("\nINFO: Solution found in A Star!"); + flag = true; + break; + } + + // If more solutions goto loop + // . . . + + // Expand children and connect to their parent + produce_childrens(currentState); + + // Put children in the forehead + for (int i = 5; i >= 0; i--) + { + if (get_childi(currentState, i) != NULL) { + + frontier = insert_AVLF_node(frontier, get_childi(currentState, i)); + + #if DEBUG + printf("\n%d new child[%d] -> %d, \t%d=%d+%d", currentState->data, i, currentState->child[i]->data, f(currentState->child[i]), + currentState->child[i]->totalCost, heuristic(currentState->child[i])); + #endif + + } + else + { + #if DEBUG + printf("\n%d nul child[%d] -> NULL", currentState->data, i); + #endif + } + } + } + + loopCount++; + } + + timer_end(); + + printf("\nSum steps: %d", loopCount); + + // Free structures from memory + free(innerList); + free(frontier); + + if (!flag) + printf("\nINFO: No solutions found in A Star"); + else + printSolution(currentState, fileout); + + // Free search tree + free(root); +} diff --git a/REGISTERS/REGISTERS/AI_algorithms.h b/REGISTERS/REGISTERS/AI_algorithms.h new file mode 100644 index 0000000..39e80b4 --- /dev/null +++ b/REGISTERS/REGISTERS/AI_algorithms.h @@ -0,0 +1,21 @@ +#pragma once + +#include "Forehead_AVL.h" +#include "AVL_Tree.h" + +enum +{ + breadth, depth, best, astar +}; + +int get_method(char* s); + +void printSolution(SearchTreeNode* finState, FILE* fileout); + +void Depth_First_Search(int init, int fin, FILE* fileout); + +void Breadth_First_Search(int init, int fin, FILE* fileout); + +void Best_First_Search(int init, int fin, FILE* fileout); + +void AStar_Search(int init, int fin, FILE* fileout); \ No newline at end of file diff --git a/REGISTERS/REGISTERS/AVL_Tree.c b/REGISTERS/REGISTERS/AVL_Tree.c new file mode 100644 index 0000000..ac91458 --- /dev/null +++ b/REGISTERS/REGISTERS/AVL_Tree.c @@ -0,0 +1,137 @@ +#include +#include + +#include "AVL_Tree.h" + +int getHeight(AVL_node* n) { + if (n == NULL) + return 0; + return n->height; +} + +void initialize_AVL(AVL_node** n) +{ + *n = NULL; +} + +bool AVL_isEmpty(AVL_node* n) +{ + return n == NULL; +} + +int getMaxHeight(AVL_node* n) +{ + int i = 0; + if (n != NULL) + i = max(getHeight(n->lchild), getHeight(n->rchild)); + else + printf("\nWARNING: Cannot get height from NULL AVLF node"); + return i; +} + +AVL_node* create_avl_node(int key) { + + AVL_node* node = (AVL_node*)malloc(sizeof(AVL_node)); + if (node == NULL) + { + printf("\nERROR: Cannot allocate more memory!"); + exit(1); + } + + node->data = key; + node->lchild = NULL; + node->rchild = NULL; + node->height = 1; + return (node); +} + +AVL_node* rightRotate(AVL_node* n) { + AVL_node* x = n->lchild; + AVL_node* y = x->rchild; + + x->rchild = n; + n->lchild = y; + + n->height = getMaxHeight(n) + 1; + x->height = getMaxHeight(x) + 1; + + return x; +} + +AVL_node* leftRotate(AVL_node* n) { + AVL_node* x = n->rchild; + AVL_node* y = x->lchild; + + x->lchild = n; + n->rchild = y; + + n->height = getMaxHeight(n) + 1; + x->height = getMaxHeight(x) + 1; + + return x; +} + +int getBalance(AVL_node* n) { + return n == NULL ? 0 : getHeight(n->lchild) - getHeight(n->rchild); +} + +AVL_node* insert_avl_node(AVL_node* n, int keyValue) { + + if (n == NULL) + return (create_avl_node(keyValue)); + + if (keyValue < n->data) + n->lchild = insert_avl_node(n->lchild, keyValue); + else if (keyValue > n->data) + n->rchild = insert_avl_node(n->rchild, keyValue); + else + return n; + + n->height = 1 + getMaxHeight(n); + + // Reconstruct Tree + int balance = getBalance(n); + if (balance > 1 && keyValue < n->lchild->data) + return rightRotate(n); + + if (balance < -1 && keyValue > n->rchild->data) + return leftRotate(n); + + if (balance > 1 && keyValue > n->lchild->data) { + n->lchild = leftRotate(n->lchild); + return rightRotate(n); + } + + if (balance < -1 && keyValue < n->rchild->data) { + n->rchild = rightRotate(n->rchild); + return leftRotate(n); + } + + return n; +} + +AVL_node* get_min_value(AVL_node* node) { + + AVL_node* current = node; + while (current->lchild != NULL) + current = current->lchild; + + return current; +} + +bool dataExists_AVL(AVL_node* root, int keyValue) +{ + bool found = false; + while (!found && !AVL_isEmpty(root)) + { + if (root->data == keyValue) + { + found = true; + } + else if (keyValue > root->data) + root = root->rchild; + else + root = root->lchild; + } + return found; +} \ No newline at end of file diff --git a/REGISTERS/REGISTERS/AVL_Tree.h b/REGISTERS/REGISTERS/AVL_Tree.h new file mode 100644 index 0000000..757e795 --- /dev/null +++ b/REGISTERS/REGISTERS/AVL_Tree.h @@ -0,0 +1,33 @@ +#pragma once +#include + +typedef int Data; + +typedef struct Node { + Data data; + int height; + struct Node* lchild; + struct Node* rchild; +} AVL_node; + +int getHeight(AVL_node* n); + +int getMaxHeight(AVL_node* n); + +void initialize_AVL(AVL_node** n); + +bool AVL_isEmpty(AVL_node* n); + +AVL_node* create_avl_node(int key); + +AVL_node* rightRotate(AVL_node* n); + +AVL_node* leftRotate(AVL_node* n); + +int getBalance(AVL_node* n); + +AVL_node* insert_avl_node(AVL_node* n, int keyValue); + +AVL_node* get_min_value(AVL_node* node); + +bool dataExists_AVL(AVL_node* root, int keyValue); \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Debug/AI_algorithms.obj b/REGISTERS/REGISTERS/Debug/AI_algorithms.obj new file mode 100644 index 0000000..af663d4 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/AI_algorithms.obj differ diff --git a/REGISTERS/REGISTERS/Debug/AVL_Tree.obj b/REGISTERS/REGISTERS/Debug/AVL_Tree.obj new file mode 100644 index 0000000..74b7af8 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/AVL_Tree.obj differ diff --git a/REGISTERS/REGISTERS/Debug/Forehead_AVL.obj b/REGISTERS/REGISTERS/Debug/Forehead_AVL.obj new file mode 100644 index 0000000..09009a0 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/Forehead_AVL.obj differ diff --git a/REGISTERS/REGISTERS/Debug/Forehead_List.obj b/REGISTERS/REGISTERS/Debug/Forehead_List.obj new file mode 100644 index 0000000..b99ff32 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/Forehead_List.obj differ diff --git a/REGISTERS/REGISTERS/Debug/REGISTERS.log b/REGISTERS/REGISTERS/Debug/REGISTERS.log new file mode 100644 index 0000000..33fa954 --- /dev/null +++ b/REGISTERS/REGISTERS/Debug/REGISTERS.log @@ -0,0 +1,18 @@ +īģŋ AI_algorithms.c + AVL_Tree.c + Forehead_AVL.c + Forehead_List.c + register.c + Search_Tree.c + Generating Code... +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\register.c(15,10): error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\register.c(31,10): error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\register.c(39,10): error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\register.c(56,10): error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(239,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(242,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(245,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(248,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(251,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(254,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c(258,9): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. diff --git a/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/CL.command.1.tlog b/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/CL.command.1.tlog new file mode 100644 index 0000000..6679a68 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/CL.command.1.tlog differ diff --git a/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/REGISTERS.lastbuildstate b/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/REGISTERS.lastbuildstate new file mode 100644 index 0000000..34a1dd8 --- /dev/null +++ b/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/REGISTERS.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native32Bit:VCToolsVersion=14.39.33218:TargetPlatformVersion=10.0.22621.0: +Debug|Win32|C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\| diff --git a/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/unsuccessfulbuild b/REGISTERS/REGISTERS/Debug/REGISTERS.tlog/unsuccessfulbuild new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/Debug/vc143.idb b/REGISTERS/REGISTERS/Debug/vc143.idb new file mode 100644 index 0000000..f285518 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/vc143.idb differ diff --git a/REGISTERS/REGISTERS/Debug/vc143.pdb b/REGISTERS/REGISTERS/Debug/vc143.pdb new file mode 100644 index 0000000..ce576c6 Binary files /dev/null and b/REGISTERS/REGISTERS/Debug/vc143.pdb differ diff --git a/REGISTERS/REGISTERS/Forehead_AVL.c b/REGISTERS/REGISTERS/Forehead_AVL.c new file mode 100644 index 0000000..db38167 --- /dev/null +++ b/REGISTERS/REGISTERS/Forehead_AVL.c @@ -0,0 +1,360 @@ +#pragma once +#include +#include +#include + +#include "Forehead_AVL.h" + +#include "AVL_Tree.h" + +int getHeightF(AVLF_node* n) { + return n == 0 ? 0 : n->height; +} + +void initialize_AVLF(AVLF_node** n, int i, int f) +{ + *n = NULL; + /* + * i=0 heuristic for best + * i=1 f=g+h for A-Star + */ + option = i; + // Final state + fin_State = f; +} + +bool AVLF_isEmpty(AVLF_node* n) +{ + return n == NULL; +} + +AVLF_node* create_AVLF_node(SearchTreeNode* n) { + + AVLF_node* node = (AVLF_node*)malloc(sizeof(AVLF_node)); + if (node == NULL) + { + printf("\nERROR: Cannot allocate more memory!"); + exit(1); + } + + node->clone = NULL; + node->node = n; + node->lchild = NULL; + node->rchild = NULL; + node->height = 1; + return node; +} + +int getMaxHeightF(AVLF_node* n) +{ + int i = 0; + if (n != NULL) + i = max(getHeightF(n->lchild), getHeightF(n->rchild)); + else + printf("\nWARNING: Cannot get height from NULL AVLF node"); + return i; +} + +AVLF_node* rightRotateF(AVLF_node* n) { + AVLF_node* x = n->lchild; + AVLF_node* y = x->rchild; + + x->rchild = n; + n->lchild = y; + + n->height = getMaxHeightF(n) + 1; + x->height = getMaxHeightF(x) + 1; + + return x; +} + +AVLF_node* leftRotateF(AVLF_node* n) { + AVLF_node* x = n->rchild; + AVLF_node* y = x->lchild; + + x->lchild = n; + n->rchild = y; + + n->height = getMaxHeightF(n) + 1; + x->height = getMaxHeightF(x) + 1; + + return x; +} + +int getBalanceF(AVLF_node* n) { + return n == NULL ? 0 : getHeightF(n->lchild) - getHeightF(n->rchild); +} + +/* + * Because the AVL tree structure is used, + * the search for the smallest element will always be found + * on the left side of the tree. + */ +AVLF_node* get_min_value_node(AVLF_node* node) { + + AVLF_node* current = node; + + while (!AVLF_isEmpty(current->lchild)) + current = current->lchild; + + return current; +} + +AVLF_node* delete_AVLF_Node(AVLF_node* root, int keyValue) { + + if (root != NULL) + { + if (keyValue < getData_AVLF(root)) + root->lchild = delete_AVLF_Node(root->lchild, keyValue); + else if (keyValue > getData_AVLF(root)) + root->rchild = delete_AVLF_Node(root->rchild, keyValue); + else { // equal == + if (!isEmpty(root->clone)) + { + /* + * When the SearchTreeNode to be deleted has a linked list, + * instead of deleting the tree SearchTreeNode, + * the value is removed (POP) from the list and replaces the value of the AVL tree (node). + * The process continues until all are removed from the list, + * then the SearchTreeNode of the AVL tree can be deleted. + */ + LinkedNodeList* ntemp = root->clone; + ntemp = ntemp->next; + root->node = pop_LinkedList(&ntemp); + } + else if (root->lchild == NULL || root->rchild == NULL) { + + AVLF_node* temp = NULL; + + // Both children are NULL + if (root->lchild == NULL && root->rchild == NULL) { + /* + * In the previous IF condition, it is examined whether the node + * has at most one child. Therefore, if it has two children, it + * does not pass through the IF but through the ELSE. + */ + temp = root; + root = NULL; + } + else + { + // Get no NULL child + temp = root->lchild != NULL ? root->lchild : root->rchild; + *root = *temp; + } + + free(temp); + } + else { + // The node has two children + AVLF_node* temp = get_min_value_node(root->rchild); + // Replace the node from min + root->node = temp->node; + // Replace the clone, if not exist then must be NULL + root->clone = temp->clone; + // new node for deletion + // the node may has at most one child because it is from minimum right -> left leaf + root->rchild = delete_AVLF_Node(root->rchild, getData_AVLF(temp)); + } + } + } + + // Reconstruct Tree + if (root != NULL) + { + root->height = 1 + max(getHeightF(root->lchild), getHeightF(root->rchild)); + + int balance = getBalanceF(root); + + if (balance > 1 && getBalanceF(root->lchild) >= 0) + return rightRotateF(root); + + if (balance > 1 && getBalanceF(root->lchild) < 0) { + root->lchild = leftRotateF(root->lchild); + return rightRotateF(root); + } + + if (balance < -1 && getBalanceF(root->rchild) <= 0) + return leftRotateF(root); + + if (balance < -1 && getBalanceF(root->rchild) > 0) { + root->rchild = rightRotateF(root->rchild); + return leftRotateF(root); + } + } + + return root; +} + +// === === === INSERT === === === // +AVLF_node* insert_AVLF_node(AVLF_node* n, SearchTreeNode* nleaf) { + + if (n == NULL) // + return (create_AVLF_node(nleaf)); + + if (getSTData(nleaf) < getData_AVLF(n)) + n->lchild = insert_AVLF_node(n->lchild, nleaf); + else if (getSTData(nleaf) > getData_AVLF(n)) + n->rchild = insert_AVLF_node(n->rchild, nleaf); + else // equals + { + /* + * In a tree structure, duplicate values are not allowed. + * + * Since we need duplicate values and the AVL tree has good complexity, + * when the same value appears in a SearchTreeNode of a tree, + * a linked list is attached to that SearchTreeNode to keep the same values. + */ + if (n->clone == NULL) + create_LinkedList(&n->clone); + (void)insert_LinkedList(n->clone, nleaf); + + return n; + } + + // Reconstruct tree while getting close to root + if (!AVLF_isEmpty(n)) + { + n->height = 1 + max(getHeightF(n->lchild), getHeightF(n->rchild)); + + int balance = getBalanceF(n); + + // Left Left Case + if (balance > 1 && getSTData(nleaf) < getData_AVLF(n->lchild)) + return rightRotateF(n); + + // Right Right Case + if (balance < -1 && getSTData(nleaf) > getData_AVLF(n->rchild)) + return leftRotateF(n); + + // Left Right Case + if (balance > 1 && getSTData(nleaf) > getData_AVLF(n->lchild)) { + n->lchild = leftRotateF(n->lchild); + return rightRotateF(n); + } + + // Right Left Case + if (balance < -1 && getSTData(nleaf) < getData_AVLF(n->rchild)) { + n->rchild = rightRotateF(n->rchild); + return leftRotateF(n); + } + } + + return n; +} + +int heuristic(SearchTreeNode* n) +{ + int i = 0; + if (n != NULL) + { + if (option == 0) + i = abs(n->data - fin_State); + else // A Star + i = (int)(floor((float)abs(n->data - fin_State) / 4)); + + } + else + (void)printf("\nWARNING: Cannot get heuristic value from a null SearchTreeNode state"); + + return i; +} + +int f(SearchTreeNode* n) +{ + int i = 0; + // f = g + h + if (n != NULL) + i = n->totalCost + heuristic(n); + else + (void)printf("\nWARNING: Cannot get f value from a null node"); + + return i; +} + +int getData_AVLF(AVLF_node* n) +{ + if (option == bestFS) + return heuristic(n->node); + return f(n->node); +} + +int getSTData(SearchTreeNode* n) +{ + if (option == bestFS) + return heuristic(n); + return f(n); +} + +SearchTreeNode* Pop_min(AVLF_node** n) +{ + AVLF_node* mnode = get_min_value_node(*n); + SearchTreeNode* temp = mnode->node; + *n = delete_AVLF_Node(*n, getData_AVLF(mnode)); + return temp; +} + +bool dataExistAstar_AVLF(AVLF_node* root, SearchTreeNode* n) +{ + bool found = false; + while (!found && !AVLF_isEmpty(root)) + { + if (root->node->data == n->data) + { + found = true; + + if (f(n) < f(root->node) || f(n) == f(root->node) && heuristic(n) < heuristic(root->node)) + { + root->node = n; + found = false; + break; + } + } + else if (n->data > root->node->data) + root = root->rchild; + else + root = root->lchild; + } + return found; +} + +/* + * In addition to the existing structures, we need a copy of this function to + * store and sort values based on their real values.This function is used for A* + * so that we can also calculate the costs. + */ +AVLF_node* insert_norm_AVLF_node(AVLF_node* n, SearchTreeNode* nleaf) { + + if (n == NULL) + return (create_AVLF_node(nleaf)); + + if (nleaf->data < n->node->data) + n->lchild = insert_norm_AVLF_node(n->lchild, nleaf); + else if (nleaf->data > n->node->data) + n->rchild = insert_norm_AVLF_node(n->rchild, nleaf); + else // equals + return n; + + if (!AVLF_isEmpty(n)) + { + n->height = 1 + max(getHeightF(n->lchild), getHeightF(n->rchild)); + + int balance = getBalanceF(n); + if (balance > 1 && nleaf->data < n->lchild->node->data) + return rightRotateF(n); + + if (balance < -1 && nleaf->data > n->rchild->node->data) + return leftRotateF(n); + + if (balance > 1 && nleaf->data > n->lchild->node->data) { + n->lchild = leftRotateF(n->lchild); + return rightRotateF(n); + } + + if (balance < -1 && nleaf->data < n->rchild->node->data) { + n->rchild = rightRotateF(n->rchild); + return leftRotateF(n); + } + } + return n; +} diff --git a/REGISTERS/REGISTERS/Forehead_AVL.h b/REGISTERS/REGISTERS/Forehead_AVL.h new file mode 100644 index 0000000..5cad72b --- /dev/null +++ b/REGISTERS/REGISTERS/Forehead_AVL.h @@ -0,0 +1,53 @@ +#pragma once + +#include "Forehead_List.h" + +typedef int Data; + +int option, fin_State; + +enum {bestFS, astarS}; + +typedef struct NodeF { + SearchTreeNode* node; + int height; + LinkedNodeList* clone; + struct NodeF* lchild; + struct NodeF* rchild; +} AVLF_node; + +int getHeightF(AVLF_node* n); + +int getMaxHeightF(AVLF_node* n); + +void initialize_AVLF(AVLF_node** n, int i, int f); + +bool AVLF_isEmpty(AVLF_node* n); + +int getData_AVLF(AVLF_node*); + +int getSTData(SearchTreeNode*); + +int heuristic(SearchTreeNode*); + +AVLF_node* create_AVLF_node(SearchTreeNode* n); + +AVLF_node* rightRotateF(AVLF_node* n); + +AVLF_node* leftRotateF(AVLF_node* n); + +int getBalanceF(AVLF_node* n); + +AVLF_node* get_min_value_node(AVLF_node* node); + +AVLF_node* delete_AVLF_Node(AVLF_node* root, int keyValue); + +AVLF_node* insert_AVLF_node(AVLF_node* n, SearchTreeNode* nleaf); + +int f(SearchTreeNode* n); + +SearchTreeNode* Pop_min(AVLF_node** n); + +bool dataExistAstar_AVLF(AVLF_node* root, SearchTreeNode* n); + +AVLF_node* insert_norm_AVLF_node(AVLF_node* n, SearchTreeNode* nleaf); \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Forehead_List.c b/REGISTERS/REGISTERS/Forehead_List.c new file mode 100644 index 0000000..8cf4f2b --- /dev/null +++ b/REGISTERS/REGISTERS/Forehead_List.c @@ -0,0 +1,124 @@ +#pragma once +#include +#include + +#include "Forehead_List.h" + +/* + * It is required before using the structure + * that the first null SearchTreeNode has been created. + * In this way, other nodes can be added. + */ +void create_LinkedList(LinkedNodeList** root) +{ + LinkedNodeList* temp = (LinkedNodeList*)malloc(sizeof(LinkedNodeList)); + + if (temp == NULL) { + printf("\nERROR: Linked List cannot be created"); + exit(EXIT_FAILURE); + } + + temp->next = NULL; + temp->previous = NULL; + temp->node = NULL; + *root = temp; +} + +/* + * Creates a new LinkedNodeList with SearchTreeNode and + * joins it in the list, AFTER the pointer l. + */ +LinkedNodeList* insert_LinkedList(LinkedNodeList* l, SearchTreeNode* n) +{ + LinkedNodeList* nl = (LinkedNodeList*)malloc(sizeof(LinkedNodeList)); + + if (nl == NULL) { + printf("\nERROR: Linked List cannot be inserted"); + exit(EXIT_FAILURE); + } + + nl->node = n; + + if (l->next == NULL) + { + // Insert the list to where it ends + l->next = nl; + nl->next = NULL; + nl->previous = l; + } + else + { + // Insert the list SearchTreeNode between two nodes + nl->next = l->next; + l->next->previous = nl; + l->next = nl; + nl->previous = l; + } + + return nl; +} + +/* + * The LinkedNodeList that is entered as an argument + * to the function is deleted and the previous one is + * returned if it exists (NULL). The referenced SearchTreeNode is + * not deleted. + */ +LinkedNodeList* delete_LinkedList(LinkedNodeList* currentList) +{ + if (currentList == NULL) + { + printf("\nWARNING: Cannot remove from empty list"); + return currentList; + } + + if (currentList->previous != NULL) // The last SearchTreeNode + currentList->previous->next = currentList->next; + if (currentList->next != NULL) // remove between nodes + currentList->next->previous = currentList->previous; + + LinkedNodeList* temp = currentList->previous; // If the last one will be NULL + + // Set pointers to NULL before freeing + currentList->next = NULL; + currentList->previous = NULL; + + free(currentList); + return temp; +} + +bool isEmpty(LinkedNodeList* currList) +{ + bool empty = true; + // If null or not created to be avoided + if (currList != NULL) + empty = currList->previous == NULL && currList->next == NULL; + + return empty; +} + +/* + * Derives the LinkedNodeList it accepts + * as an argument, deletes it, and 1) + * changes the curr pointer to point to + * its predecessor, 2) returns the + * referenced SearchTreeNode from the list + */ +SearchTreeNode* pop_LinkedList(LinkedNodeList** curr) +{ + SearchTreeNode* temp = (*curr)->node; + *curr = delete_LinkedList(*curr); + return temp; +} + +void traverseToFront(LinkedNodeList** l) +{ + while ((*l)->next != NULL) + *l = (*l)->next; +} + +void traverseToBack(LinkedNodeList** l) +{ + while ((*l)->previous != NULL) + *l = (*l)->previous; +} diff --git a/REGISTERS/REGISTERS/Forehead_List.h b/REGISTERS/REGISTERS/Forehead_List.h new file mode 100644 index 0000000..f50ad48 --- /dev/null +++ b/REGISTERS/REGISTERS/Forehead_List.h @@ -0,0 +1,32 @@ +#pragma once + +#include "Search_Tree.h" + +struct LinkedList; + +/* + * This structure is linked + * list with previous and next. + * Each LinkedNodeList has a reference + * to a SearchTreeNode. + */ +typedef struct LinkedList +{ + SearchTreeNode* node; + struct LinkedList* next; + struct LinkedList* previous; +} LinkedNodeList; + +void create_LinkedList(LinkedNodeList** root); + +LinkedNodeList* insert_LinkedList(LinkedNodeList* l, SearchTreeNode* n); + +LinkedNodeList* delete_LinkedList(LinkedNodeList* currentList); + +bool isEmpty(LinkedNodeList* currList); + +SearchTreeNode* pop_LinkedList(LinkedNodeList** curr); + +void traverseToFront(LinkedNodeList** l); + +void traverseToBack(LinkedNodeList** l); diff --git a/REGISTERS/REGISTERS/REGISTERS.vcxproj b/REGISTERS/REGISTERS/REGISTERS.vcxproj new file mode 100644 index 0000000..e7dcb91 --- /dev/null +++ b/REGISTERS/REGISTERS/REGISTERS.vcxproj @@ -0,0 +1,149 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {55a62834-7079-4e60-b15d-39ec9ae12e78} + REGISTERS + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + MultiByte + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/REGISTERS.vcxproj.filters b/REGISTERS/REGISTERS/REGISTERS.vcxproj.filters new file mode 100644 index 0000000..d019b4a --- /dev/null +++ b/REGISTERS/REGISTERS/REGISTERS.vcxproj.filters @@ -0,0 +1,54 @@ +īģŋ + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/REGISTERS.vcxproj.user b/REGISTERS/REGISTERS/REGISTERS.vcxproj.user new file mode 100644 index 0000000..dc58743 --- /dev/null +++ b/REGISTERS/REGISTERS/REGISTERS.vcxproj.user @@ -0,0 +1,11 @@ +īģŋ + + + astar 322 475344 out.txt + WindowsLocalDebugger + + + astar 322 475344 out.txt + WindowsLocalDebugger + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Release/REGISTERS.Build.CppClean.log b/REGISTERS/REGISTERS/Release/REGISTERS.Build.CppClean.log new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/Release/REGISTERS.exe.recipe b/REGISTERS/REGISTERS/Release/REGISTERS.exe.recipe new file mode 100644 index 0000000..c0e9f74 --- /dev/null +++ b/REGISTERS/REGISTERS/Release/REGISTERS.exe.recipe @@ -0,0 +1,11 @@ +īģŋ + + + + C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\Release\REGISTERS.exe + + + + + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Release/REGISTERS.log b/REGISTERS/REGISTERS/Release/REGISTERS.log new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/REGISTERS/REGISTERS/Release/REGISTERS.log @@ -0,0 +1 @@ +īģŋ \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Release/REGISTERS.vcxproj.FileListAbsolute.txt b/REGISTERS/REGISTERS/Release/REGISTERS.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/Search_Tree.c b/REGISTERS/REGISTERS/Search_Tree.c new file mode 100644 index 0000000..e944b69 --- /dev/null +++ b/REGISTERS/REGISTERS/Search_Tree.c @@ -0,0 +1,260 @@ +#pragma once +#include +#include +#include +#include +#include + +#include "Search_Tree.h" + +const int MAX = 1000000000; +const int MIN = 0; + + +bool values_in_bound(Data d) +{ + return (d > MIN && d < MAX); +} + +/* + * Before using the algorithmic tree it is required + * to create the root first. The same root is returned. + */ +SearchTreeNode* create_root(int init) +{ + SearchTreeNode* root = (SearchTreeNode*)malloc(sizeof(SearchTreeNode)); + if (root == NULL) + { + printf("\nERROR: Cannot allocate more memory!"); + exit(1); + } + + root->data = init; // Initial State is the ROOT + root->parent = NULL; // Root does not have a parent + root->pos = -1; // There is no parent + root->totalCost = 0; // Zero cost in root + for (int i = 0; i <= 5; i++) { + root->child[i] = NULL; // All children are pointed to NULL + root->cost[i] = 0; + } + return root; +} + +/* + * returns the child's father + */ +SearchTreeNode* get_parent(SearchTreeNode* n) +{ + return n->parent; +} + +/* + * returns the child i + */ +SearchTreeNode* get_childi(SearchTreeNode* n, int i) +{ + return n->child[i]; +} + +/* + * returns the cost for the child i + */ +int get_cost_to_childi(SearchTreeNode* n, int i) +{ + return n->cost[i]; +} + +/* + * Creates a child of the parent SearchTreeNode referenced by + * its argument. The cost is the cost of creating + * the child and the data is added to it. The place + * to be placed in the array is determined by the childPlace. + */ +SearchTreeNode create_child(SearchTreeNode* parent, int cost, Data data, int childPlace) +{ + // Create a memory chunk + SearchTreeNode* newChild = (SearchTreeNode*)malloc(sizeof(SearchTreeNode)); + if (newChild == NULL) + { + printf("\nERROR: Cannot allocate more memory!"); + exit(EXIT_FAILURE); + } + + // Add the data to the SearchTreeNode + newChild->data = data; + + // The initial cost to a child depending on the act + parent->cost[childPlace] = cost; + newChild->totalCost = parent->totalCost + cost; + + // Connect Parent and child + parent->child[childPlace] = newChild; + newChild->parent = parent; + + // Position child from parent array + newChild->pos = childPlace; + + // The new child created by the SearchTreeNode is the new border + for (int i = 0; i <= 5; i++) { + newChild->child[i] = NULL; + newChild->cost[i] = 0; + } + + return *newChild; +} + +/* + * Creates all children by performing the mathematical + * operators allowed. Father is the SearchTreeNode entered as an + * argument to the function. If the SearchTreeNode is not allowed + * to execute the operands, no change is made. + */ +void produce_childrens(SearchTreeNode* parent) +{ + // #1 Plus X+1 + if (parent->data < MAX) + create_child(parent, 2, parent->data + 1, 0); + + // #2 Minus X-1 + if (parent->data > MIN) + create_child(parent, 2, parent->data - 1, 1); + + // #3 Mult 2*X + if (parent->data > 0 && 2 * parent->data <= MAX) + create_child(parent, ((int)ceil((float)parent->data / 2) + 1), + parent->data * 2, 2); + + // #4 Floor Div [X/2] + if (parent->data > MIN) + create_child(parent, ((int)ceil((float)parent->data / 4) + 1), + (Data)floor((float)parent->data / 2), 3); + + //#5 Power X^2 + if (pow(parent->data, 2) <= MAX) + create_child(parent, ((int)pow(parent->data, 2) - parent->data) / 4 + 1, + (Data)pow(parent->data, 2), 4); + + //#6 Square Root Sqrt(x) + if (sqrt(parent->data) == ((int)(sqrt(parent->data))) && parent->data > 1) + create_child(parent, (parent->data - (int)sqrt(parent->data)) / 4 + 1, + (Data)sqrt(parent->data), 5); +} + +/* + * Returns true if the SearchTreeNode has at least 1 child, + * otherwise returns false for none. + */ +bool has_children(SearchTreeNode* parent) +{ + bool childFound = false; + int i = 0; + if (parent != NULL) + while (i <= 5 && !childFound) + { + if (parent->child[i] != NULL) + childFound = true; + i++; + } + return childFound; +} + +/* + * When a SearchTreeNode has no children it indicates that it + * is on the border. + */ +bool is_boundary_set(SearchTreeNode* n) +{ + return !has_children(n); +} + +/* + * It goes one level higher to his parent, + * then the child is searched and the location + * is returned. -1 for no parent (root). + */ +int getChildPosition(SearchTreeNode* child) +{ + int i = -1; + + if (child == NULL) + printf("\nINFO: Child is null. Returning -1"); + else if (child->parent == NULL) + printf("\nINFO: There is no parent to get child loc. Returning -1"); + else + { + i = child->pos; + } + return i; +} + +/* + * This function is only used by depth-first-search. + * In the depth-first algorithm the tested nodes + * must be deleted. In the following function, it + * deletes the specific SearchTreeNode given as an argument + * to it. An additional function of this function + * is to also check if the father has no other + * children. If he has no other children then based + * on the algorithm he should be deleted as well. + * The function continues at a higher level and + * stops when a father is found that he have at + * least one child. + */ +void nodeDeleteBranch(SearchTreeNode** n) +{ + // Do not delete a parent with children + if (!has_children(*n)) + { + SearchTreeNode* parent = get_parent(*n); + // Unlink parent to his child + parent->child[getChildPosition(*n)] = NULL; + Data d = (*n)->data; + free(*n); + // Recursive call to a higher level + // It will stop when it finds parent with children + nodeDeleteBranch(&parent); + (void)printf("\nINFO: Node %d deleted successfully ", d); + } +} + +/* + * Returns the name instruction by the number place + * of child. The allocation of memory must be freed. + */ +char* get_instruction_ToString(int i) +{ + char* c = (char*)malloc(sizeof(char) * 9); + if (c == NULL) + { + printf("\nERROR: Cannot allocate more memory!"); + exit(EXIT_FAILURE); + } + + switch (i) + { + case INCREASE: + (void)strcpy(c, "increase"); + break; + case DECREASE: + (void)strcpy(c, "decrease"); + break; + case DOUBLE: + (void)strcpy(c, "double"); + break; + case HALF: + (void)strcpy(c, "half"); + break; + case SQUARE: + (void)strcpy(c, "square"); + break; + case ROOT: + (void)strcpy(c, "root"); + break; + default: + printf("\nINFO: Not instruction found."); + (void)strcpy(c, "NoInstr"); + break; + } + + return c; +} \ No newline at end of file diff --git a/REGISTERS/REGISTERS/Search_Tree.h b/REGISTERS/REGISTERS/Search_Tree.h new file mode 100644 index 0000000..20230b9 --- /dev/null +++ b/REGISTERS/REGISTERS/Search_Tree.h @@ -0,0 +1,54 @@ +#pragma once +#include + +#define INCREASE 0 +#define DECREASE 1 +#define DOUBLE 2 +#define HALF 3 +#define SQUARE 4 +#define ROOT 5 + +const int MAX; +const int MIN; + +// kind int for Data +typedef unsigned int Data; + +/* + * The structure is a tree where a SearchTreeNode can have + * from none to 6 children. Each child of the SearchTreeNode + * is assigned a cost to it. Each SearchTreeNode has a parent + * other than the root. + */ +typedef struct tree { + Data data; + struct tree* child[6]; + int cost[6]; + int totalCost; // is g for A* algorithm + int pos; + struct tree* parent; +} SearchTreeNode; + +bool values_in_bound(Data d); + +SearchTreeNode* create_root(int init); + +SearchTreeNode* get_parent(SearchTreeNode* n); + +SearchTreeNode* get_childi(SearchTreeNode* n, int i); + +int get_cost_to_childi(SearchTreeNode* n, int i); + +SearchTreeNode create_child(SearchTreeNode* parent, int cost, Data data, int childPlace); + +void produce_childrens(SearchTreeNode* parent); + +bool has_children(SearchTreeNode* parent); + +bool is_boundary_set(SearchTreeNode* n); + +int getChildPosition(SearchTreeNode* child); + +void nodeDeleteBranch(SearchTreeNode** n); + +char* get_instruction_ToString(int i); \ No newline at end of file diff --git a/REGISTERS/REGISTERS/register.c b/REGISTERS/REGISTERS/register.c new file mode 100644 index 0000000..5fc6b8b --- /dev/null +++ b/REGISTERS/REGISTERS/register.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +#include "AI_algorithms.h" + +void check_input(char **v, int *init, int *fin, int *alg_i, FILE **file) +{ + // Get the state numbers + char *algname; + int initial = -1; + int final = -1; + + algname = v[1]; // Algorithm name + + initial = strtol(v[2], NULL, 10); // string to integer + final = strtol(v[3], NULL, 10); + + *file = fopen(v[4], "w"); + + if (*file == NULL) + { + printf("\nERROR: Cannot open/create file"); + exit(EXIT_FAILURE); + } + + bool flag; + do + { + flag = false; + if (initial > MAX || initial < MIN) + { + flag = true; + printf("\nThe initial state (%d) is out of bound, please enter a proper value: ", initial); + (void)fflush(stdin); + (void)scanf("%d", &initial); + } + + if (final > MAX || final < MIN) + { + flag = true; + printf("\nThe final state (%d) is out of bound, please enter a proper value: ", final); + (void)fflush(stdin); + (void)scanf("%d", &final); + } + } + while (flag); + + do + { + flag = true; + if (strcmp(algname, "breadth") == 0 || strcmp(algname, "depth") == 0 || + strcmp(algname, "best") == 0 || strcmp(algname, "astar") == 0) + flag = false; + + if (flag == true) + { + printf("\nThe algorithm name you entered \"%s\" is not supported, please enter one below:\n" + "breadth (Breadth-First-Search), depth (Depth-First-Search), \nbest (Best First), astar (A*).\n$ ", algname); + fflush(stdin); + (void)scanf("%s", algname); + } + } + while (flag); + + *init = initial; + *fin = final; + *alg_i = get_method(algname); +} + +int main(int argc, char **argv) +{ + int initial_state=0, final_state=0, alg_i; + FILE* fileout = NULL; + + printf ("***************************\n" + "* CHAMALIDIS iis22183 *\n" + "* University of Macedonia *\n" + "***************************\n"); + + if (argc >= 3) + check_input(argv, &initial_state, &final_state, &alg_i, &fileout); + else + { + printf("\nERROR: Not correct input!"); + exit(1); + } + + printf("\nInitial State: %d, Final State: %d\n", initial_state, final_state); + + switch (alg_i) + { + case breadth: + Breadth_First_Search(initial_state, final_state, fileout); + break; + case depth: + Depth_First_Search(initial_state, final_state, fileout); + break; + case best: + Best_First_Search(initial_state, final_state, fileout); + break; + case astar: + AStar_Search(initial_state, final_state, fileout); + break; + default: + printf("\nINFO: Could not find algorithm's index on alg_i"); + break; + } + + (void)fclose(fileout); + + printf("\n\n * * * Program END * * *\n"); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/REGISTERS/REGISTERS/x64/Debug/REGISTERS.Build.CppClean.log b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.Build.CppClean.log new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/x64/Debug/REGISTERS.exe.recipe b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.exe.recipe new file mode 100644 index 0000000..5414f3c --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.exe.recipe @@ -0,0 +1,11 @@ +īģŋ + + + + C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\x64\Debug\REGISTERS.exe + + + + + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/x64/Debug/REGISTERS.log b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.log new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.log @@ -0,0 +1 @@ +īģŋ \ No newline at end of file diff --git a/REGISTERS/REGISTERS/x64/Debug/REGISTERS.vcxproj.FileListAbsolute.txt b/REGISTERS/REGISTERS/x64/Debug/REGISTERS.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/x64/Release/AI_algorithms.obj b/REGISTERS/REGISTERS/x64/Release/AI_algorithms.obj new file mode 100644 index 0000000..be5dd8e Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/AI_algorithms.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/AVL_Tree.obj b/REGISTERS/REGISTERS/x64/Release/AVL_Tree.obj new file mode 100644 index 0000000..f5520e8 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/AVL_Tree.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/Forehead_AVL.obj b/REGISTERS/REGISTERS/x64/Release/Forehead_AVL.obj new file mode 100644 index 0000000..3c95ad3 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/Forehead_AVL.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/Forehead_List.obj b/REGISTERS/REGISTERS/x64/Release/Forehead_List.obj new file mode 100644 index 0000000..e2f8563 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/Forehead_List.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.Build.CppClean.log b/REGISTERS/REGISTERS/x64/Release/REGISTERS.Build.CppClean.log new file mode 100644 index 0000000..133546c --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.Build.CppClean.log @@ -0,0 +1,19 @@ +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\vc143.pdb +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\search_tree.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\register.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\forehead_list.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\forehead_avl.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\avl_tree.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\ai_algorithms.obj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\x64\release\registers.exe +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\x64\release\registers.pdb +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.ipdb +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.iobj +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\cl.command.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\cl.items.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\cl.read.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\cl.write.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\link.command.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\link.read.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\link.secondary.1.tlog +c:\users\basil\documents\visual_studio_and_jetbrains\uom_ai\registers\registers\x64\release\registers.tlog\link.write.1.tlog diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.exe.recipe b/REGISTERS/REGISTERS/x64/Release/REGISTERS.exe.recipe new file mode 100644 index 0000000..43dd1ef --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.exe.recipe @@ -0,0 +1,11 @@ +īģŋ + + + + C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\x64\Release\REGISTERS.exe + + + + + + \ No newline at end of file diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.iobj b/REGISTERS/REGISTERS/x64/Release/REGISTERS.iobj new file mode 100644 index 0000000..fcbee08 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.iobj differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.ipdb b/REGISTERS/REGISTERS/x64/Release/REGISTERS.ipdb new file mode 100644 index 0000000..5d9963b Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.ipdb differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.log b/REGISTERS/REGISTERS/x64/Release/REGISTERS.log new file mode 100644 index 0000000..9b72983 --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.log @@ -0,0 +1,12 @@ +īģŋ AI_algorithms.c +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\AI_algorithms.c(214,35): warning C4090: 'function': different 'const' qualifiers + AVL_Tree.c + Forehead_AVL.c + Forehead_List.c + register.c + Search_Tree.c + Generating code + Previous IPDB not found, fall back to full compilation. + All 62 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. + Finished generating code + REGISTERS.vcxproj -> C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\x64\Release\REGISTERS.exe diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.command.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.command.1.tlog new file mode 100644 index 0000000..533f6aa Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.command.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.read.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.read.1.tlog new file mode 100644 index 0000000..190de23 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.read.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.write.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.write.1.tlog new file mode 100644 index 0000000..6f12868 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/CL.write.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/Cl.items.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/Cl.items.tlog new file mode 100644 index 0000000..5175be1 --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/Cl.items.tlog @@ -0,0 +1,6 @@ +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\AI_algorithms.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\AI_algorithms.obj +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\AVL_Tree.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\AVL_Tree.obj +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Forehead_AVL.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\Forehead_AVL.obj +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Forehead_List.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\Forehead_List.obj +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\register.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\register.obj +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\Search_Tree.c;C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\Search_Tree.obj diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/REGISTERS.lastbuildstate b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/REGISTERS.lastbuildstate new file mode 100644 index 0000000..580c6e0 --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/REGISTERS.lastbuildstate @@ -0,0 +1,2 @@ +PlatformToolSet=v143:VCToolArchitecture=Native64Bit:VCToolsVersion=14.39.33218:TargetPlatformVersion=10.0.22621.0: +Release|x64|C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\| diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.command.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.command.1.tlog new file mode 100644 index 0000000..d929864 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.command.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.read.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.read.1.tlog new file mode 100644 index 0000000..afb7275 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.read.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.secondary.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.secondary.1.tlog new file mode 100644 index 0000000..e5544a4 --- /dev/null +++ b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.secondary.1.tlog @@ -0,0 +1,3 @@ +^C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\AI_ALGORITHMS.OBJ|C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\AVL_TREE.OBJ|C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\FOREHEAD_AVL.OBJ|C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\FOREHEAD_LIST.OBJ|C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\REGISTER.OBJ|C:\USERS\BASIL\DOCUMENTS\VISUAL_STUDIO_AND_JETBRAINS\UOM_AI\REGISTERS\REGISTERS\X64\RELEASE\SEARCH_TREE.OBJ +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\REGISTERS.IPDB +C:\Users\basil\Documents\Visual_Studio_and_JetBrains\UOM_AI\REGISTERS\REGISTERS\x64\Release\REGISTERS.iobj diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.write.1.tlog b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.write.1.tlog new file mode 100644 index 0000000..62425a9 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/REGISTERS.tlog/link.write.1.tlog differ diff --git a/REGISTERS/REGISTERS/x64/Release/REGISTERS.vcxproj.FileListAbsolute.txt b/REGISTERS/REGISTERS/x64/Release/REGISTERS.vcxproj.FileListAbsolute.txt new file mode 100644 index 0000000..e69de29 diff --git a/REGISTERS/REGISTERS/x64/Release/Search_Tree.obj b/REGISTERS/REGISTERS/x64/Release/Search_Tree.obj new file mode 100644 index 0000000..5a58ba0 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/Search_Tree.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/register.obj b/REGISTERS/REGISTERS/x64/Release/register.obj new file mode 100644 index 0000000..ef05758 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/register.obj differ diff --git a/REGISTERS/REGISTERS/x64/Release/vc143.pdb b/REGISTERS/REGISTERS/x64/Release/vc143.pdb new file mode 100644 index 0000000..29d7960 Binary files /dev/null and b/REGISTERS/REGISTERS/x64/Release/vc143.pdb differ diff --git a/REGISTERS/x64/Release/REGISTERS.exe b/REGISTERS/x64/Release/REGISTERS.exe new file mode 100644 index 0000000..540ef71 Binary files /dev/null and b/REGISTERS/x64/Release/REGISTERS.exe differ diff --git a/REGISTERS/x64/Release/REGISTERS.pdb b/REGISTERS/x64/Release/REGISTERS.pdb new file mode 100644 index 0000000..3fb68a7 Binary files /dev/null and b/REGISTERS/x64/Release/REGISTERS.pdb differ diff --git a/img/YJyA9je34KphtizvuebCJW-1200-80.jpg b/img/YJyA9je34KphtizvuebCJW-1200-80.jpg new file mode 100644 index 0000000..fa78cf8 Binary files /dev/null and b/img/YJyA9je34KphtizvuebCJW-1200-80.jpg differ diff --git a/img/breadth.png b/img/breadth.png new file mode 100644 index 0000000..da0716a Binary files /dev/null and b/img/breadth.png differ diff --git a/img/cost_stats.png b/img/cost_stats.png new file mode 100644 index 0000000..004f3c9 Binary files /dev/null and b/img/cost_stats.png differ diff --git a/img/depth.png b/img/depth.png new file mode 100644 index 0000000..01bae31 Binary files /dev/null and b/img/depth.png differ diff --git a/img/paradektos.png b/img/paradektos.png new file mode 100644 index 0000000..02c9916 Binary files /dev/null and b/img/paradektos.png differ diff --git a/img/stats.png b/img/stats.png new file mode 100644 index 0000000..27a8bfa Binary files /dev/null and b/img/stats.png differ diff --git a/img/steps_diag.png b/img/steps_diag.png new file mode 100644 index 0000000..7507fad Binary files /dev/null and b/img/steps_diag.png differ diff --git a/img/time_stats.png b/img/time_stats.png new file mode 100644 index 0000000..004f3c9 Binary files /dev/null and b/img/time_stats.png differ