-
Notifications
You must be signed in to change notification settings - Fork 1
/
naive.py
64 lines (42 loc) · 1.62 KB
/
naive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from typing import List
import math
from graph import Graph, Vertex, Edge
def naive_wsn(graph: Graph, network: Vertex, target: Vertex):
# First create a list of all edges in the graph
edges = list(set([e for v in graph.vertices for e in v.edges]))
rates = {v: 0.0 for v in graph.vertices}
for i in range(2 ** len(edges)):
# Generate the set of failed edges
failed = [edges[j] for j in range(len(edges)) if (i >> j) & 1 > 0]
# Get the set of directly impacted nodes
vertices = failed_vertices(target, failed)
reached = reachable(network, vertices)
# Compute the absolute list of impacted vertices
impacted = [v for v in graph.vertices if v not in reached]
chance = math.prod([e.weight if e in failed else 1.0 - e.weight for e in edges])
for v in impacted:
rates[v] += chance
influence = sum([k.households * v for (k, v) in rates.items()])
return influence, rates
def failed_vertices(target: Vertex, edges: List[Edge]) -> List[Vertex]:
visited = []
queue = [target]
while len(queue) > 0:
next = queue.pop()
if next in visited:
continue
visited.append(next)
for e in next.edges:
if e not in edges:
continue
other = e.get_other(next)
queue.append(other)
return visited
def reachable(network: Vertex, visited: List[Vertex]) -> List[Vertex]:
visited = visited + [network]
res = [network]
for v in network.neighbours:
if v in visited:
continue
res += reachable(v, visited)
return res