A Comparative Study of Breadth First Search and Depth First Search Algorithms in Solving The Water Jug Problem On Google Colab
A Comparative Study of Breadth First Search and Depth First Search Algorithms in Solving The Water Jug Problem On Google Colab
Rahul Jain,
Abstract:
The Water Jug Problem, also known as the Die-Hard Problem, is a well-known artificial
intelligence problem that involves filling and pouring water from two jugs of different
capacities to obtain a specific amount of water. In this research, we investigate the performance
of two search algorithms, namely Breadth First Search (BFS) and Depth First Search (DFS),
in solving the Water Jug Problem on Google Colab. We define the rules of the problem and
implement the BFS and DFS algorithms to find the optimal path from an initial node to a goal
node. We compare the execution time and the number of explored nodes for each algorithm to
evaluate their efficiency and effectiveness. The results show that the BFS algorithm performs
better than the DFS algorithm in terms of execution time and explored nodes. The findings of
this research contribute to the understanding of search algorithms and their applicability in
solving real-world problems.
Keywords: Water jug Problem, Artificial Intelligence, BFS, DFS, Google Colab
Introduction:
The water jug problem, also known as the die-hard problem, is a classic problem in artificial
intelligence that involves two or more water jugs of different sizes, and the goal is to measure
a specific amount of water using these jugs.
In the problem, the jugs can be filled with water, emptied, and poured from one jug to another,
and the objective is to find a sequence of actions that will result in obtaining the desired amount
of water. The problem can be made more challenging by adding constraints, such as limits on
the number of moves or the amount of water that can be poured at a time.
The water jug problem is often used as a simple example of a search problem in AI, where the
solution involves finding a path through a state space that represents all possible configurations
of the jugs and the amount of water in them. Various search algorithms, such as depth-first
search, breadth-first search, and heuristic search, can be applied to solve this problem.
Methodology:
The code defines two search algorithms, namely Breadth First Search (BFS) and Depth First
Search (DFS), to find the optimal path from an initial node to a goal node in a problem of filling
The BFS algorithm is defined in the BfsAlgo class, which contains a pushlist, popnode, and
generateAllSuccessors methods. The pushlist method adds a list of nodes to the BFS queue,
the popnode method removes and returns the first node in the queue, and the
generateAllSuccessors method generates all possible nodes that can be reached from a given
node. The bfsMain method uses these methods to search for the goal node from the initial node.
The DFS algorithm is defined in the DfsAlgo class, which contains similar methods to the BFS
class, such as pushNode, pushList, popnode, generateRandomSuccessor, and
generateAllSuccessors. The pushNode method adds a node to the DFS stack, the pushList
method adds a list of nodes to the DFS stack, and the generateRandomSuccessor method
generates a random node from the current node that has not been visited before. The dfsMain
method uses these methods to search for the goal node from the initial node.
Code:
import time
import random
class node:
def __init__(self,data):
self.x=0
self.y=0
self.parent=data
def __repr__(self):
return "("+str(self.x)+","+str(self.y)+")"
def operation(cnode,rule):
x = cnode.x
y = cnode.y
if rule == 1 :
if x < maxjug1 :
x = maxjug1
else :
return None
elif rule == 2 :
if y < maxjug2 :
y = maxjug2
else :
return None
elif rule == 3 :
if x > 0 :
x=0
else :
return None
def printpath(cnode):
temp = cnode
list1=[]
while(temp != None):
list1.append(temp)
temp = temp.parent
list1.reverse()
class BfsAlgo:
def __init__(self):
self.bfsq = []
def pushlist(self,list1):
for m in list1:
self.bfsq.append(m)
def popnode(self):
if(self.is_empty(self.bfsq)):
return None
else:
return self.bfsq.pop(0)
def is_empty(self,l):
return len(l) == 0
def generateAllSuccessors(self,cnode):
list1=[]
for rule in range (1,9):
nextnode = operation(cnode,rule)
if nextnode != None :
list1.append(nextnode)
return list1
def bfsMain(self,initialNode,GoalNode):
self.bfsq.append(initialNode)
while not self.is_empty(self.bfsq):
visited_node = self.popnode()
#print(str(visited_node))
if isGoalNode(visited_node,GoalNode):
return visited_node
successor_nodes = self.generateAllSuccessors(visited_node)
#print("Successors:"+str(successor_nodes))
self.pushlist(successor_nodes)
return None
class DfsAlgo:
def __init__(self):
self.dfsStack = []
def pushNode(self,m):
self.dfsStack.append(m)
def pushList(self,list1):
for m in list1:
self.dfsStack.append(m)
def is_empty(self,l):
return len(l) == 0
Results:
Try 1:
Enter value of maxjug1:4
Enter value of maxjug2:3
Enter value of Goal in jug1:2
BFS Algorithm is running...
Solution can Found by using BFS algorithm:
(0,0)
(0,3)
(3,0)
Try 2:
Enter value of maxjug1:4
Enter value of maxjug2:3
Enter value of Goal in jug1:2
BFS Algorithm is running...
Solution can Found by using BFS algorithm:
(0,0)
(0,3)
(3,0)
(3,3)
(4,2)
(0,2)
(2,0)
Path Cost: 7
Execution Time: 7.701396942138672 ms
DFS Algorithm is running...
Solution can Found by using DFS algorithm:
(0,0)
(0,3)
(4,3)
(4,0)
(1,3)
(1,0)
(0,1)
(4,1)
(2,3)
(2,0)
Path Cost: 10
Execution Time: 0.5414485931396484 ms
Try 4:
Enter value of maxjug1:4
Enter value of maxjug2:3
Enter value of Goal in jug1:2
BFS Algorithm is running...
Solution can Found by using BFS algorithm:
(0,0)
(0,3)
(3,0)
(3,3)
(4,2)
(0,2)
(2,0)
Path Cost: 7
Execution Time: 7.1659088134765625 ms
DFS Algorithm is running...
Solution can Found by using DFS algorithm:
(0,0)
(0,3)
(4,3)
Try 5:
Enter value of maxjug1:4
Enter value of maxjug2:3
Enter value of Goal in jug1:2
BFS Algorithm is running...
Solution can Found by using BFS algorithm:
(0,0)
(0,3)
(3,0)
(3,3)
(4,2)
(0,2)
(2,0)
Path Cost: 7
Execution Time: 6.980180740356445 ms
DFS Algorithm is running...
Solution can Found by using DFS algorithm:
(0,0)
(0,3)
(4,3)
(4,0)
(1,3)
(1,0)
(0,1)
(4,1)
(2,3)
(2,0)
Path Cost: 10
Execution Time: 0.6630420684814453 ms
Complexity Analysis:
Time complexity of BFS:
The worst-case time complexity of BFS is O(b^d), where b is the branching factor of the search
tree, and d is the depth of the solution. In this code, the branching factor is 8, as there are 8
possible operations that can be performed on a node. The depth of the solution is not known
beforehand. Therefore, the worst-case time complexity of BFS is O(8^d).
Space complexity of BFS: