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

Lab 4 SP Solution 02052023 042711pm

The document describes a directed weighted graph with six nodes and various edges between them with associated costs. It provides code to represent such a graph as well as functions to find the shortest path between nodes by tracking the total cost.

Uploaded by

Tayyab Satti
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Lab 4 SP Solution 02052023 042711pm

The document describes a directed weighted graph with six nodes and various edges between them with associated costs. It provides code to represent such a graph as well as functions to find the shortest path between nodes by tracking the total cost.

Uploaded by

Tayyab Satti
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

Artificial Intelligence

CSL 411

LAB JOURNAL 4

Name: Hassan Sadaqet


Enrollment 01-135202-113
BSIT 6A

Department of Computer Science


BAHRIA UNIVERSITY, ISLAMABAD
Lab Task:
1. Change the function find path to return shortest path.

CODE
graph = {'A': ['B', 'C'],

'B': ['C', 'D'],

'C': ['D','F'],

'D': ['C','E'],

'E': ['F'],

'F': ['C','E']}

def get_all_path(graph, src, destination, path = []):

path = path + [src]

if src == destination:

return [path]

paths = []

new_path_list = []

for vertex in graph[src]:

if vertex not in path:

new_path_list = get_all_path(graph, vertex, destination, path)

for new_path in new_path_list:

paths.append(new_path)

return paths
def find_shortest_path(graph, start, target, path=[]):

path = path + [start]

if start == target:

return path

if start not in graph:

return None

shortest_path = None

for node in graph[start]:

if node not in path:

newpath = find_shortest_path(graph, node, target, path)

if newpath:

if shortest_path is None or len(newpath) < len(shortest_path):

shortest_path = newpath

return shortest_path

paths = get_all_path(graph, 'A', 'F')

print('\nAll Paths From Node A to F: ')

for path in paths:

print(path)

shortest = find_shortest_path(graph,'A','F')

print("\nThe Shortest path from A to F is: ",shortest)

OUTPUT
2. Consider a simple (directed) graph (digraph) having six nodes (A-F) and the following arcs
(directed edges) with respective cost of edge given in parentheses:
A -> B (2)
A -> C (1)
B -> C (2)
B -> D (5)
C -> D (1)
C -> F (3)
D -> C (1)
D -> E (4)
E -> F (3)
F -> C (1)
F -> E (2)
Using the code for a directed weighted graph in Example 2, instantiate an object of DWGraph in
__main__, add the nodes and edges of the graph using the relevant functions, and implement a function
find_path() that takes starting and ending nodes as arguments and returns at least one path (if one exists)
between those two nodes. The function should also keep track of the cost of the path and return the total
cost as well as the path. Print the path and its cost in __main__.
Code
class Graph:

def __init__(self, nodes=None, edges=None):

"""Initialize a graph object.

Args:

nodes: Iterator of nodes. Each node is an object.

edges: Iterator of edges. Each edge is a tuple of 2 nodes.

"""

self.nodes, self.adj = [], {}

def length(self):

"""Returns the number of nodes in the graph.

>>> g = Graph(nodes=[x for x in range(7)])

>>> len(g)

"""

return len(self.nodes)

def traverse(self):

return 'Vertices: %s\nEdges: %s' % (self.nodes, self.adj)

def add_node(self, n):

if n not in self.nodes:
self.nodes.append(n)

self.adj[n] = []

def add_edge(self, u, v): # undirected unweighted graph

self.adj[u] = self.adj.get(u, []) + [v]

self.adj[v] = self.adj.get(v, []) + [u]

def number_of_nodes(self):

return len(self.nodes)

def number_of_edges(self):

return sum(len(l) for _, l in self.adj.items()) // 2

class DGraph(Graph):

def add_edge(self, u, v):

self.adj[u] = self.adj.get(u, []) + [v]

class WGraph(Graph):

def __init__(self, nodes=None, edges=None):

"""Initialize a graph object.

Args:

nodes: Iterator of nodes. Each node is an object.

edges: Iterator of edges. Each edge is a tuple of 2 nodes and a weight.

"""
self.nodes, self.adj, self.weight = [], {}, {}

def add_edge(self, u, v, w):

self.adj[u] = self.adj.get(u, []) + [v]

self.adj[v] = self.adj.get(v, []) + [u]

self.weight[(u,v)] = w

self.weight[(v,u)] = w

def get_weight(self, u, v):

return self.weight[(u,v)]

class DWGraph(WGraph):

def add_edge(self, u, v, w):

self.adj[u] = self.adj.get(u, []) + [v]

self.weight[(u,v)] = w

def find_path(self, start, end, path=[],cost=0):

newpath=None

path=path+[start]

if start == end:

return path,cost

print(path,'\n updated cost -----> ',cost)

if start not in self.adj:

return None,cost
for node in self.adj[start]:

if node not in path:

newpath,cost = self.find_path(node, end, path, cost+self.get_weight(start, node))

if newpath!=None:

return newpath,cost

dw=DWGraph()

dw.add_node('A')

dw.add_node('B')

dw.add_node('C')

dw.add_node('D')

dw.add_node('F')

dw.add_edge('A','B',2)

dw.add_edge('A','C',1)

dw.add_edge('B','C',2)

dw.add_edge('B','D',5)

dw.add_edge('C','D',1)

dw.add_edge('C','F',3)

dw.add_edge('D','C',1)

dw.add_edge('D','E',4)

dw.add_edge('E','F',3)

dw.add_edge('F','C',1)

dw.add_edge('F','E',2)

print('Length of Graph is',dw.length())

print(dw.traverse(),'\n')
print(dw.find_path('A', 'F'))

Output

You might also like