This project is completely related to the third chapter of Artificial Intelligence A Modern Approach . The idea is to solve any problems without having to re-implement the algorithms every time and to provide a different resolution strategy to solve each problem. To achieve this goal I use
1 2 3 4 5 6 7 8 | typedef struct State { long int id; void* state; } State; typedef struct Action { State* (*move)(State* old_state); } Action; |
(Full code is available here).
NB: some of these functions will not available in "problem" struct but there are needed to support other key functions, just like public and private methods. (For example, the Constraint Test Function used by the Transaction Model)
I represented these concepts in the source code in this way:1 2 3 4 5 6 7 8 9 10 | typedef struct Problem { State* initial_state; long int depth_solution; List* (*transition_functions)(State* state); Boolean (*goal_test)(State* state); void (*print_state)(State* state); int (*heuristic)(State* state); int (*step_cost)(State* state, int cost); int (*state_compare)(void* state1, void* state2); } Problem; |
(Full code is avaible here).
1 2 3 4 5 6 7 8 9 10 | typedef struct IA_Node { long int id; struct State* node_state; struct IA_Node* parent; struct Action* node_action; float path_cost; float heuristic_Cost; float total_cost; struct IA_Node* (*child_ia_node)(struct Problem* problem, struct IA_Node* actual, struct Action* move); } IA_Node; |
(Full code is avaible here).
Pierre (the name came from the pronunciation of PR that stand for Problem Resolver) is just a menu with which the user interacts.
It will print to him a list of the already implemented problem to solve. When he has chosen one of them, it provides him a list of algorithms to use to solve it. (for example, I have already implemented the lake problem and the 8-puzzle problem. The first one is very easy to solve, the second one needs to a heuristic function).
These algorithms use a classic data struct like priority list or red-black tree but also a node struct described above.
The struct node needs to the struct that describes the problem.
So you need to implement the required functions to describe your problem. (we talked about it here)
To do this you need to import a common.h that, in addition to providing functions for creating and use a list, provide also the state and action struct.
//Internal scheme of Pierre
pierre.h
|
algorithms.h
/ | \
/ | \
priority_list.h node.h redblack_tree.h
|
problem.h
|
*Problem_to_solve*
|
common.h
|
list.h
The following paragraph is a list of all the implemented algorithms that can be found in the source code , followed by a brief description:
This entire paragraph is a quote from Solving Problems by Searching - Artificial Intelligence: A Modern Approach (3rd Edition).At the end of the article I left you an example of the running program: