From d25edc16218c68ea86f732c68b005b9285dd81db Mon Sep 17 00:00:00 2001 From: fmurat Date: Tue, 25 May 2021 06:56:07 +0300 Subject: [PATCH] Term Project --- Ahc.py | 16 ++- CONTRIBUTORS.md | 1 + Channels.py | 5 + TagToTag/GenericTag_ChandyMisra.py | 83 +++++++++++++++ TagToTag/GenericTag_MerlinSegall.py | 137 +++++++++++++++++++++++++ tests/TagToTag/testTag_ChandyMisra.py | 86 ++++++++++++++++ tests/TagToTag/testTag_MerlinSegall.py | 83 +++++++++++++++ 7 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 TagToTag/GenericTag_ChandyMisra.py create mode 100644 TagToTag/GenericTag_MerlinSegall.py create mode 100644 tests/TagToTag/testTag_ChandyMisra.py create mode 100644 tests/TagToTag/testTag_MerlinSegall.py diff --git a/Ahc.py b/Ahc.py index b2d5487..f244023 100644 --- a/Ahc.py +++ b/Ahc.py @@ -255,6 +255,20 @@ class Topology: nodes = {} channels = {} + # Only available with TagToTagFIFOPerfectChannel + def construct_from_weighted_graph(self, G: nx.Graph, nodetype, channeltype): + self.G = G + nodes = list(G.nodes) + edges = list(G.edges) + for i in nodes: + cc = nodetype(nodetype.__name__, i) + self.nodes[i] = cc + for k in edges: + ch = channeltype(channeltype.__name__, str(k[0]) + "-" + str(k[1]), G[k[0]][k[1]]['weight']) + self.channels[k] = ch + self.nodes[k[0]].connect_me_to_channel(ConnectorTypes.DOWN, ch) + self.nodes[k[1]].connect_me_to_channel(ConnectorTypes.DOWN, ch) + def construct_from_graph(self, G: nx.Graph, nodetype, channeltype): self.G = G nodes = list(G.nodes) @@ -315,7 +329,7 @@ class Topology: #mypath = path[i][j] # print(f"{i}to{j} path = {path[i][j]} nexthop = {path[i][j][1]}") #self.ForwardingTable[i][j] = path[i][j][1] - + # print(f"{i}to{j}path = NONE") #self.ForwardingTable[i][j] = inf # No paths #except IndexError: diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 6b324da..d077bd2 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,4 @@ # Contributors - [Berker Acır](https://github.com/berkeracir) +- [Furkan Murat](https://github.com/fmurat) diff --git a/Channels.py b/Channels.py index a6e9bbd..3ba9be6 100644 --- a/Channels.py +++ b/Channels.py @@ -158,3 +158,8 @@ class P2PFIFOFairLossChannel(P2PFIFOPerfectChannel): class FIFOBroadcastPerfectChannel(Channel): pass + +class TagToTagFIFOPerfectChannel(P2PFIFOPerfectChannel): + def __init__(self, componentname, componentinstancenumber, edgeweight): + self.edgeweight = edgeweight + super().__init__(componentname, componentinstancenumber) diff --git a/TagToTag/GenericTag_ChandyMisra.py b/TagToTag/GenericTag_ChandyMisra.py new file mode 100644 index 0000000..6c48f5f --- /dev/null +++ b/TagToTag/GenericTag_ChandyMisra.py @@ -0,0 +1,83 @@ +from enum import Enum +import time + +from Ahc import ComponentModel, MessageDestinationIdentifiers, Event, GenericMessageHeader, GenericMessagePayload, GenericMessage, EventTypes, ConnectorTypes, registry +from Channels import TagToTagFIFOPerfectChannel + +class TagMessageTypes(Enum): + SND = "SENDDISTANCE" + +# define your own message header structure +class TagMessageHeader(GenericMessageHeader): + def __init__(self, messagetype, messagefrom, messageto, initialdistance, nexthop=float('inf'), interfaceid=float('inf'), sequencenumber=-1): + self.initialdistance = initialdistance + super().__init__(messagetype, messagefrom, messageto, nexthop, interfaceid, sequencenumber) + +# define your own message payload structure +class TagMessagePayload(GenericMessagePayload): + pass + +class TagMessage(GenericMessage): + pass + +class TagMessageDestinationIdentifiers(Enum): + SHAREDISTANCEEXCEPTPARENT = -3 + +class TagComponent(ComponentModel): + def on_init(self, eventobj: Event): + # print(f"Initializing {self.componentname}.{self.componentinstancenumber}") + pass + + def start_initiator(self): + self.starting_message_timestamp = time.perf_counter() + self.last_incoming_message_timestamp = self.starting_message_timestamp + # print("Started") + self.initial_distance = 0 + self.fill_channels_id_list_except_parent() + self.send_message_to_down() + + def fill_channels_id_list_except_parent(self): + self.channels_id_list_except_parent = [] + if ConnectorTypes.DOWN in self.connectors[ConnectorTypes.DOWN][0].connectors: + for channel in self.connectors[ConnectorTypes.DOWN][0].connectors[ConnectorTypes.DOWN]: + if self.initial_parent_channel != channel.componentinstancenumber: + self.channels_id_list_except_parent.append(channel.componentinstancenumber) + + def prepare_outgoing_message(self, messagetype, messagefrom, messageto, initialdistance, interface_id): + message_header = TagMessageHeader(messagetype, messagefrom, messageto, initialdistance, interfaceid=interface_id) + message_payload = TagMessagePayload(None) + message = TagMessage(message_header, message_payload) + return Event(self, EventTypes.MFRT, message) + + def send_message_to_down(self): + # Gönderilen mesajlar buraya + for channel_id in self.channels_id_list_except_parent: + self.send_down(self.prepare_outgoing_message(TagMessageTypes.SND, self.componentinstancenumber, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT, self.initial_distance, channel_id)) + + def on_message_from_bottom(self, eventobj: Event): + # Alınan mesajlar buraya + message_header = eventobj.eventcontent.header + message_type = message_header.messagetype + message_from = message_header.messagefrom + message_to = message_header.messageto + incoming_distance = message_header.initialdistance + incoming_channel = message_header.interfaceid + incoming_edge_weight = registry.get_component_by_key(TagToTagFIFOPerfectChannel.__name__, incoming_channel).edgeweight + + if message_type == TagMessageTypes.SND: + self.last_incoming_message_timestamp = time.perf_counter() + if incoming_distance + incoming_edge_weight < self.initial_distance: + self.initial_distance = incoming_distance + incoming_edge_weight + self.initial_parent = message_from + self.initial_parent_channel = incoming_channel + + self.fill_channels_id_list_except_parent() + self.send_message_to_down() + + def __init__(self, componentname, componentinstancenumber): + self.initial_distance = float('inf') + self.initial_parent = None + self.initial_parent_channel = None + self.last_incoming_message_timestamp = None + self.channels_id_list_except_parent = [] + super().__init__(componentname, componentinstancenumber) diff --git a/TagToTag/GenericTag_MerlinSegall.py b/TagToTag/GenericTag_MerlinSegall.py new file mode 100644 index 0000000..b7895d1 --- /dev/null +++ b/TagToTag/GenericTag_MerlinSegall.py @@ -0,0 +1,137 @@ +from enum import Enum +import time + +from Ahc import ComponentModel, MessageDestinationIdentifiers, Event, GenericMessageHeader, GenericMessagePayload, GenericMessage, EventTypes, ConnectorTypes, registry +from Channels import TagToTagFIFOPerfectChannel + +class TagMessageTypes(Enum): + RZS = "ROUNDZEROSENDDISTANCE" + ORS = "OTHERROUNDSSENDDISTANCE" + +# define your own message header structure +class TagMessageHeader(GenericMessageHeader): + def __init__(self, messagetype, messagefrom, messageto, initialdistance, nexthop=float('inf'), interfaceid=float('inf'), sequencenumber=-1): + self.initialdistance = initialdistance + super().__init__(messagetype, messagefrom, messageto, nexthop, interfaceid, sequencenumber) + +# define your own message payload structure +class TagMessagePayload(GenericMessagePayload): + pass + +class TagMessage(GenericMessage): + pass + +class TagMessageDestinationIdentifiers(Enum): + SHAREDISTANCETOPARENT = -3 + SHAREDISTANCEEXCEPTPARENT = -4 + +class TagComponent(ComponentModel): + def on_init(self, eventobj: Event): + # print(f"Initializing {self.componentname}.{self.componentinstancenumber}") + pass + + def fill_lists(self): + self.all_incoming_messages = [] + self.channels_id_list_except_parent = [] + self.temp_channels_id_list = [] + if ConnectorTypes.DOWN in self.connectors[ConnectorTypes.DOWN][0].connectors: + for channel in self.connectors[ConnectorTypes.DOWN][0].connectors[ConnectorTypes.DOWN]: + if self.initial_parent_channel != channel.componentinstancenumber: + self.channels_id_list_except_parent.append(channel.componentinstancenumber) + self.temp_channels_id_list.append(channel.componentinstancenumber) + # for channel in self.connectors[ConnectorTypes.DOWN][0].connectors[ConnectorTypes.DOWN]: + # for node in channel.connectors: + # if self.componentinstancenumber != channel.connectors[node][0].componentinstancenumber: + # tosendlist.append(channel.connectors[node][0].componentinstancenumber) + + def prepare_outgoing_message(self, messagetype, messagefrom, messageto, initialdistance, interface_id): + message_header = TagMessageHeader(messagetype, messagefrom, messageto, initialdistance, interfaceid=interface_id) + message_payload = TagMessagePayload(None) + message = TagMessage(message_header, message_payload) + return Event(self, EventTypes.MFRT, message) + + def start_initiator(self, node_count): + self.starting_message_timestamp = time.perf_counter() + # print("Started") + self.is_initiator = True + self.initial_distance = 0 + self.round_count = node_count - 1 + self.fill_lists() + self.send_message_to_down(TagMessageTypes.RZS, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT) + + def send_message_to_down(self, message_type: TagMessageTypes, message_identifier: TagMessageDestinationIdentifiers, parent_channel_id=None): + # Gönderilen mesajlar buraya + if message_identifier == TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT: + for channel_id in self.channels_id_list_except_parent: + self.send_down(self.prepare_outgoing_message(message_type, self.componentinstancenumber, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT, self.initial_distance, channel_id)) + elif message_identifier == TagMessageDestinationIdentifiers.SHAREDISTANCETOPARENT: + self.send_down(self.prepare_outgoing_message(message_type, self.componentinstancenumber, TagMessageDestinationIdentifiers.SHAREDISTANCETOPARENT, self.initial_distance, parent_channel_id)) + + def on_message_from_bottom(self, eventobj: Event): + # Alınan mesajlar buraya + message_header = eventobj.eventcontent.header + message_type = message_header.messagetype + message_from = message_header.messagefrom + message_to = message_header.messageto + incoming_distance = message_header.initialdistance + incoming_channel = message_header.interfaceid + incoming_edge_weight = registry.get_component_by_key(TagToTagFIFOPerfectChannel.__name__, incoming_channel).edgeweight + + if message_type == TagMessageTypes.RZS: + if self.initial_parent == None and self.is_initiator == False: + self.initial_parent = message_from + self.initial_parent_channel = incoming_channel + self.fill_lists() + self.temp_channels_id_list.remove(incoming_channel) + self.send_message_to_down(TagMessageTypes.RZS, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT) + else: + self.temp_channels_id_list.remove(incoming_channel) + + if len(self.temp_channels_id_list) == 0: + self.fill_lists() + if self.is_initiator == False: + self.send_message_to_down(TagMessageTypes.RZS, TagMessageDestinationIdentifiers.SHAREDISTANCETOPARENT, self.initial_parent_channel) + else: + self.send_message_to_down(TagMessageTypes.ORS, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT) + + elif message_type == TagMessageTypes.ORS: + if incoming_channel == self.initial_parent_channel and self.is_initiator == False: + self.temp_channels_id_list.remove(incoming_channel) + if self.initial_distance == float('inf'): + self.initial_distance = incoming_distance + incoming_edge_weight + self.send_message_to_down(TagMessageTypes.ORS, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT) + else: + self.temp_channels_id_list.remove(incoming_channel) + if self.is_initiator == False: + self.all_incoming_messages.append((incoming_distance + incoming_edge_weight, message_from, incoming_channel)) + + if len(self.temp_channels_id_list) == 0: + self.all_incoming_messages.sort(key = lambda x: x[0]) + if len(self.all_incoming_messages) > 0 and self.all_incoming_messages[0][0] < self.initial_distance: + self.initial_distance = self.all_incoming_messages[0][0] + self.initial_parent = self.all_incoming_messages[0][1] + old_parent_channel = self.initial_parent_channel + self.initial_parent_channel = self.all_incoming_messages[0][2] + self.fill_lists() + self.send_message_to_down(TagMessageTypes.ORS, TagMessageDestinationIdentifiers.SHAREDISTANCETOPARENT, old_parent_channel) + else: + self.fill_lists() + if self.is_initiator == False: + self.send_message_to_down(TagMessageTypes.ORS, TagMessageDestinationIdentifiers.SHAREDISTANCETOPARENT, self.initial_parent_channel) + else: + self.round_count -= 1 + if self.round_count > 0: + self.send_message_to_down(TagMessageTypes.ORS, TagMessageDestinationIdentifiers.SHAREDISTANCEEXCEPTPARENT) + else: + # print("Finished") + self.ending_message_timestamp = time.perf_counter() + + def __init__(self, componentname, componentinstancenumber): + self.is_initiator = False + self.initial_distance = float('inf') + self.initial_parent = None + self.initial_parent_channel = None + self.channels_id_list_except_parent = [] + self.temp_channels_id_list = [] + self.all_incoming_messages = [] + super().__init__(componentname, componentinstancenumber) diff --git a/tests/TagToTag/testTag_ChandyMisra.py b/tests/TagToTag/testTag_ChandyMisra.py new file mode 100644 index 0000000..382b3eb --- /dev/null +++ b/tests/TagToTag/testTag_ChandyMisra.py @@ -0,0 +1,86 @@ +import random +import time +from enum import Enum + +import matplotlib.pyplot as plt +import networkx as nx + +from TagToTag.GenericTag_ChandyMisra import TagComponent, TagMessageDestinationIdentifiers, TagMessageTypes +from Ahc import ComponentModel, MessageDestinationIdentifiers, Event, GenericMessageHeader, GenericMessagePayload, GenericMessage, EventTypes, ConnectorTypes, Topology, ComponentRegistry, registry +from Channels import TagToTagFIFOPerfectChannel + +class AdHocNode(ComponentModel): + + def on_init(self, eventobj: Event): + print(f"Initializing {self.componentname}.{self.componentinstancenumber}") + + def on_message_from_top(self, eventobj: Event): + # print("Outgoing Message from ", self.componentinstancenumber, ". Node", ", via channel: [", eventobj.eventcontent.header.interfaceid, "]") + self.send_down(Event(self, EventTypes.MFRT, eventobj.eventcontent)) + + def on_message_from_bottom(self, eventobj: Event): + # print("Incoming Message to ", self.componentinstancenumber, ". Node, From: ", eventobj.eventcontent.header.messagefrom) + self.send_up(Event(self, EventTypes.MFRB, eventobj.eventcontent)) + + def __init__(self, componentname, componentid): + + # SUBCOMPONENTS + self.mainTagComponent = TagComponent("MainTagComponent", componentid) + + # CONNECTIONS AMONG SUBCOMPONENTS + + # Connect the bottom component to the composite component.... + self.mainTagComponent.connect_me_to_component(ConnectorTypes.DOWN, self) + self.connect_me_to_component(ConnectorTypes.UP, self.mainTagComponent) + + super().__init__(componentname, componentid) + +def draw_randow_geometric_graph_with_edge_weight(node_count, radius, max_weight): + G = nx.random_geometric_graph(node_count, radius) + edges = list(G.edges) + for edge in edges: + random_weight = random.randint(1, max_weight) + G[edge[0]][edge[1]]['weight'] = random_weight + G[edge[1]][edge[0]]['weight'] = random_weight + node_positions = nx.get_node_attributes(G, 'pos') + node_labels = {node:node for node in G.nodes()} + edge_labels = nx.get_edge_attributes(G, 'weight') + nx.draw(G, node_positions, edge_color='black', node_color='blue', labels=node_labels) + nx.draw_networkx_edge_labels(G, node_positions, edge_labels=edge_labels, font_color='red') + return G + +node_count = 5 +radius = 0.8 +max_weight = 10 + +G = draw_randow_geometric_graph_with_edge_weight(node_count, radius, max_weight) + +topo = Topology() +topo.construct_from_weighted_graph(G, AdHocNode, TagToTagFIFOPerfectChannel) +topo.start() + +initiator_tag_id = 0 +topo.nodes[initiator_tag_id].mainTagComponent.start_initiator() + +time.sleep(3) + +starting_time = topo.nodes[initiator_tag_id].mainTagComponent.starting_message_timestamp +last_incoming_message_timestamp = topo.nodes[initiator_tag_id].mainTagComponent.starting_message_timestamp + +for n in topo.nodes: + if topo.nodes[n].mainTagComponent.initial_parent == None: + if n == initiator_tag_id: + if topo.nodes[n].mainTagComponent.last_incoming_message_timestamp > last_incoming_message_timestamp: + last_incoming_message_timestamp = topo.nodes[n].mainTagComponent.last_incoming_message_timestamp + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: Initiator Tag)") + else: + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: None) [Unreached Node]") + else: + if topo.nodes[n].mainTagComponent.last_incoming_message_timestamp > last_incoming_message_timestamp: + last_incoming_message_timestamp = topo.nodes[n].mainTagComponent.last_incoming_message_timestamp + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: ", topo.nodes[n].mainTagComponent.initial_parent, ")") + +time_difference = last_incoming_message_timestamp - starting_time +print("Time Difference: ", time_difference) + +plt.show() diff --git a/tests/TagToTag/testTag_MerlinSegall.py b/tests/TagToTag/testTag_MerlinSegall.py new file mode 100644 index 0000000..897c8e8 --- /dev/null +++ b/tests/TagToTag/testTag_MerlinSegall.py @@ -0,0 +1,83 @@ +import random +import time +import datetime +from enum import Enum + +import matplotlib.pyplot as plt +import networkx as nx + +from TagToTag.GenericTag_MerlinSegall import TagComponent, TagMessageDestinationIdentifiers, TagMessageTypes +from Ahc import ComponentModel, MessageDestinationIdentifiers, Event, GenericMessageHeader, GenericMessagePayload, GenericMessage, EventTypes, ConnectorTypes, Topology, ComponentRegistry, registry +from Channels import TagToTagFIFOPerfectChannel + +class AdHocNode(ComponentModel): + + def on_init(self, eventobj: Event): + print(f"Initializing {self.componentname}.{self.componentinstancenumber}") + + def on_message_from_top(self, eventobj: Event): + # print("Outgoing Message from ", self.componentinstancenumber, ". Node", ", via channel: [", eventobj.eventcontent.header.interfaceid, "]") + self.send_down(Event(self, EventTypes.MFRT, eventobj.eventcontent)) + + def on_message_from_bottom(self, eventobj: Event): + # print("Incoming Message to ", self.componentinstancenumber, ". Node, From: ", eventobj.eventcontent.header.messagefrom) + self.send_up(Event(self, EventTypes.MFRB, eventobj.eventcontent)) + + def __init__(self, componentname, componentid): + + # SUBCOMPONENTS + self.mainTagComponent = TagComponent("MainTagComponent", componentid) + + # CONNECTIONS AMONG SUBCOMPONENTS + + # Connect the bottom component to the composite component.... + self.mainTagComponent.connect_me_to_component(ConnectorTypes.DOWN, self) + self.connect_me_to_component(ConnectorTypes.UP, self.mainTagComponent) + + super().__init__(componentname, componentid) + +def draw_randow_geometric_graph_with_edge_weight(node_count, radius, max_weight): + G = nx.random_geometric_graph(node_count, radius) + edges = list(G.edges) + for edge in edges: + random_weight = random.randint(1, max_weight) + G[edge[0]][edge[1]]['weight'] = random_weight + G[edge[1]][edge[0]]['weight'] = random_weight + node_positions = nx.get_node_attributes(G, 'pos') + node_labels = {node:node for node in G.nodes()} + edge_labels = nx.get_edge_attributes(G, 'weight') + nx.draw(G, node_positions, edge_color='black', node_color='blue', labels=node_labels) + nx.draw_networkx_edge_labels(G, node_positions, edge_labels=edge_labels, font_color='red') + return G + +node_count = 5 +radius = 0.8 +max_weight = 10 + +G = draw_randow_geometric_graph_with_edge_weight(node_count, radius, max_weight) + +topo = Topology() +topo.construct_from_weighted_graph(G, AdHocNode, TagToTagFIFOPerfectChannel) +topo.start() + +initiator_tag_id = 0 +topo.nodes[initiator_tag_id].mainTagComponent.start_initiator(node_count) + +time.sleep(3) + +starting_time = topo.nodes[initiator_tag_id].mainTagComponent.starting_message_timestamp +ending_time = topo.nodes[initiator_tag_id].mainTagComponent.ending_message_timestamp + +for n in topo.nodes: + if topo.nodes[n].mainTagComponent.initial_parent == None: + if n == initiator_tag_id: + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: Initiator Tag)") + else: + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: None) [Unreached Node]") + else: + print(n, ": (Distance: ", topo.nodes[n].mainTagComponent.initial_distance, ", Parent: ", topo.nodes[n].mainTagComponent.initial_parent, ")") + +time_difference = ending_time - starting_time +print("Time Difference: ", time_difference) + +plt.show() -- GitLab