class TestSimulation(unittest.TestCase): def setUp(self): self.test_graph = Graph() self.test_node_0 = Node(0, 0.1, 1, 1, 1, 1, 1, 1) self.test_node_1 = Node(1, 0.2, 2, 2, 2, 2, 2, 2) self.test_node_2 = Node(2, 0.3, 1, 2, 3, 4, 5, 6) self.test_graph.add_vertex(self.test_node_0) self.test_graph.add_vertex(self.test_node_1) self.test_graph.add_vertex(self.test_node_2) self.test_graph.add_edge(self.test_node_0, self.test_node_1, 30) self.test_graph.add_edge(self.test_node_1, self.test_node_2, 50) self.test_sim = Simulation() self.test_sim.load_graph(self.test_graph) def test_spread(self): res1 = min(1, Simulation.sigmoid(30) * 0.15) res2 = min(1, Simulation.sigmoid(60) * 0.25 * 1.2) self.assertAlmostEqual( Simulation.spread(self.test_node_0, self.test_node_1), res1) self.assertAlmostEqual( Simulation.spread(self.test_node_1, self.test_node_2), res2) def test_calc_new_score(self): res = (Simulation.spread(self.test_node_0, self.test_node_1) + Simulation.spread(self.test_node_2, self.test_node_1)) / 2 self.assertAlmostEqual(self.test_sim.calc_new_score(self.test_node_1), res) def test_run_one_timestep(self): print(self.test_sim.graph.get_scores()) self.test_sim.run_one_timestep() print(self.test_sim.graph.get_scores())
def extended_popularity_similarity_optimisation_model(N, m, L=0, beta=1 / 2, T=0): def distance(i, j): r_i, phi_i, r_j, phi_j = r[i], phi[i], r[j], phi[j] r_j = beta * r_i + (1 - beta) * r_j d_phi = pi - abs(pi - abs(phi_i - phi_j)) return cosh(r_i) * cosh(r_j) + sinh(r_i) * sinh(r_j) * cos(d_phi) if beta == 0: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * (1 - exp(-r_i / 2)) / m) elif beta == 1: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * r_i / m) else: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * (1 - exp(-r_i * (1 - beta) / 2)) / m / (1 - beta)) def connection_probability(d_ij, cutoff_i): return 1 / (1 + exp((d_ij - cutoff_i) / 2 / T)) G = Graph() r = [2 * math.log(i + 1) for i in range(N)] phi = [2 * math.pi * random.random() for _ in range(N)] for i in range(N): G.add_vertex(i, r=r[i], phi=phi[i]) #G.add_vertex(i, x=r[i]*math.cos(phi[i]), y=r[i]*math.sin(phi[i])) m += 2 * L * (1 - beta) / (1 - N**(beta - 1))**2 / (2 * beta - 1) * ( (N / i)**(2 * beta - 1) - 1) * (1 - i**(beta - 1)) if i <= m: for j in range(i): G.add_edge(i, j) elif T == 0: neighbours = sorted(range(i), key=lambda j: distance(i, j))[m] for j in neighbours: G.add_edge(i, j) else: cutoff_i = cutoff(r[i]) for j in range(i): d_ij = distance(r[i], phi[i], r[j], phi[j]) if random.random() < connection_probability(d_ij, cutoff_i): G.add_edge(i, j) return G
def popularity_similarity_optimisation_model(N, m, beta=1 / 2, T=0): def distance(i, j): r_i, phi_i, r_j, phi_j = r[i], phi[i], r[j], phi[j] r_j = beta * r_i + (1 - beta) * r_j d_phi = pi - abs(pi - abs(phi_i - phi_j)) return acosh( cosh(r_i) * cosh(r_j) + sinh(r_i) * sinh(r_j) * cos(d_phi)) if beta == 0: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * (1 - exp(-r_i / 2)) / m) elif beta == 1: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * r_i / m) else: def cutoff(r_i): return r_i - 2 * log(T / sin(T * pi) * (1 - exp(-r_i * (1 - beta) / 2)) / m / (1 - beta)) def connection_probability(d_ij, cutoff_i): return 1 / (1 + exp((d_ij - cutoff_i) / 2 / T)) G = Graph() r = [2 * math.log(i) for i in range(1, N + 1)] phi = [2 * math.pi * random.random() for _ in range(N)] for i in range(N): G.add_vertex(i, r=geometry.native_disk_to_hyperboloid(r[i]), phi=phi[i]) if i <= m: for j in range(i): G.add_edge(i, j) elif T == 0: print(i) print(sorted(range(i), key=lambda v: v)) neighbours = sorted(range(i), key=lambda j: distance(i, j))[:m] for j in neighbours: G.add_edge(i, j) else: cutoff_i = cutoff(r[i]) for j in range(i): d_ij = distance(r[i], phi[i], r[j], phi[j]) if random.random() < connection_probability(d_ij, cutoff_i): G.add_edge(i, j) return G
def empty_graph(N=0, directed=False): ''' Create an empty graph of given size. Parameters ---------- N:int Number of vertices. Returns ------- G : Graph Generated empty graph ''' G = Graph() if not directed else DiGraph() for i in range(N): G.add_vertex(i) return G
class TestGraph(unittest.TestCase): def setUp(self): self.test_graph = Graph() self.test_node_0 = Node(0, 0.1, 1, 1, 1, 1, 1, 1) self.test_node_1 = Node(1, 0.1, 1, 1, 1, 1, 1, 1) def test_add_vertex(self): # add the two test nodes self.test_graph.add_vertex(self.test_node_0) self.test_graph.add_vertex(self.test_node_1) # see if they are in the graph vertex dictionary self.assertEqual(len(self.test_graph.vertices), 2) self.assertTrue(0 in self.test_graph.vertices) self.assertTrue(1 in self.test_graph.vertices) # if node already in graph, do not allow adding with self.assertRaises(AssertionError): self.test_graph.add_vertex(self.test_node_0) def test_add_edge(self): n0, n1 = self.test_node_0, self.test_node_1 strength: int = 10 self.test_graph.add_vertex(n0) self.test_graph.add_vertex(n1) self.test_graph.add_edge(n0, n1, strength) self.assertTrue(1 in n0.neighbours) self.assertTrue(0 in n1.neighbours) # check bidirectional strength self.assertEqual(n0.neighbours[1], strength) self.assertEqual(n1.neighbours[0], strength) # do not allow adding the same edge with self.assertRaises(AssertionError): self.test_graph.add_edge(n0, n1, strength) with self.assertRaises(AssertionError): self.test_graph.add_edge(n1, n0, strength) def test_remove_vertex(self): n0, n1 = self.test_node_0, self.test_node_1 n2 = Node(2, 0.1, 1, 1, 1, 1, 1, 1) self.test_graph.add_vertex(n0) self.test_graph.add_vertex(n1) self.test_graph.add_vertex(n2) self.test_graph.add_edge(n0, n1, 5) self.test_graph.add_edge(n1, n2, 15) self.test_graph.add_edge(n2, n0, 25) self.test_graph.remove_vertex(0) # test_node_0 no longer in neighbours dicts self.assertFalse(0 in n1.neighbours) self.assertFalse(0 in n2.neighbours) # neighbours edges intact self.assertTrue(2 in n1.neighbours) self.assertTrue(1 in n2.neighbours) self.assertFalse(0 in self.test_graph.vertices) # try to remove something that is removed with self.assertRaises(AssertionError): self.test_graph.remove_vertex(0) self.test_graph.remove_vertex(1) self.assertFalse(1 in n2.neighbours) def test_get_node(self): self.test_graph.add_vertex(self.test_node_0) self.assertEqual(self.test_graph.get_node(0), self.test_node_0) with self.assertRaises(AssertionError): self.test_graph.get_node(1)