Coverage for flexnetsim/network.py: 100%
187 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-22 20:03 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-22 20:03 +0000
1from .node import Node
2from .link import Link
3import json
6class Network():
8 def __init__(self, arg=None):
9 self.__link_counter = 0
10 self.__node_counter = 0
11 self.__nodes = []
12 self.__links = []
13 self.__links_in = []
14 self.__links_out = []
15 self.__nodes_in = []
16 self.__nodes_out = []
18 self.nodes_in.append(0)
19 self.nodes_out.append(0)
21 if arg != None:
22 if isinstance(arg, Network):
23 self.__link_counter = arg.link_counter
24 self.__node_counter = arg.node_counter
25 self.__nodes = arg.nodes
26 self.__links = arg.links
27 self.__links_in = arg.links_in
28 self.__links_out = arg.links_out
29 self.__nodes_in = arg.nodes_in
30 self.__nodes_out = arg.nodes_out
31 else:
32 f = open(arg)
33 NSFnet = json.load(f)
34 f.close()
35 nummber_of_nodes = len(NSFnet["nodes"])
36 number_of_links = len(NSFnet["links"])
37 for i in range(0, nummber_of_nodes):
38 id = NSFnet["links"][i]["id"]
39 node = Node(id)
40 self.add_node(node)
42 for i in range(0, number_of_links):
43 id = NSFnet["links"][i]["id"]
44 length = NSFnet["links"][i]["length"]
45 slots = NSFnet["links"][i]["slots"]
46 link = Link(id, length, slots)
47 self.add_link(link)
49 src = NSFnet["links"][i]["src"]
50 id = NSFnet["links"][i]["id"]
51 dst = NSFnet["links"][i]["dst"]
52 self.connect(src, id, dst)
54 @property
55 def nodes(self):
56 return self.__nodes
58 @property
59 def links(self):
60 return self.__links
62 @property
63 def node_counter(self):
64 return self.__node_counter
66 @property
67 def nodes_in(self):
68 return self.__nodes_in
70 @property
71 def nodes_out(self):
72 return self.__nodes_out
74 @property
75 def link_counter(self):
76 return self.__link_counter
78 @property
79 def links_out(self):
80 return self.__links_out
82 @property
83 def links_in(self):
84 return self.__links_in
86 def get_link(self, link_pos):
87 if(link_pos < 0) or (link_pos >= len(self.__links)):
88 raise ValueError("Cannot get Link from a position out of bounds.")
89 return self.__links[link_pos]
91 def get_node(self, node_pos):
92 if (node_pos < 0) or (node_pos >= len(self.__nodes)):
93 raise ValueError("Cannot get Node from a position out of bounds.")
94 return self.__nodes[node_pos]
96 def add_node(self, node: Node):
97 if node.id != self.__node_counter:
98 raise ValueError(
99 "Cannot add a Node to this network with Id mismatching node counter.")
100 self.__node_counter += 1
101 self.__nodes.append(node)
102 self.__nodes_in.append(0)
103 self.__nodes_out.append(0)
105 def add_link(self, link: Link):
106 if link.id != self.__link_counter:
107 raise ValueError(
108 "Cannot add a Link to this network with Id mismatching link counter.")
109 self.__link_counter += 1
110 self.__links.append(link)
112 def connect(self, src, link_pos, dst):
113 if(src < 0) or (src >= self.__node_counter):
114 raise ValueError(
115 f"Cannot connect src {src} because its ID is not in the network. Number of nodes in network: {self.node_counter}")
117 if(dst < 0) or (dst >= self.__node_counter):
118 raise ValueError(
119 f"Cannot connect dst {dst} because its ID is not in the network. Number of nodes in network: {self.node_counter}")
121 if(link_pos < 0) or (link_pos >= self.__link_counter):
122 raise ValueError(
123 f"Cannot use link {link_pos} because its ID is not in the network. Number of links in network: {self.link_counter}")
125 self.__links_out.insert(self.__nodes_out[src], self.__links[link_pos])
126 for i in range((src+1), len(self.__nodes_out)):
127 self.__nodes_out[i] += 1
128 self.__links_in.insert(self.__nodes_in[dst], self.__links[link_pos])
129 for i in range((dst+1), len(self.__nodes_in)):
130 self.__nodes_in[i] += 1
131 self.__links[link_pos].src = src
132 self.__links[link_pos].dst = dst
134 def is_connected(self, src, dst):
135 for i in range(self.__nodes_out[src], self.__nodes_out[src+1]):
136 for j in range(self.__nodes_in[dst], self.__nodes_in[dst+1]):
137 if self.__links_out[i].id == self.__links_in[j].id:
138 return self.__links_out[i].id
139 return -1
141 def use_slot(self, link_pos, *, slot_pos=None, slot_from=None, slot_to=None):
142 if (link_pos < 0) or (link_pos >= len(self.__links)):
143 raise ValueError("Link position out of bounds")
144 if (slot_pos != None) and (slot_from == None) and (slot_to == None):
145 if(slot_pos < 0) or (slot_pos >= self.__links[link_pos].slots_number()):
146 raise ValueError("Slot position out of bounds.")
147 self.__links[link_pos].set_slot(slot_pos, True)
149 elif (slot_pos == None) and (slot_from != None) and (slot_to != None):
150 if(slot_from < 0) or (slot_from >= self.__links[link_pos].slots_number()):
151 raise ValueError("Slot position out of bounds.")
152 if(slot_to < 0) or (slot_to >= self.__links[link_pos].slots_number()):
153 raise ValueError("Slot position out of bounds.")
154 if(slot_from > slot_to):
155 raise ValueError(
156 "Initial slot position must be lower than the final slot position.")
157 if(slot_from == slot_to):
158 raise ValueError("Slot from and slot To cannot be equals.")
160 for i in range(slot_from, slot_to):
161 self.__links[link_pos].set_slot(i, True)
163 else:
164 raise ValueError("Incorrect arguments given.")
166 def unuse_slot(self, link_pos, *, slot_pos=None, slot_from=None, slot_to=None):
167 if (link_pos < 0) or (link_pos >= len(self.__links)):
168 raise ValueError("Link position out of bounds")
169 if (slot_pos != None) and (slot_from == None) and (slot_to == None):
170 if(slot_pos < 0) or (slot_pos >= self.__links[link_pos].slots_number()):
171 raise ValueError("Slot position out of bounds.")
172 self.__links[link_pos].set_slot(slot_pos, False)
174 elif (slot_pos == None) and (slot_from != None) and (slot_to != None):
175 if(slot_from < 0) or (slot_from >= self.__links[link_pos].slots_number()):
176 raise ValueError("Slot position out of bounds.")
177 if(slot_to < 0) or (slot_to >= self.__links[link_pos].slots_number()):
178 raise ValueError("Slot position out of bounds.")
179 if(slot_from > slot_to):
180 raise ValueError(
181 "Initial slot position must be lower than the final slot position.")
182 if(slot_from == slot_to):
183 raise ValueError("Slot from and slot To cannot be equals.")
185 for i in range(slot_from, slot_to):
186 self.__links[link_pos].set_slot(i, False)
188 else:
189 raise ValueError("Incorrect arguments given.")
191 def is_slot_used(self, link_pos, *, slot_pos=None, slot_from=None, slot_to=None):
192 if (link_pos < 0) or (link_pos >= len(self.__links)):
193 raise ValueError("Link position out of bounds")
194 if (slot_pos != None) and (slot_from == None) and (slot_to == None):
195 if(slot_pos < 0) or (slot_pos >= self.__links[link_pos].slots_number()):
196 raise ValueError("Slot position out of bounds.")
197 return self.__links[link_pos].get_slot(slot_pos)
199 elif (slot_pos == None) and (slot_from != None) and (slot_to != None):
200 if(slot_from < 0) or (slot_from >= self.__links[link_pos].slots_number()):
201 raise ValueError("Slot position out of bounds.")
202 if(slot_to < 0) or (slot_to >= self.__links[link_pos].slots_number()):
203 raise ValueError("Slot position out of bounds.")
204 if(slot_from > slot_to):
205 raise ValueError(
206 "Initial slot position must be lower than the final slot position.")
207 if(slot_from == slot_to):
208 raise ValueError("Slot from and slot To cannot be equals.")
210 for i in range(slot_from, slot_to):
211 if self.__links[link_pos].get_slot(i):
212 return True
213 return False
215 else:
216 raise ValueError("Incorrect arguments given.")
218 def average_neighborhood(self):
219 if self.__node_counter == 0:
220 raise ValueError("The network must be have at least one node.")
221 result = self.__link_counter/self.__node_counter
222 return result
224 def normal_average_neighborhood(self):
225 if self.__node_counter == 0:
226 raise ValueError("The network must be have at least one node.")
227 result = self.__link_counter / \
228 (self.__node_counter * (self.__node_counter - 1))
229 return result
231 def nodal_variance(self):
232 if self.__node_counter == 0:
233 raise ValueError("The network must be have at least one node.")
234 result = 0.0
235 average = self.average_neighborhood()
236 for i in range(self.__node_counter):
237 result += pow((self.__nodes_out[i+1] -
238 self.__nodes_out[i])-average, 2)
239 result /= self.__node_counter
240 return result