0% found this document useful (0 votes)
8 views

Implementation Assignment

Uploaded by

rayane raba'a
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Implementation Assignment

Uploaded by

rayane raba'a
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

BEIRUT ARAB UNIVERSITY

EMERGING TOPICS IN ARTIFCIAL INTELLIGENCE

CMPS715

GENERIC SOLVER PROJECT IMPLEMENTATION

PURPOSE:

 Starting first phase of a project that describes a generic algorithm to search for a solution path
in a well formulated search problem. The algorithm is independent of any particular search
strategy and any particular search problem.

IDEA:
The intuitive idea behind the generic search algorithm, given a start node /initial state, and a set of
goal states/nodes, is to incrementally explore paths from the start nodes. However, we do not need
to maintain a tree or graph structure of the explored nodes in order to avoid additional space and
time complexities. We need to find a solution ; i.e. the sequence of actions or transitions that
take us from the initial state to the goal state depending on the search strategy.

search
problem solution
algorithm
 The choice of
strategy can be very important as
to how quickly the problem will be solved, if indeed the problem will be solved at all.

In the first phase you are required to start with creating an abstraction of the various search
algorithms and use it to solve a single specific problem, the 8-puzzle problem. Different tests will
be made with different problem difficulties. The search algorithms will be then benchmarked and
compared.

THE 8-PUZZLE PROBLEM

The 8-puzzle problem is a puzzle popularized by Sam Loyd in the 1870s. It is played on a 3-by-3
grid with 8 square blocks labeled 1 through 8 and a blank square. Your goal is to rearrange the
blocks so that they are in order.

 states? locations of tiles

 initial state? consider the given start state

 actions? move blank (left, right, up, down)

 goal test? consider the given goal state

 path cost? 1 per move


We need to well-formulate the problem as follows:

A state is a representation of a physical configuration of the 8-puzzle board and this may be
considered as a 1x9 array filled with 0, 1, 2, …, 7 or 8, where 0 represents the blank square. A
representation with a matrix of 3x3 is also correct. If you have another suggestion, propose it and
explain your choice.

As for the 1x9 array representation, the given initial state is represented by {7,2,4,5,0,6,8,3,1}.
The given goal state is represented by {0,1,2,3,4,5,6,7,8}.

A successor function: ( state*action--> state) returns the set of states reachable from a specific
state by applying the possible actions. For example, for the state {2, 8, 3, 1, 6, 4, 7, 0, 5},the
function returns the following successors:{2, 8, 3, 1, 0, 4, 7, 6, 5}, {2, 8, 3, 1, 6, 4, 0, 7, 5} and

{2, 8, 3, 1, 6, 4, 7, 5, 0}. These successors correspond to the actions UP, LEFT and RIGHT
respectively, the action DOWN being un-applicable on this state.

Consider a unit cost per action.

MAIN VIEW

Create a main class GenericSolver with method

- private void solve(FormulatedProblem p, SearchAlgorithm alg)


{
alg.solve(p);
}

//Sample main program


GenericSolver s = new GenericSolver();
SearchAlgorithm alg = new BFS(); //can choose any search algorithm
FormulatedProblem p = new EightPuzzleProblem(); //can choose any
predefined formulated problem to be solved
s.solve(p, alg);

We will start with implementing the interfaces and classes for the formulated 8-puzzle problem
then we will move on in parts 2 and 3 of phase I to implement different search algorithms.

PART 1

PROBLEM IMPLEMENTATION

1. Create a class Node containing

- private Object state the state in the state space to which the node corresponds;
- private Node parent the node in the search tree that generated this node

- private int pathCost the cost of the path from the initial state to the node, as
indicated by the parent pointers.

- private Action action the action that was applied to the parent to generate the node

- constructor that sets the values for the four private member variables

- get... four methods that return the values of the four private member variables

- public ArrayList<Node> getPathFromRoot()Returns the path from the root


node to this node.

2. Create an interface Action (similar to abstract class it contains only method prototypes
with no implementation here) where given a particular state s it returns the set of actions that
can be executed in s

- Object apply (Object state); //how to apply each action

- int getCostPerAction(); //cost of specific action

3. Create a class EightPuzzleAction that implements Action

- private string name;


- constructor

@Override
public Object apply(Object state) {
int[] s = (int[]) state;
int blankPosition=0;
int newBlankPosition=0;
// you have to implement it
// should specify explicitly how to apply the UP DOWN LEFT RIGHT actions according to the
position of the "0" tile i.e. blank square
//if this action is the UP action, then...
if (name.equals("UP")) {
// then ...getIndex of 0, and subtract 3 from it
}
}
//Assume first that the cost per action is 1
@Override
public int getCostPerAction(){return 1};
4. Create an interface SuccessorFunction containing

ArrayList<Action> getPossibleApplicableActions(Object state);

Given a particular state s, this method returns the set of possible actions that can be executed for
a given state. We say that each of these actions is applicable in this state.

5. Create a class EightPuzzleSuccessorFunction to implement the


SuccessorFunction interface for the specific eight puzzle problem containing

- private Action UP = new EightPuzzleAction("UP");

// create actions DOWN, LEFT and RIGHT

- public ArrayList<Action> getPossibleApplicableActions(Object


state)

This method should specify explicitly the set of possible applicable actions given a specific state
for the 8-puzzle problem

6. Create an interface FormulatedProblem


- Object getInitialState();
- boolean isGoalState(Object state);to check whether the goal state is reached
- Successorfunction getSuccessorFunction();

7. Create a class EightPuzzleProblem to implement the FormulatedProblem


interface for a specific eight puzzle problem
- Object getInitialState(){//creates and returns an array with initial configuration
of tiles as given above}
- boolean isGoalState(Object state){ //check whether the given 8-puzzle goal
state is reached}
- SuccessorFunction getSuccessorFunction(){//creates and returns an
EightPuzzleSuccessorFunction object}

IDEA - PART 2- IMPLEMENTING UNINFORMED SEARCH ALGORITHMS

The following search algorithms should be implemented:

- Breadth-First,
- Depth-First,
- Iterative Depth, and
- Uniform Cost, or Lowest Cost First.

Each algorithm accomplishes the following steps:

- It builds an initial node pointing to the initial state of the problem


- It then calls iteratively the successor function of the problem to compute the successor
nodes
- Until it reaches a solution; hence, the algorithm has to check for each explored node
whether its state is a solution or not.

The various uninformed search algorithms share many components, mainly:

- The node data structure: state, path from the root state, the total cost of the path, …
- The queue data structure, which is roughly speaking the bag of nodes to be explored at a
given moment.

Clearly, the queues used by the various search algorithms behave differently in terms of how
they push and pop the nodes, which influences the order in which the nodes are visited.

Specifically, the Uniform Cost algorithm uses a priority queue. The priority function is based on
the cost function g that associates to each state the number of moves made so far to get to the
state.

Search algorithm
Input
Formulated problem p: It should get the Start node (initial state) and check
iteratively for the fulfillment of the goal; i.e. goal state(s)
Output
path from Start node to a node for which goal is true
or false if there are no solution paths

PART 2

SEARCH ALGORITHM IMPLEMENTATION

1. Create an interface SearchAlgorithm

- void solve(FormulatedProblem p);

2. Create a class BFS to implement the SearchAlgorithm interface as the first specific
uninformed brute-force search method

- private ArrayList<Node> queue; //Create a queue for enqueuing and dequeuing


nodes for search
- // constructor with an instance creation for queue
@Override
- public void solve (FormulatedProblem p)
{
//declare an initial state object and get the initial state of the problem p
//declare an initial node and enqueue it using pushNode() stated below
//declare a Boolean variable solutionFound and set it to False
//As long as there are still nodes in the queue and we did not get a solution do the following
// declare a new nodeToExplore and pop it from the queue
// check whether the nodeToExplore state is a goal state or not yet
// if yes get the goal path from root
// else put node successors, then loop
SuccessorFunction succFunc = p.getSuccessorFunction();
ArrayList<Action> actions =
succFunc.getPossibleApplicableActions(stateToExplore);
for (Action action : actions) {
Object successorState = action.apply(stateToExplore);
Node successorNode = new Node(successorState, nodeToExplore,
nodeToExplore.getCost() + action.getCostPerAction());
//push the successor node (s)
}
- private void pushNode (Node node)
{ //add the node to the queue }
- private Node popNextNode ()
{ //remove the node from the queue }

Make sure you implemented the main class GenericSolver as stated


earlier in part 1..

EVALUATING THE UNINFORMED SEARCH ALGORITHMS

The uninformed search algorithms should be called to work on problems with various
difficulties, i.e. initial states that are at various distances from the solution.

Here are some example puzzles:

Goal: Easy: Medium: Hard: Worst:

123 134 281 281 567

8 4 862 43 463 4 8

765 7 5 765 75 321

Goal: Easy: Medium: Extreme:


12 125 142 87

345 34 758 654

678 678 3 6 321

In order to evaluate the algorithms, the following metrics should be implemented.

METRICS

For each search algorithm, the solver should output:

- The total number of explored nodes. This is interpreted as a time complexity indicator.
- The maximum queue size, i.e. the maximum number of nodes that existed at the same
time in the queue waiting to be explored. This is interpreted as a space complexity
indicator.
- The sequence of actions allowing to reach the goal from the initial state
- The length of the path from the initial state to the solution, i.e. the length of the sequence
of actions allowing to reach the goal.

IDEA: PART 3 - IMPLEMENTING INFORMED SEARCH ALGORTHMS

The next step consists of implementing informed search algorithms.

First, upgrade the search algorithms architecture to allow considering heuristics. The heuristic
function should be a problem dependent separate entity that is able to evaluate any state of the
problem.

We already defined a SEARCH NODE of the game to be a board, the number of moves made to
reach the board, and the previous search node. First, insert the initial search node (the initial board,
0 moves, and a null previous search node) into a priority queue. Then, delete from the priority
queue the search node with the minimum priority, and insert onto the priority queue all neighboring
search nodes (those that can be reached in one move from the dequeued search node). Repeat this
procedure until the search node dequeued corresponds to a goal board. The success of this approach
hinges on the choice of PRIORITY FUNCTION for a search node. We consider two priority
functions:

- HAMMING PRIORITY FUNCTION. A natural heuristic for a given state is the number
of blocks in the wrong position. Intuitively, states with a small number of blocks in the
wrong position are close to the goal state, and we prefer a search node that have been
reached using a small number of moves.
- MANHATTAN PRIORITY FUNCTION. A better heuristic value for a given state is the
sum of the Manhattan distances (sum of the vertical and horizontal distance) from the
blocks to their goal positions, plus the number of moves made so far to get to the state
(search node).

For example, the Hamming and Manhattan priorities of the initial search node below are 5 and
10, respectively.

8 1 3 1 2 3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
4 2 4 5 6 ---------------------- ----------------------
7 6 5 7 8 1 1 0 0 1 1 0 1 1 2 0 0 2 2 0 3

initial goal Hamming = 5 + 0 Manhattan = 10 + 0

IMPLEMENTATION

1. In Class EightPuzzleProblem ; you can use the goal

1 2
3 4 5
6 7 8 goal

OR the

1 2 3
goal
4 5 6
7 8

This will affect the hamming and manhattan distance calculations. Target Xs and Ys will differ

2. Create 2 methods for calculating the two different heuristics

- public int calcHammingDistance (Object currentState)


{ int hamming = 0;
int [] state = Arrays.copyOf((int[]) currentState,
((int[])currentState).length);
for (int i = 0; i < state.length; i++)
{// Implement the heuristic function
}
return hamming;

}
- public int calcManhattanDistance (Object currentState)
{ int manhattan = 0;
int [] state = Arrays.copyOf((int[]) currentState,
((int[])currentState).length);

for (int x = 0; x < 3; x++){//x-dimensions --rows


for (int y = 0; y < 3; y++) { // y-dimensions --cols
//Implement the function here
//Check the value at every position
//Relate it to its target position
targetX = value/3 & targetY = value %3 for the goal
1 2
3 4 5
6 7 8
OR
targetX = (value-1)/3 & targetY = (value-1)%3
for the goal
1 2 3
4 5 6
7 8
//calculate the distance between current position and target
position in x and y dimensions
}
}
return manhattan;
}
3. Create a new class HeuristicSearchOne that implements SearchAlgorithm. Use the
Hamming Distance heuristic in this implementation. You should calculate the required heuristic
for each node and insert nodes on the queue according to priority.
Implement the required methods including solve, insert, remove, ......

4. Create a new class HeuristicSearchTwo that implements SearchAlgorithm. Use the


Manhattan Distance heuristic in this implementation. Again You should calculate the required
heuristic for each node and insert nodes on the queue according to priority.
Implement the required methods including solve, insert, remove, .....

You might also like