diff --git a/src/topupopt/problems/esipp/time.py b/src/topupopt/problems/esipp/time.py index 7fc02bb54917c22c185ce6335b8609a151551635..378483afc0cd638454288f59a92303314269249b 100644 --- a/src/topupopt/problems/esipp/time.py +++ b/src/topupopt/problems/esipp/time.py @@ -134,8 +134,13 @@ class TimeFrame: def consecutive_qpk(self, qpk_keyed_dict: dict) -> bool: "Returns True if all (q,p,k) tuple keys are valid and consecutive." - # TODO: here - raise NotImplementedError + # all k intervals have to be consecutive for each (q,p) pair + set_qp = set(qpk[0:2] for qpk in qpk_keyed_dict.keys()) + for qp in set_qp: + for k in range(self.number_time_intervals(qp[0])): + if (*qp,k) not in qpk_keyed_dict: + return False + return True # ************************************************************************* # ************************************************************************* diff --git a/tests/test_esipp_time.py b/tests/test_esipp_time.py index 349f2701aaaa9e784f9310a89942352c012566ec..18bdd01fa3b29e5e445c80717a442678a7d944df 100644 --- a/tests/test_esipp_time.py +++ b/tests/test_esipp_time.py @@ -202,6 +202,28 @@ class TestTimeFrame: assert not tf.complete_qpk( {(0, 0, 0): 1, (0, 0, 1): 1, (0, 1, 0): 1, (0, 1, 1): 1} ) + # qpk: consecutive + assert tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 0): 1, + (0, 1, 1): 1, + (0, 2, 0): 1, + (0, 2, 1): 1, + } + ) + # qpk: not consecutive + assert not tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 1): 1, + (0, 1, 2): 1, + (0, 2, 0): 1, + (0, 2, 1): 1, + } + ) qk_dict = {qk: None for qk in tf.qk()} qp_dict = {qp: None for qp in tf.qp()} @@ -357,6 +379,28 @@ class TestTimeFrame: assert not tf.complete_qpk( {(0, 0, 0): 1, (0, 0, 1): 1, (1, 1, 0): 1, (1, 1, 1): 1} ) + # qpk: consecutive + assert tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (1, 1, 0): 1, + (1, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + } + ) + # qpk: not consecutive + assert not tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 3): 1, + (1, 1, 0): 1, + (1, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + } + ) qk_dict = {qk: None for qk in tf.qk()} qp_dict = {qp: None for qp in tf.qp()} @@ -507,6 +551,30 @@ class TestTimeFrame: (1, 2, 1): 1, } ) + # qpk: consecutive + assert tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 0): 1, + (0, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + (1, 2, 2): 1, + } + ) + # qpk: not consecutive + assert not tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 0): 1, + (0, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + (1, 2, 3): 1, + } + ) qk_dict = {qk: None for qk in tf.qk()} qp_dict = {qp: None for qp in tf.qp()} @@ -672,6 +740,40 @@ class TestTimeFrame: (1, 2, 1): 1, } ) + # qpk: consecutive + assert tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 0): 1, + (0, 1, 1): 1, + (0, 2, 0): 1, + (0, 2, 1): 1, + (1, 0, 0): 1, + (1, 0, 1): 1, + (1, 1, 0): 1, + (1, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + } + ) + # qpk: not consecutive + assert not tf.consecutive_qpk( + { + (0, 0, 0): 1, + (0, 0, 1): 1, + (0, 1, 0): 1, + (0, 1, 1): 1, + (0, 2, 0): 1, + (0, 2, 2): 1, + (1, 0, 0): 1, + (1, 0, 1): 1, + (1, 1, 0): 1, + (1, 1, 1): 1, + (1, 2, 0): 1, + (1, 2, 1): 1, + } + ) qk_dict = {qk: None for qk in tf.qk()} qp_dict = {qp: None for qp in tf.qp()} @@ -905,6 +1007,40 @@ class TestTimeFrame: # (5, 2, 1): 1, } ) + # qpk: consecutive + assert tf.consecutive_qpk( + { + (0, 0, 0): 1, + (1, 0, 0): 1, + (2, 1, 0): 1, + (3, 1, 0): 1, + (4, 2, 0): 1, + (5, 2, 0): 1, + (0, 0, 1): 1, + (1, 0, 1): 1, + (2, 1, 1): 1, + (3, 1, 1): 1, + (4, 2, 1): 1, + (5, 2, 1): 1, + } + ) + # qpk: not consecutive + assert not tf.consecutive_qpk( + { + (0, 0, 0): 1, + (1, 0, 0): 1, + (2, 1, 0): 1, + (3, 1, 0): 1, + (4, 2, 0): 1, + (5, 2, 0): 1, + (0, 0, 2): 1, + (1, 0, 1): 1, + (2, 1, 1): 1, + (3, 1, 1): 1, + (4, 2, 1): 1, + (5, 2, 1): 1, + } + ) qk_dict = {qk: None for qk in tf.qk()} qp_dict = {qp: None for qp in tf.qp()}