-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdefender.py
More file actions
133 lines (110 loc) · 4.51 KB
/
defender.py
File metadata and controls
133 lines (110 loc) · 4.51 KB
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import random
import numpy as np
import sample_strategy as ss
class Defender(object):
def __init__(self, G):
self.num_nodes = G.number_of_nodes()
self.observation = []
self.history = 3
self.prev_obs = [0]*self.num_nodes*(self.history - 1)
self.defact = set()
self.prev_defact = [set()]*self.history
self.rand_limit = 4
#TODO: nn should input mask!!!!!!! ALL zeros.
def def_greedy_action_builder(self, G, timeleft):
self.defact.clear()
isDup = False
mask = np.zeros(shape=(1, self.num_nodes), dtype=np.float32)
#TODO: sample a strategy
nn = ss.sample_strategy_from_mixed(env=self.myenv,str_set=self.str_set,mix_str=self.mix_str,identity=0)
self.set_current_strategy(nn)
while not isDup:
def_input = self.def_obs_constructor(G, timeleft)
x = self.nn_def(def_input[None], mask)[0] #corrensponding to baselines
if not isinstance(x,int):
raise ValueError("The chosen action is not an integer.")
action_space = self.get_def_actionspace(G)
action = action_space[x] #TODO: make sure whether x starting from 0 or 1.
if action == 'pass':
break
isDup = (action in self.defact)
if not isDup:
self.defact.add(action)
def def_greedy_action_builder_single(self, G, timeleft, nn_def):
self.defact.clear()
isDup = False
mask = np.zeros(shape=(1, self.num_nodes), dtype=np.float32)
while not isDup:
def_input = self.def_obs_constructor(G, timeleft)
x = nn_def(def_input[None], mask)[0] #corrensponding to baselines
if not isinstance(x,int):
raise ValueError("The chosen action is not an integer.")
action_space = self.get_def_actionspace(G)
action = action_space[x] # x starting from 0.
if action == 'pass':
break
isDup = (action in self.defact)
if not isDup:
self.defact.add(action)
#TODO: Since initialize with zeros, clean these funcs.
def def_obs_constructor(self, G, timeleft):
wasdef = self.get_def_wasDefended(G)
indef = self.get_def_inDefenseSet(G)
def_input = self.prev_obs + self.observation + wasdef + indef + [timeleft]
return np.array(def_input)
# TODO: Can we do matrix operation to get this vector?
def get_def_wasDefended(self, G):
wasdef = []
#old defact is added first.
for obs in self.prev_defact:
for node in G.nodes:
if node in obs:
wasdef.append(1)
else:
wasdef.append(0)
return wasdef
def get_def_inDefenseSet(self, G):
indef = []
for node in G.nodes:
if node in self.defact:
indef.append(1)
else:
indef.append(0)
return indef
def get_def_actionspace(self, G):
actionspace = list(G.nodes) + ['pass']
return actionspace
def uniform_strategy(self, G):
return set(sorted(random.sample(list(G.nodes), self.rand_limit)))
def cut_prev_obs(self):
if len(self.prev_obs)/self.num_nodes > self.history - 1:
self.prev_obs = self.prev_obs[(- self.history + 1)*self.num_nodes:]
def cut_prev_defact(self):
if len(self.prev_defact) > self.history:
self.prev_defact = self.prev_defact[-self.history:]
def save_defact2prev(self):
print("Don't forget to update defact after save_defact2prev.")
self.prev_defact.append(self.defact)
self.cut_prev_defact()
def update_obs(self, obs):
#TODO: check obs update for the first time step
self.prev_obs += self.observation #TODO: prev_obs is a list. Do not append.
self.cut_prev_obs()
self.observation = obs
# TODO: in env, feed noisy obs to the observation
def update_history(self, history):
self.history = history
def reset_def(self):
self.observation = []
self.prev_obs = [0] * self.num_nodes * (self.history - 1)
self.defact.clear()
self.prev_defact = [set()] * self.history
def set_current_strategy(self,strategy):
self.nn_def = strategy
#TODO: call this while creating env
def set_env_belong_to(self,env):
self.myenv = env
def set_mix_strategy(self,mix):
self.mix_str = mix
def set_str_set(self,set):
self.str_set = set