def test_get_node_id(self):
     num_rows = 3
     num_cols = 3
     network_config = NetworkConfig(num_rows, num_cols)
     assert network_config.get_node_id((0,1)) == 0
     assert network_config.get_node_id((1, 0)) == 1
     assert network_config.get_node_id((1, 1)) == 2
     assert network_config.get_node_id((1, 2)) == 3
     assert network_config.get_node_id((2, 1)) == 4
     assert network_config.get_node_id((2, 2)) == -1
     assert network_config.get_node_id((2, 0)) == -1
     assert network_config.get_node_id((0, 0)) == -1
     assert network_config.get_node_id((0, 2)) == -1
Beispiel #2
0
 def randomize_attacker_position(self, network_config: NetworkConfig):
     temp_rows = list(range(1, network_config.num_rows))
     temp_cols = list(range(0, network_config.num_cols))
     positions = []
     for r in temp_rows:
         for c in temp_cols:
             node_id = network_config.get_node_id((r, c))
             if network_config.node_list[node_id] == NodeType.SERVER.value \
                     or network_config.node_list[node_id] == NodeType.START.value:
                 positions.append((r, c))
     rnd_idx = np.random.choice(list(range(len(positions))))
     rnd_pos = positions[rnd_idx]
     id = network_config.get_node_id(rnd_pos)
     if network_config.node_list[id] == NodeType.START.value:
         rnd_pos = network_config.start_pos
     self.attacker_pos = rnd_pos
Beispiel #3
0
    def get_attacker_observation(
            self,
            network_config: NetworkConfig,
            local_view=False,
            reconnaissance=False,
            reconnaissance_bool_features=False) -> np.ndarray:
        """
        Converts the state of the dynamical system into an observation for the attacker. As the environment
        is a partially observed markov decision process, the attacker observation is only a subset of the game state

        :param network_config: the network configuration of the game
        :param local_view: boolean flag indicating whether observations are provided in a local view or not
        :param reconnaissance: boolean flag indicating whether reconnaissance states should be included
        :param reconnaissance_bool_features: boolean flag whether to include boolean features that indicate if
                                             reconnaissance have been done for a certain defense type
        :return: An observation of the environment
        """
        if not reconnaissance:
            # +1 to have an extra feature that indicates if this is the node that the attacker is currently in
            attack_observation = np.zeros((len(network_config.node_list),
                                           self.attack_values.shape[1] + 1))
        elif reconnaissance and not reconnaissance_bool_features:
            # +1 to have an extra feature that indicates if this is the node that the attacker is currently in
            attack_observation = np.zeros(
                (len(network_config.node_list),
                 (self.attack_values.shape[1] * 2 + 1)))
        else:
            # +2 to have an extra feature that indicates if this is the node that the attacker is currently in and reconnaissance bool feature
            attack_observation = np.zeros(
                (len(network_config.node_list),
                 (self.attack_values.shape[1] * 2 + 2)))

        current_pos = self.attacker_pos
        current_node_id = network_config.get_node_id(current_pos)
        current_row, current_col = current_pos
        current_adjacency_matrix_id = network_config.get_adjacency_matrix_id(
            current_row, current_col)

        if local_view:
            neighbors = []

        for node_id in range(len(network_config.node_list)):
            pos = network_config.get_node_pos(node_id)
            node_row, node_col = pos
            node_adjacency_matrix_id = network_config.get_adjacency_matrix_id(
                node_row, node_col)
            if local_view:
                if network_config.adjacency_matrix[current_adjacency_matrix_id][node_adjacency_matrix_id] \
                        and node_id != current_node_id:
                    if not reconnaissance:
                        neighbor_data = np.append(self.attack_values[node_id],
                                                  node_id)
                    elif reconnaissance and not reconnaissance_bool_features:
                        neighbor_data = np.append(
                            np.append(self.attack_values[node_id], node_id),
                            self.reconnaissance_state[node_id]),
                    else:
                        reconaissance_bool = [0]
                        if node_id in self.reconnaissance_actions:
                            reconaissance_bool = [1]
                        neighbor_data = np.append(
                            np.append(
                                np.append(self.attack_values[node_id],
                                          node_id),
                                self.reconnaissance_state[node_id]),
                            reconaissance_bool)
                    neighbor_row, neighbor_col = network_config.get_node_pos(
                        node_id)
                    neighbors.append(
                        (neighbor_row, neighbor_col, neighbor_data))
            else:
                if node_id == current_node_id:
                    if not reconnaissance:
                        attack_observation[node_id] = np.append(
                            self.attack_values[node_id], 1)
                    elif reconnaissance and not reconnaissance_bool_features:
                        attack_observation[node_id] = np.append(
                            np.append(self.attack_values[node_id], 1),
                            self.reconnaissance_state[node_id])
                    else:
                        reconaissance_bool = [0]
                        if node_id in self.reconnaissance_actions:
                            reconaissance_bool = [1]
                        attack_observation[node_id] = np.append(
                            np.append(
                                np.append(self.attack_values[node_id], 1),
                                self.reconnaissance_state[node_id]),
                            reconaissance_bool)
                elif network_config.fully_observed:
                    attack_observation[node_id] = np.append(
                        self.attack_values[node_id], 0)
                elif network_config.adjacency_matrix[
                        current_adjacency_matrix_id][node_adjacency_matrix_id]:
                    if not reconnaissance:
                        attack_observation[node_id] = np.append(
                            self.attack_values[node_id], 0)
                    elif reconnaissance and not reconnaissance_bool_features:
                        attack_observation[node_id] = np.append(
                            np.append(self.attack_values[node_id], 0),
                            self.reconnaissance_state[node_id])
                    else:
                        reconaissance_bool = [0]
                        if node_id in self.reconnaissance_actions:
                            reconaissance_bool = [1]
                        attack_observation[node_id] = np.append(
                            np.append(
                                np.append(self.attack_values[node_id], 0),
                                self.reconnaissance_state[node_id]),
                            reconaissance_bool)
                elif reconnaissance:
                    if not reconnaissance_bool_features:
                        attack_values = np.zeros((self.attack_values.shape[1]))
                        attack_observation[node_id] = np.append(
                            np.append(attack_values, 0),
                            self.reconnaissance_state[node_id])
                    else:
                        reconaissance_bool = [0]
                        if node_id in self.reconnaissance_actions:
                            reconaissance_bool = [1]
                        attack_values = np.zeros((self.attack_values.shape[1]))
                        attack_observation[node_id] = np.append(
                            np.append(np.append(attack_values, 0),
                                      self.reconnaissance_state[node_id]),
                            reconaissance_bool)

        if local_view:
            # sort by row then col
            sorted_neighbors = sorted(neighbors, key=lambda x: (x[0], x[1]))
            neighbor_data = np.array(
                list(map(lambda x: x[2], sorted_neighbors)))
            neighbor_ids = neighbor_data[:, self.attack_values.shape[1]]
            if not reconnaissance:
                local_view_obs = np.full((network_config.max_neighbors,
                                          self.attack_values.shape[1] + 1), -1)
            elif reconnaissance and not reconnaissance_bool_features:
                local_view_obs = np.full((network_config.max_neighbors,
                                          self.attack_values.shape[1] * 2 + 1),
                                         -1)
            else:
                local_view_obs = np.full((network_config.max_neighbors,
                                          self.attack_values.shape[1] * 2 + 2),
                                         -1)
            for n in range(network_config.max_neighbors):
                rel_neighbor_pos = network_config.relative_neighbor_positions[
                    n]
                neighbor_pos = (current_row + rel_neighbor_pos[0],
                                current_col + rel_neighbor_pos[1])
                for i in range(len(neighbor_ids)):
                    node_id = neighbor_ids[i]
                    node_pos = network_config.get_node_pos(node_id)
                    if node_pos == neighbor_pos and node_pos[0] <= current_row:
                        local_view_obs[n] = neighbor_data[i]
            attack_observation = np.array(local_view_obs)
        return attack_observation