0

hi I am working on this python code and wanted to know which searching algorithm its using to find goal state. I want to know if the following code is using BFS or any other searching algorithm this code is solving classic farmer, wolf, cabbage, goat problem

initial = ['L', 'L', 'L', 'L']
goal = ['R', 'R', 'R', 'R']
 
stack = []
stack.append(initial)

def nextState(state):
    if state == goal: return False
    farmer = state[3]
    for i, s in enumerate(state):
        if s == farmer:
            tryState = makeState(state, i)
            if testState(tryState) and isUnique(tryState):
                stack.append(tryState)
                return True
    return False       

def makeState(s, i):
    t = []
    for x in s: t.append(x)
    t[3] = 'R' if t[3] == 'L' else 'L'
    if t[3] == 'L':
        if not testState(t):
            t[i] = 'R' if t[i] == 'L' else 'L'
    else:
        t[i] = 'R' if t[i] == 'L' else 'L'
    return t
 
def testState(s):
    if s[0] == s[1] and s[3] != s[0]: return False
    if s[1] == s[2] and s[3] != s[1]: return False
    return True

def isUnique(s):     
    if s in stack: return False
    return True
      
while nextState(stack[-1]): pass
for i, x in enumerate(stack): 
    print (i)
    print (x)
Pranav Hosangadi
  • 23,755
  • 7
  • 44
  • 70

1 Answers1

0

Short Answer

It becomes BFS when you add your next possible states to a queue, and DFS when you use add them to a stack.

Long Answer

Assume our start node is S, and C is some child node, and each node has 3 children nodes (just for simplifying explanation, otherwise it does not matter).

First, lets see what happens when you add children states to queue. You add your initial state to queue, current nodes in your queue are:

[S]

You get a node from your queue (currently your starting node). You generate its next states and add them to queue, nodes in your queue now are:

[C1, C2, C3]

You select another node from your data structure, C1 since its a queue, generate its children and add them to queue as well:

[C2, C3, C11, C12, C13]

Lets repeat this process a few more steps, you will get C2 and C3 from your queue and perform same operations:

[C11, C12, C13, C21, C22, C23, C31, C32, C33]

Notice the pattern we have. We first expanded to all nodes at level 0 (starting state), then all nodes in level 1 (first children of starting node), now we will start expanding to nodes at level 2 and so on. That is why when you find a solution it must be the one that is closest to your starting state.


Now lets see what would happen if you were to use a stack data structure. First steps will be the same, after you generate all children of your start node and put them into stack, stack now contains:

[C1, C2, C3]

But now the difference is you will pick last added node for expanding:

[C1, C2, C31, C32, C33]
[C1, C2, C31, C32, C331, C332, C333]
...

Instead of trying all possible states at same depth first, you select one path and go deeper as much as you can. If you find a solution at C3331, you can not know if its optimal because C21 might also be a solution too.

unlut
  • 3,525
  • 2
  • 14
  • 23