You are on page 1of 6

Ministerul Educaţiei

al Republicii Moldova

Universitatea Tehnică a Moldovei

RAPORT
despre lucrarea de laborator Nr. 4
la Analiza și Proiectarea Algoritmilor în Python

A îndeplinit: Spac Antonio


TI-195

A verificat: Buldumac Oleg

Chişinău – 2021
Tema:Algoritmul Floyd si Dijkstra
SARCINA DE BAZĂ:
1. De studiat tehnica greedy de proiectare a algoritmilor.
2. De implementat într-un limbaj de programare algoritmii Floyd şi
Dijkstra.
3. De alcătuit un raport.

Algoritmul 1
Algoritmul Dijkstra
import time
import numpy
start = time.time()

class Node:
  
    def __init__(self, data, indexloc = None):
        self.data = data
        self.index = indexloc
        
       
class Graph:
 
    @classmethod
    def create_from_nodes(self, nodes):
        return Graph(len(nodes), len(nodes), nodes)
 
  
    def __init__(self, row, col, nodes = None):
        
        self.adj_mat = [[0] * col for _ in range(row)]
        self.nodes = nodes
        for i in range(len(self.nodes)):
            self.nodes[i].index = i
 
   
    def connect_dir(self, node1, node2, weight = 1):
        node1, node2 = self.get_index_from_node(node1), self.get_index_from_node
(node2)
        self.adj_mat[node1][node2] = weight
  
    
    def connect(self, node1, node2, weight = 1):
        self.connect_dir(node1, node2, weight)
        self.connect_dir(node2, node1, weight)
 
    
    def connections_from(self, node):
        node = self.get_index_from_node(node)
        return [(self.nodes[col_num], self.adj_mat[node][col_num]) for col_num i
n range(len(self.adj_mat[node])) if self.adj_mat[node][col_num] != 0]
 
    
    def connections_to(self, node):
      node = self.get_index_from_node(node)
      column = [row[node] for row in self.adj_mat]
      return [(self.nodes[row_num], column[row_num]) for row_num in range(len(co
lumn)) if column[row_num] != 0]
     
  
    def print_adj_mat(self):
      for row in self.adj_mat:
          print(row)
  
    def add_node(self,node):
      self.nodes.append(node)
      node.index = len(self.nodes) - 1
      for row in self.adj_mat:
        row.append(0)     
      self.adj_mat.append([0] * (len(self.adj_mat) + 1))
    
    def dijkstra(self, node):
        nodenum = self.get_index_from_node(node)
        dist = [None] * len(self.nodes)
        for i in range(len(dist)):
            dist[i] = [float("inf")]
            dist[i].append([self.nodes[nodenum]])
        
        dist[nodenum][0] = 0
        
        queue = [i for i in range(len(self.nodes))]
        seen = set()
        while len(queue) > 0:
            
            min_dist = float("inf")
            min_node = None
            for n in queue: 
                if dist[n][0] < min_dist and n not in seen:
                    min_dist = dist[n][0]
                    min_node = n
            
            
            queue.remove(min_node)
            seen.add(min_node)
           
            connections = self.connections_from(min_node)
           
            for (node, weight) in connections: 
                tot_dist = weight + min_dist
                if tot_dist < dist[node.index][0]:
                    dist[node.index][0] = tot_dist
                    dist[node.index][1] = list(dist[min_node][1])
                    dist[node.index][1].append(node)
        return dist
    def get_index_from_node(self, node):
        if not isinstance(node, Node) and not isinstance(node, int):
            raise ValueError("Nodul trebue sa fie un numar intreg sau un obiect 
Nod")
        if isinstance(node, int):
            return node
        else:
            return node.index

a = Node("A")
b = Node("B")
c = Node("C")
d = Node("D")
e = Node("E")
f = Node("F")

w_graph = Graph.create_from_nodes([a,b,c,d,e,f])
 
w_graph.connect(a, b, 5)
w_graph.connect(a, c, 10)
w_graph.connect(a, e, 2)
w_graph.connect(b, c, 2)
w_graph.connect(b, d, 4)
w_graph.connect(c, d, 7)
w_graph.connect(c, f, 10)
w_graph.connect(d, e, 3)
 
w_graph.print_adj_mat()
print([(weight, [n.data for n in node]) for (weight, node) in w_graph.dijkstra(a
)])            

end = time.time()
print(f"Timpul de executie a programului este de:{(end - start) / 1000}")

Algoritmul 2
Algoritmul Floyd
import time
start = time.time()
nV = 4 #Num de varfuri

INF = 999

# Algoritmul Floyd
def floyd_warshall(G):
    distance = list(map(lambda i: list(map(lambda j: j, i)), G))

    # Adaugarea varfurilor  pentru k i j
    for k in range(nV):
        for i in range(nV):
            for j in range(nV):
                distance[i][j] = min(distance[i][j], distance[i][k] + distance[k
][j])
    print_solution(distance)

# Printarea acesot solutii
def print_solution(distance):
    for i in range(nV):
        for j in range(nV):
            if(distance[i][j] == INF):
                print("INF", end=" ")
            else:
                print(distance[i][j], end="  ")
        print(" ")

G = [[0, 3, INF, 5],
    [2, 0, INF, 4],
    [INF, 1, 0, INF],
    [INF, INF, 2, 0]]
floyd_warshall(G)

end = time.time()
print(f"Timpul de executie a programului este de:{(end - start) / 1000}")

Concluzie:
În cursul efectuării lucrării de laborator am observat că algoritmul lui Dijkstra
demonstrează o viteză relativ mai mare de calcul față de algoritmul Floyd luând în
considerație că a fost folosit limbajul Python datele rezultante sunt valabile doar
pentru acest limbaj.
Timpul lor de execuție nu variază mult ,practic e la fel însă algoritmul lui Dijkstra
mai repede caluleaza cea mai scurta cale intre oricare doua virfuri ale grafului,

motiv din care l-am și clasat pe locul întîi după vigilență.

You might also like