[Python] Distance Vector Routing issue [closed]

Discussão em 'Python' iniciado por Stack, Junho 10, 2025.

  1. Stack

    Stack Membro Participativo

    I am having an issue with my code, where the values are in the wrong spots and the T=0 stops at 2 and repeats, when it is supposed to go up until 5. Can Anyone help me?

    #!/usr/bin/env python3
    import math
    import sys


    class DistanceVectorNode:
    def __init__(self, node_id, neighbours):
    self.node_id = node_id
    self.neighbours = neighbours.copy()

    self.dv = {node_id: (0, node_id)}
    for neighbour, cost in neighbours.items():
    self.dv[neighbour] = (cost, neighbour)

    self.received_dvs = {}
    for neighbour in neighbours:
    self.received_dvs[neighbour] = {}

    def get_distance_vector(self, all_nodes):
    result = {}
    for node in all_nodes:
    if node in self.dv:
    result[node] = self.dv[node][0]
    else:
    result[node] = math.inf
    return result

    def update(self, neighbour_id, neighbour_dv):
    if neighbour_id not in self.neighbours:
    return False

    self.received_dvs[neighbour_id] = neighbour_dv.copy()

    updated = False
    cost_to_neighbour = self.neighbours[neighbour_id]

    for dest, neighbour_cost in neighbour_dv.items():
    if dest == self.node_id:
    continue

    if neighbour_cost >= math.inf:
    continue

    new_cost = cost_to_neighbour + neighbour_cost

    if dest not in self.dv:
    self.dv[dest] = (new_cost, neighbour_id)
    updated = True
    elif new_cost < self.dv[dest][0]:
    self.dv[dest] = (new_cost, neighbour_id)
    updated = True

    elif self.dv[dest][1] == neighbour_id:
    old_cost = self.dv[dest][0]
    self.dv[dest] = (new_cost, neighbour_id)
    if old_cost != new_cost:
    updated = True

    return updated

    def add_neighbour(self, neighbour_id, cost):
    self.neighbours[neighbour_id] = cost
    self.dv[neighbour_id] = (cost, neighbour_id)
    if neighbour_id not in self.received_dvs:
    self.received_dvs[neighbour_id] = {}

    def remove_neighbour(self, neighbour_id):
    if neighbour_id in self.neighbours:
    del self.neighbours[neighbour_id]
    if neighbour_id in self.received_dvs:
    del self.received_dvs[neighbour_id]

    routes_to_recalculate = []
    for dest in list(self.dv.keys()):
    if dest != self.node_id and dest in self.dv and self.dv[dest][1] == neighbour_id:
    routes_to_recalculate.append(dest)

    for dest in routes_to_recalculate:
    if dest in self.dv:
    del self.dv[dest]

    for dest in routes_to_recalculate:
    best_cost = math.inf
    best_next_hop = None
    for via_neighbour in self.neighbours.keys():
    if via_neighbour in self.received_dvs and dest in self.received_dvs[via_neighbour]:
    alt_cost = self.neighbours[via_neighbour] + self.received_dvs[via_neighbour][dest]
    if alt_cost < best_cost:
    best_cost = alt_cost
    best_next_hop = via_neighbour

    if best_next_hop is not None:
    self.dv[dest] = (best_cost, best_next_hop)


    def update_neighbour_cost(self, neighbour_id, new_cost):
    if neighbour_id in self.neighbours:
    old_cost = self.neighbours[neighbour_id]
    self.neighbours[neighbour_id] = new_cost
    self.dv[neighbour_id] = (new_cost, neighbour_id)

    for dest in list(self.dv.keys()):
    if dest != self.node_id and self.dv[dest][1] == neighbour_id:
    if neighbour_id in self.received_dvs and dest in self.received_dvs[neighbour_id]:
    new_route_cost = new_cost + self.received_dvs[neighbour_id][dest]
    self.dv[dest] = (new_route_cost, neighbour_id)


    def reset_unreachable_destinations(self, all_nodes):
    neighbours_to_remove = []
    for neighbour in self.received_dvs.keys():
    if neighbour not in self.neighbours:
    neighbours_to_remove.append(neighbour)

    for neighbour in neighbours_to_remove:
    del self.received_dvs[neighbour]

    destinations_to_remove = []
    for dest in list(self.dv.keys()):
    if dest != self.node_id and dest in self.dv:
    next_hop = self.dv[dest][1]
    if next_hop not in self.neighbours:
    destinations_to_remove.append(dest)

    for dest in destinations_to_remove:
    del self.dv[dest]


    def print_distance_table(self, t, all_nodes):
    print(f"Distance Table of router {self.node_id:} at t={t}:")
    destinations = sorted([node for node in all_nodes if node != self.node_id])

    header = " "
    for dest in destinations:
    header += f"{dest:<5}"
    print(header)

    neighbours_to_show = sorted(self.neighbours.keys())
    for via_node in neighbours_to_show:
    row = f"{via_node:<5}"

    for dest in destinations:
    if dest == via_node:
    cost = self.neighbours[via_node]
    row += f"{cost:<5}"
    else:
    if via_node in self.received_dvs and dest in self.received_dvs[via_node]:
    neighbour_cost_to_dest = self.received_dvs[via_node][dest]
    if neighbour_cost_to_dest >= math.inf:
    row += "INF "
    else:
    cost_via = self.neighbours[via_node] + neighbour_cost_to_dest
    if cost_via >= math.inf:
    row += "INF "
    else:
    row += f"{cost_via:<5}"
    else:
    row += "INF "
    print(row)
    print()


    def print_routing_table(self):
    print(f"Routing Table of router {self.node_id}:")
    destinations = sorted([dest for dest in self.dv.keys() if dest != self.node_id])
    for dest in destinations:
    if dest in self.dv:
    cost, next_hop = self.dv[dest]
    if cost == math.inf:
    print(f"{dest}, INF,INF")
    else:
    print(f"{dest},{next_hop},{cost}")
    print()


    def simulate_distance_vector(nodes):
    all_node_names = sorted(nodes.keys())

    for node_name in all_node_names:
    nodes[node_name].print_distance_table(0, all_node_names)

    iteration = 0
    max_iterations = 10

    while iteration < max_iterations:
    changed = False
    iteration += 1

    distance_vectors = {}
    for node_id, node in nodes.items():
    distance_vectors[node_id] = node.get_distance_vector(all_node_names)


    for node_id, node in nodes.items():
    for neighbour_id in list(node.neighbours.keys()):
    if neighbour_id in nodes and neighbour_id in distance_vectors:
    if node.update(neighbour_id, distance_vectors[neighbour_id]):
    changed = True

    for node_name in all_node_names:
    nodes[node_name].print_distance_table(iteration, all_node_names)

    if not changed:
    break

    for node_name in all_node_names:
    nodes[node_name].print_routing_table()

    def parse_input():
    lines = []
    for line in sys.stdin:
    lines.append(line.strip())

    line_index = 0

    node_names = []
    while line_index < len(lines) and lines[line_index] != "START":
    if lines[line_index]:
    node_names.append(lines[line_index])
    line_index += 1

    if line_index >= len(lines):
    return

    line_index += 1

    nodes = {}
    for name in node_names:
    nodes[name] = DistanceVectorNode(name, {})


    while line_index < len(lines) and lines[line_index] != "UPDATE":
    if lines[line_index]:
    parts = lines[line_index].split()
    if len(parts) == 3:
    node1, node2, cost = parts[0], parts[1], int(parts[2])

    if node1 not in nodes:
    nodes[node1] = DistanceVectorNode(node1, {})
    if node2 not in nodes:
    nodes[node2] = DistanceVectorNode(node2, {})

    if cost == -1:
    nodes[node1].remove_neighbour(node2)
    nodes[node2].remove_neighbour(node1)
    else:
    nodes[node1].add_neighbour(node2, cost)
    nodes[node2].add_neighbour(node1, cost)
    line_index += 1

    if line_index >= len(lines):
    return

    line_index += 1

    simulate_distance_vector(nodes)

    topology_changed = False
    while line_index < len(lines) and lines[line_index] != "END":
    if lines[line_index]:
    parts = lines[line_index].split()
    if len(parts) == 3:
    node1, node2, cost = parts[0], parts[1], int(parts[2])

    if node1 not in nodes:
    nodes[node1] = DistanceVectorNode(node1, {})
    if node2 not in nodes:
    nodes[node2] = DistanceVectorNode(node2, {})

    if cost == -1:
    nodes[node1].remove_neighbour(node2)
    nodes[node2].remove_neighbour(node1)
    else:
    nodes[node1].add_neighbour(node2, cost)
    nodes[node2].add_neighbour(node1, cost)

    topology_changed = True
    line_index += 1

    if topology_changed:
    all_node_names = sorted(nodes.keys())
    for node in nodes.values():
    node.reset_unreachable_destinations(all_node_names)

    simulate_distance_vector(nodes)


    if __name__ == "__main__":
    parse_input()


    My input --> X Y Z START X Z 9 X Y 3 Y Z 4 UPDATE X Z 1 Z Y -1 END

    My output --> Distance Table of router X at t=0: Y Z
    Y 3 INF
    Z INF 9

    Distance Table of router Y at t=0: X Z
    X 3 INF
    Z INF 4

    Distance Table of router Z at t=0: X Y
    X 9 INF
    Y INF 4

    Distance Table of router X at t=1: Y Z
    Y 3 7
    Z 13 9

    Distance Table of router Y at t=1: X Z
    X 3 12
    Z 13 4

    Distance Table of router Z at t=1: X Y
    X 9 12
    Y 7 4

    Distance Table of router X at t=2: Y Z
    Y 3 7
    Z 13 9

    Distance Table of router Y at t=2: X Z
    X 3 10
    Z 11 4

    Distance Table of router Z at t=2: X Y
    X 9 12
    Y 7 4

    Routing Table of router X: Y,Y,3 Z,Y,7

    Routing Table of router Y: X,X,3 Z,Z,4

    Routing Table of router Z: X,Y,7 Y,Y,4

    Distance Table of router X at t=0: Y Z
    Y 3 7
    Z 5 1

    Distance Table of router Y at t=0: X Z
    X 3 10

    Distance Table of router Z at t=0: X Y
    X 1 4

    Distance Table of router X at t=1: Y Z
    Y 3 13
    Z 5 1

    Distance Table of router Y at t=1: X Z
    X 3 4

    Distance Table of router Z at t=1: X Y
    X 1 4

    Distance Table of router X at t=2: Y Z
    Y 3 7
    Z 5 1

    Distance Table of router Y at t=2: X Z
    X 3 4

    Distance Table of router Z at t=2: X Y
    X 1 4

    Routing Table of router X: Y,Y,3 Z,Z,1

    Routing Table of router Y: X,X,3 Z,X,4

    Routing Table of router Z: X,X,1 Y,X,4

    Expected output -->

    Distance Table of router X at t=0: Y Z
    Y 3 INF
    Z INF 9

    Distance Table of router Y at t=0: X Z
    X 3 INF
    Z INF 4

    Distance Table of router Z at t=0: X Y
    X 9 INF
    Y INF 4

    Distance Table of router X at t=1: Y Z
    Y 3 13
    Z 7 9

    Distance Table of router Y at t=1: X Z
    X 3 13
    Z 12 4

    Distance Table of router Z at t=1: X Y
    X 9 7
    Y 12 4

    Distance Table of router X at t=2: Y Z
    Y 3 13
    Z 7 9

    Distance Table of router Y at t=2: X Z
    X 3 11
    Z 10 4

    Distance Table of router Z at t=2: X Y
    X 9 7
    Y 12 4

    Routing Table of router X: Y,Y,3 Z,Y,7

    Routing Table of router Y: X,X,3 Z,Z,4

    Routing Table of router Z: X,Y,7 Y,Y,4

    Distance Table of router X at t=3: Y Z
    Y 3 5
    Z 7 1

    Distance Table of router Y at t=3: X Z
    X 3 INF
    Z 10 INF

    Distance Table of router Z at t=3: X Y
    X 1 INF
    Y 4 INF

    Distance Table of router X at t=4: Y Z
    Y 3 5
    Z 13 1

    Distance Table of router Y at t=4: X Z
    X 3 INF
    Z 4 INF

    Distance Table of router Z at t=4: X Y
    X 1 INF
    Y 4 INF

    Distance Table of router X at t=5: Y Z
    Y 3 5
    Z 7 1

    Distance Table of router Y at t=5: X Z
    X 3 INF
    Z 4 INF

    Distance Table of router Z at t=5: X Y
    X 1 INF
    Y 4 INF

    Routing Table of router X: Y,Y,3 Z,Z,1

    Routing Table of router Y: X,X,3 Z,X,4

    Routing Table of router Z: X,X,1 Y,X,4

    Continue reading...

Compartilhe esta Página