diff --git a/README.rst b/README.rst
index 3d05d9a..38a7c57 100755
--- a/README.rst
+++ b/README.rst
@@ -79,6 +79,12 @@ License
What's new
----------
+
+- 2023-05-14 (v 0.12.0) (MINOR release)
+
+ + Renamed `NASimEnv.get_minimum_actions -> NASimEnv.get_minumum_hops` to better reflect what it does (thanks @rzvnbr for the suggestion).
+
+
- 2023-03-13 (v 0.11.0) (MINOR release)
+ Migrated to `gymnasium (formerly Open AI gym) `_ fromOpen AI gym (thanks @rzvnbr for the suggestion).
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 78a9b87..4c44be2 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -9,6 +9,12 @@ The environment is modelled after the `gymnasium (formerly Open AI gym) NASimEnv.get_minumum_hops` to better reflect what it does (thanks @rzvnbr for the suggestion).
+
+
Version 0.11.0
**************
diff --git a/nasim/__init__.py b/nasim/__init__.py
index 2e6a575..40e593b 100755
--- a/nasim/__init__.py
+++ b/nasim/__init__.py
@@ -211,4 +211,4 @@ def _register(id, entry_point, kwargs, nondeterministic, force=True):
nondeterministic=True
)
-__version__ = "0.11.0"
+__version__ = "0.12.0"
diff --git a/nasim/envs/environment.py b/nasim/envs/environment.py
index 6a87f7f..dcd74be 100755
--- a/nasim/envs/environment.py
+++ b/nasim/envs/environment.py
@@ -395,18 +395,19 @@ def render_network_graph(self, ax=None, show=False):
state = self.current_state
self._renderer.render_graph(state, ax, show)
- def get_minimum_actions(self):
- """Get the minimum number of actions required to reach the goal.
+ def get_minimum_hops(self):
+ """Get the minimum number of network hops required to reach targets.
- That is minimum number of actions to exploit all sensitive hosts on
- the network starting from the initial state
+ That is minimum number of hosts that must be traversed in the network
+ in order to reach all sensitive hosts on the network starting from the
+ initial state
Returns
-------
int
- minumum possible actions to reach goal
+ minumum possible number of network hops to reach target hosts
"""
- return self.network.get_minimal_steps()
+ return self.network.get_minimal_hops()
def get_action_mask(self):
"""Get a vector mask for valid actions.
@@ -432,10 +433,10 @@ def get_score_upper_bound(self):
The theoretical upper bound score is where the agent exploits only a
single host in each subnet that is required to reach sensitive hosts
- along the shortest bath in network graph, and exploits the two
- sensitive hosts (i.e. the minial steps). Assuming action cost of 1 and
- each sensitive host is exploitable from any other connected subnet
- (which may not be true, hence being an upper bound).
+ along the shortest bath in network graph, and exploits the all
+ sensitive hosts (i.e. the minimum network hops). Assuming action cost
+ of 1 and each sensitive host is exploitable from any other connected
+ subnet (which may not be true, hence being an upper bound).
Returns
-------
@@ -444,7 +445,7 @@ def get_score_upper_bound(self):
"""
max_reward = self.network.get_total_sensitive_host_value()
max_reward += self.network.get_total_discovery_value()
- max_reward -= self.network.get_minimal_steps()
+ max_reward -= self.network.get_minimal_hops()
return max_reward
def goal_reached(self, state=None):
diff --git a/nasim/envs/network.py b/nasim/envs/network.py
index 359b188..5284d1f 100755
--- a/nasim/envs/network.py
+++ b/nasim/envs/network.py
@@ -1,7 +1,7 @@
import numpy as np
from nasim.envs.action import ActionResult
-from nasim.envs.utils import get_minimal_steps_to_goal, min_subnet_depth, AccessLevel
+from nasim.envs.utils import get_minimal_hops_to_goal, min_subnet_depth, AccessLevel
# column in topology adjacency matrix that represents connection between
# subnet and public
@@ -225,8 +225,8 @@ def get_total_discovery_value(self):
total += host.discovery_value
return total
- def get_minimal_steps(self):
- return get_minimal_steps_to_goal(
+ def get_minimal_hops(self):
+ return get_minimal_hops_to_goal(
self.topology, self.sensitive_addresses
)
diff --git a/nasim/envs/utils.py b/nasim/envs/utils.py
index d348789..7b4fca8 100644
--- a/nasim/envs/utils.py
+++ b/nasim/envs/utils.py
@@ -49,15 +49,15 @@ def __repr__(self):
return self.name
-def get_minimal_steps_to_goal(topology, sensitive_addresses):
- """Get the minimum total number of steps required to reach all sensitive
- hosts in the network starting from outside the network (i.e. can only
- reach exposed subnets).
+def get_minimal_hops_to_goal(topology, sensitive_addresses):
+ """Get minimum network hops required to reach all sensitive hosts.
+
+ Starting from outside the network (i.e. can only reach exposed subnets).
Returns
-------
int
- minimum number of steps to reach all sensitive hosts
+ minimum number of network hops to reach all sensitive hosts
"""
num_subnets = len(topology)
max_value = np.iinfo(np.int16).max
diff --git a/test/test_env.py b/test/test_env.py
index 149f476..2f3943e 100644
--- a/test/test_env.py
+++ b/test/test_env.py
@@ -60,3 +60,14 @@ def test_get_total_sensitive_host_value(scenario, expected_value):
env.reset()
actual_value = env.network.get_total_sensitive_host_value()
assert actual_value == expected_value
+
+
+@pytest.mark.parametrize(
+ ("scenario", "expected_value"),
+ [("tiny", 3), ("small", 4)]
+)
+def test_get_minumum_hops(scenario, expected_value):
+ env = nasim.make_benchmark(scenario)
+ env.reset()
+ actual_value = env.get_minimum_hops()
+ assert actual_value == expected_value