From 7270e035748abdac3fcaaa8da7953b721aca2380 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Tue, 13 May 2025 19:46:53 +0200 Subject: [PATCH 1/3] better assertion error in algorithms for variables given --- pycona/active_algorithms/gquacq.py | 3 ++- pycona/active_algorithms/growacq.py | 3 ++- pycona/active_algorithms/mquacq.py | 3 ++- pycona/active_algorithms/mquacq2.py | 3 ++- pycona/active_algorithms/pquacq.py | 3 ++- pycona/active_algorithms/quacq.py | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pycona/active_algorithms/gquacq.py b/pycona/active_algorithms/gquacq.py index d15e973..e4801f2 100644 --- a/pycona/active_algorithms/gquacq.py +++ b/pycona/active_algorithms/gquacq.py @@ -43,7 +43,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) diff --git a/pycona/active_algorithms/growacq.py b/pycona/active_algorithms/growacq.py index 180c524..a3fc740 100644 --- a/pycona/active_algorithms/growacq.py +++ b/pycona/active_algorithms/growacq.py @@ -40,7 +40,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) diff --git a/pycona/active_algorithms/mquacq.py b/pycona/active_algorithms/mquacq.py index 82bc580..2467f36 100644 --- a/pycona/active_algorithms/mquacq.py +++ b/pycona/active_algorithms/mquacq.py @@ -34,7 +34,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) diff --git a/pycona/active_algorithms/mquacq2.py b/pycona/active_algorithms/mquacq2.py index 93b4710..2e9b49d 100644 --- a/pycona/active_algorithms/mquacq2.py +++ b/pycona/active_algorithms/mquacq2.py @@ -44,7 +44,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) diff --git a/pycona/active_algorithms/pquacq.py b/pycona/active_algorithms/pquacq.py index 172284b..6cf579d 100644 --- a/pycona/active_algorithms/pquacq.py +++ b/pycona/active_algorithms/pquacq.py @@ -38,7 +38,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) diff --git a/pycona/active_algorithms/quacq.py b/pycona/active_algorithms/quacq.py index 2064f37..31352bd 100644 --- a/pycona/active_algorithms/quacq.py +++ b/pycona/active_algorithms/quacq.py @@ -34,7 +34,8 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos """ if X is None: X = instance.X - assert isinstance(X, list) and set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a list of variables" + assert isinstance(X, list), "When using .learn(), set parameter X must be a list of variables. Instead got: {}".format(X) + assert set(X).issubset(set(instance.X)), "When using .learn(), set parameter X must be a subset of the problem instance variables. Instead got: {}".format(X) self.env.init_state(instance, oracle, verbose, metrics) From 2ad58d7b0aac98a04e9b6e3322109fb88b2d3586 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Tue, 13 May 2025 19:47:10 +0200 Subject: [PATCH 2/3] handle names that do not have brackets --- pycona/utils.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/pycona/utils.py b/pycona/utils.py index e226c11..26f01bb 100644 --- a/pycona/utils.py +++ b/pycona/utils.py @@ -322,8 +322,9 @@ def get_var_name(var): :return: The name of the variable without its indices. """ name = re.findall(r"\[\d+[,\d+]*\]", var.name) - name = var.name.replace(name[0], '') - return name + if name: # Check if we found any indices + return var.name.replace(name[0], '') + return var.name # Return original name if no indices found def get_var_ndims(var): @@ -344,9 +345,11 @@ def get_var_dims(var): Get the dimensions of a variable. :param var: The variable. - :return: The dimensions of the variable. + :return: The dimensions of the variable. Returns empty list if variable has no indices. """ dims = re.findall(r"\[\d+[,\d+]*\]", var.name) + if not dims: # If no indices found + return [] dims_str = "".join(dims) dims = re.split(r"[\[\]]", dims_str)[1] dims = [int(dim) for dim in re.split(",", dims)] @@ -406,13 +409,18 @@ def get_variables_from_constraints(constraints): :param constraints: List of constraints. :return: List of variables involved in the constraints. """ - # Create set to hold unique variables variable_set = set() for constraint in constraints: variable_set.update(get_variables(constraint)) - extract_nums = lambda s: list(map(int, s.name[s.name.index("[") + 1:s.name.index("]")].split(','))) + def extract_nums(s): + dims = re.findall(r"\[\d+[,\d+]*\]", s.name) + if not dims: + return [0] # Default value for variables without indices + dims_str = "".join(dims) + dims = re.split(r"[\[\]]", dims_str)[1] + return [int(dim) for dim in re.split(",", dims)] variable_list = sorted(variable_set, key=extract_nums) return variable_list From 21ac81226d523b39ec67ecb17b2bfbc1f3955512 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Tue, 13 May 2025 19:47:32 +0200 Subject: [PATCH 3/3] accept lists of variables in probleminstance --- pycona/problem_instance/problem_instance.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pycona/problem_instance/problem_instance.py b/pycona/problem_instance/problem_instance.py index 1ad27d9..52f9ea2 100644 --- a/pycona/problem_instance/problem_instance.py +++ b/pycona/problem_instance/problem_instance.py @@ -123,7 +123,11 @@ def variables(self, vars): """ self._variables = vars if vars is not None: - self.X = list(self._variables.flatten()) + if isinstance(vars, NDVarArray): + self.X = list(self._variables.flatten()) + else: + self.X = vars + self._variables = cp.cpm_array(vars) @property def X(self):