|
|
|
import numpy as np
|
|
|
|
import sample_path as sp
|
|
|
|
import networkx as nx
|
|
|
|
import node
|
|
|
|
|
|
|
|
|
|
|
|
class NetworkGraph():
|
|
|
|
"""
|
|
|
|
Rappresenta un grafo dinamico con la seguente struttura:
|
|
|
|
{Key: {Arcs:{node_object: #in_arcs.....}, Time:t, Node:node_object}.....}
|
|
|
|
Key = lo state_id del nodo
|
|
|
|
Arcs = la lista di adiacenza del nodo identificato dalla stringa state_id, contenente oggetti di tipo Node
|
|
|
|
Time = lo state residence time del nodo identificato dalla stringa state_id
|
|
|
|
Node = L'oggetto Node con lo stesso state_id pari a Key e node_id opportunamento inizalizzato
|
|
|
|
|
|
|
|
:sample_path: le traiettorie/a da cui costruire il grafo
|
|
|
|
:graph: la struttura dinamica che definisce il grafo
|
|
|
|
:states_number: il numero di nodi contenuti nel grafo graph
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self, sample_path):
|
|
|
|
self.sample_path = sample_path
|
|
|
|
self.graph = {}
|
|
|
|
|
|
|
|
|
|
|
|
def initialize_graph(self, trajectory):
|
|
|
|
"""
|
|
|
|
Data la traiettoria trajectory inizializza le chiavi del dizionario graph e crea le opportune sottostrutture interne.
|
|
|
|
|
|
|
|
"""
|
|
|
|
for(node_id,state) in enumerate(trajectory.get_states()):
|
|
|
|
n = node.Node(state, node_id)
|
|
|
|
self.graph[state] = {"Arcs":{}, "Time":0.0, "Node":n}
|
|
|
|
self.states_number += 1
|
|
|
|
|
|
|
|
|
|
|
|
def build_graph_from_first_traj(self, trajectory):
|
|
|
|
self.initialize_graph(trajectory)
|
|
|
|
matrix_traj = trajectory.get_trajectory_as_matrix()
|
|
|
|
for indx in range(len(matrix_traj) - 1):
|
|
|
|
self.add_transaction(matrix_traj, indx)
|
|
|
|
|
|
|
|
def add_transaction(self, matrix_traj, indx):
|
|
|
|
"""
|
|
|
|
Aggiunge la transizione dal nodo current_state al nodo next_state e aggiorna lo state residence time del nodo
|
|
|
|
con chiave current_state.
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
matrix_traj: la traiettoria con cui si sta costruendo il grafo graph
|
|
|
|
indx: la posizione nella visita
|
|
|
|
Returns:
|
|
|
|
void
|
|
|
|
"""
|
|
|
|
current_state = matrix_traj[indx][1]
|
|
|
|
next_state = matrix_traj[indx + 1][1]
|
|
|
|
self.graph[current_state]["Time"] += matrix_traj[indx + 1][0] - matrix_traj[indx][0]
|
|
|
|
next_node = self.graph[next_state]["Node"] #Punta all'oggeto Node con node_id precedentemente settato
|
|
|
|
if next_node not in self.graph[current_state]["Arcs"].keys(): #Se non hai ancora incontrato next_node inizializza il numero di archi entranti
|
|
|
|
self.graph[current_state]["Arcs"][next_node] = 1
|
|
|
|
else:
|
|
|
|
self.graph[current_state]["Arcs"][next_node] += 1
|
|
|
|
|
|
|
|
def append_new_trajectory(self, trajectory):
|
|
|
|
"""
|
|
|
|
Aggiunge i risultati di una nuova esplorazione trajectory al grafo graph.
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
trajectory: la traiettoria da aggiungere
|
|
|
|
Returns:
|
|
|
|
void
|
|
|
|
"""
|
|
|
|
matrix_traj = trajectory.get_trajectory_as_matrix()
|
|
|
|
|
|
|
|
current_state = matrix_traj[0][1] #Aggiungi se necessario i primi due stati
|
|
|
|
next_state = matrix_traj[1][1]
|
|
|
|
self.add_node_if_not_present(current_state)
|
|
|
|
self.add_node_if_not_present(next_state)
|
|
|
|
self.add_transaction(matrix_traj, 0)
|
|
|
|
|
|
|
|
for indx in range(1, (len(matrix_traj) - 1)):
|
|
|
|
current_state = matrix_traj[indx][1]
|
|
|
|
next_state = matrix_traj[indx + 1][1]
|
|
|
|
self.add_node_if_not_present(next_state)
|
|
|
|
self.add_transaction(matrix_traj, indx)
|
|
|
|
|
|
|
|
def add_node_if_not_present(self, current_state):
|
|
|
|
if current_state not in self.graph.keys(): #Se non hai ancora incontrato il lo state current_state
|
|
|
|
current_node = node.Node(current_state, self.states_number) #Crea il l'oggetto con opportuno node_id
|
|
|
|
self.graph[current_state] = {"Arcs":{}, "Time":0.0, "Node":current_node} #Aggiungilo al dizionario graph
|
|
|
|
self.states_number += 1
|
|
|
|
|
|
|
|
def build_graph(self):
|
|
|
|
for indx, trajectory in enumerate(self.sample_path.trajectories):
|
|
|
|
if indx == 0:
|
|
|
|
self.build_graph_from_first_traj(trajectory)
|
|
|
|
else:
|
|
|
|
self.append_new_trajectory(trajectory)
|
|
|
|
|
|
|
|
def get_root_node(self):
|
|
|
|
return self.graph[list(self.graph)[0]]["Node"]
|
|
|
|
|
|
|
|
def get_neighbours(self, node):
|
|
|
|
return self.graph[node.state_id]["Arcs"]
|
|
|
|
|
|
|
|
|
|
|
|
######Veloci Tests#######
|
|
|
|
|
|
|
|
#s1 = sp.SamplePath()
|
|
|
|
#s1.build_trajectories()
|
|
|
|
#print(s1.get_number_trajectories())
|
|
|
|
|
|
|
|
#g1 = DynamicGraph(s1)
|
|
|
|
#g1.build_graph()
|
|
|
|
#print(g1.graph)
|
|
|
|
#print(g1.states_number)
|