Pierre: Solving Problems By Intelligent Search


Realized in 2017 Tags: c, A*

concept_of_pierre

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 c because it is fast and I combine it with a high-level approach oriented to object programming, through the use of struct, void pointer and function pointers.

Index


States and Actions

Before we start talking about strategies to solve problems, we must introduce the basic elements of the problem:
I represented these concepts in the source code in this way:
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).

Formulating problems

Now let's talk about the problem description that the software needs to solve it:


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).

Node Structure

Each algorithm does not work directly on the problem but works on a graph where each node contains information about the respective status of the problem.
Now we see the internal structure of the node:


I represented these concepts in the source code in this way:
 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).

Internal logic

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 
                       
            
            

Implemented Algorithms


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: