Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Mini-Project 1

SHEEP & WOLVES


Zeeshan Ahmad
zahmad39@gatech.edu

Abstract—This document describes my solution to the Sheep and


Wolves problem. It analyzes how my agent works by generating
new states and how does it eliminate invalid states based on test. It
uses concepts from the generate and test chapter to generate states
and test them and also from means end analysis chapter in order
to find an optimal path for the solution. The document will also
talk about the efficiency and the performance of my algorithm.

1 INTRODUCTION

Sheep and wolves problem involves a group of sheep and wolves trying to cross
a river via a boat. The goal is to find a sequence of moves which transfers all
the sheep and wolves across the river with 2 constraints. First, the wolves never
outnumber the sheep and the other second is that the boat can only take one or
two animals at a time.

2 AGENT DESCRIPTION

2.1 How does my agent work?

2.1.1 Initialization

The algorithm starts by creating a tuple of the initial number of sheep, initial
number of wolves and the position of the boat where 0 represents that boat is
the left side where as 1 represents that the boat is on the right side. For instance,
if we take an example of 3 sheep and 3 wolves on the left side of the river. The
initial state would be (3,3,0). Based on this, the final state or our goal state
would be (0, 0, 1) which means there are no sheep and wolves on the left
side and the boat is on the right side.

Also, all the possible moves supported for this problem are [(0,2), (2,0),
(1,1), (1,0), (0,1)]. These moves are a list of tuples denoting (number of
sheep, number of wolves) being sent to the other side in a single move.

1
2.1.2 Generating valid states

Now, I start by passing the current state, in our example (3, 3, 0) to the gener-
ateValidStates() function. This function applies all the possible moves that we have
initialized to the current state and generates the next possible states. Based on
our example, the next possible states will be - {(3,1,1) : (0,2), (1,3,1) :
(2,0), (2,2,1) : (1,1), (2,3,1) : (1,0), (3,2,1) : (0,1)}. Note, that I
am using a python dictionary to store the state and move the led to that state.
Now, I take care of the following constraints:

Test Possible States:

• Check for unproductive move: If we are sending a single animal to an empty


river side, it is an unproductive move. So this eliminates {(2,3,1) : (1,0),
(3,2,1) : (0,1)}
• Check for legal state: It checks that sheep and wolves on either side are not
less than 0 or greater than initial number of sheep or wolves
• The problem constraint: A sheep can never outnumber the wolves on either
side. This eliminates (1,3,1) : (2,0)

This leaves us with 2 valid states based on the initial state. {(3,1,1) : (0,2),
(2,2,1) : (1,1)}

2.1.3 Exploring the valid states

I am using A* search algorithm to explore the states efficiently and in-order to


find the optimal path, I use a min-heap data structure to store the states that
needs to be explored. An A* algorithm uses difference between the initial and
final goal to calculate the cost to reach the goal state. This is also explained by
Mr. Goel in Means-Ends analysis chapter. I add the number of sheep and wolves
on the left side of the river to calculate the cost to reach to the right side. And
since, I use a min-heap to store the states to explore, I always get the state with
the lowest cost to explore first. Although, this helps me to estimate how far I
am from the goal, but does not consider the number of moves already taken. In
order to overcome this shortcoming, I also add the length of all the moves already
taken to the number of sheep and wolves before storing it in heap. So the total
(cost = length of new path + number of sheep on left side + number of wolves on left
side).

2
This helps me finding an optimal path.
I am also using a set to store all the visited or the explored states. This ensures
that I do not explore a state that has already been explored saving use time and
being caught in a loop.
So, whenever I get as dictionary item containing the valid state to explore and
the move that led to that state, I store it in a min heap, which contains (cost,
next_path, move) if the path is not already visited.
The agent backtracks if it reaches a state with no valid moves left.
Overall, the algorithm generates new states by applying all possible moves, tests
their validity, estimates the cost by adding the distance to goal and length of
path, and employs the A* algorithm to find the optimal path.

3 AGENT PERFORMANCE

3.1 How well does your agent perform?

My algorithm will perform well for simple problems where the number of sheep
and wolves is small. Also, since I am using the A* search algorithm, the explo-
ration of states is done based on minimum cost to goal, which leads to efficient
exploration of states.

3.2 Does it struggle on any particular cases?

If the number of sheep and wolves are large, my algorithm might suffer from
memory consumption as the number of moves stored in the heap might increase
a lot especially since my maximum depth is not limited. However, if I limit my
maximum depth, I might not reach the final state in cases where the number of
moves are more than the maximum depth.

4 AGENT EFFICIENCY

4.1 How efficient is your agent?

4.1.1 Time Complexity

The worst case time complexity would be O(N X M), where

• N is the number of all possible moves. In our example, it was 3


• M is the number of moves required to reach goal state. In our example, it was
11

3
4.2 Space complexity

The space complexity depends on the number of states stored in the min-heap.
As the number of animals increase, the space complexity increases exponentially
which might cause huge memory consumption and can create memory issues.
Limiting the depth of the solution can mitigate memory consumption to some
extent but it is at the cost of no solution in cases where more depth is required
than the declared max depth.

5 HUMAN COMPARISON

5.1 How does your agent compare to a human?

5.1.1 Generating valid states

When it comes to generating valid states based on the possible moves, a human
would think in a similar way of eliminating invalid moves and exploring only
the valid moves. However, a human mind works based on mental model which
means as and when the number of animals would increase, the human mind
might find it difficult to map the increased number of moves and states. Also,
a human mind might miss tracking the already visited states as and when the
number of animal increase.

5.1.2 Using cost to determine which states to explore first

Although, a human could use the cost to determine the distance of the current
state to the goal state, this cost based approach does not come intuitively to
humans. Again, in this casee too, as the number of animals would increase, a
human mind will find it difficult to comprehend all the states and cost to the
goal state.

5.2 Learning capabilities

The advantage with humans is that they can learn from their previous attempts
and adjust their strategies accordingly. However, this algorithm will works on
predefined rules and constraints.

6 REFERENCES

1. A* search algorithm
https://isaaccomputerscience.org/concepts/dsa_search_a_star?examBoard=all&stage=all

You might also like