From 323e7400f33ccb3b1246e902d2d254eddb6eb26c Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 20:23:29 +0200 Subject: [PATCH 1/8] do not empty bias before return --- pycona/active_algorithms/genacq.py | 1 - pycona/active_algorithms/mineacq.py | 1 - pycona/active_algorithms/mquacq.py | 1 - pycona/active_algorithms/mquacq2.py | 1 - pycona/active_algorithms/pquacq.py | 1 - pycona/active_algorithms/quacq.py | 1 - 6 files changed, 6 deletions(-) diff --git a/pycona/active_algorithms/genacq.py b/pycona/active_algorithms/genacq.py index fc43212..34cb48c 100644 --- a/pycona/active_algorithms/genacq.py +++ b/pycona/active_algorithms/genacq.py @@ -68,7 +68,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.total_queries} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generation_time(gen_end - gen_start) diff --git a/pycona/active_algorithms/mineacq.py b/pycona/active_algorithms/mineacq.py index a9b262f..2885058 100644 --- a/pycona/active_algorithms/mineacq.py +++ b/pycona/active_algorithms/mineacq.py @@ -66,7 +66,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.total_queries} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generation_time(gen_end - gen_start) diff --git a/pycona/active_algorithms/mquacq.py b/pycona/active_algorithms/mquacq.py index 2467f36..565e047 100644 --- a/pycona/active_algorithms/mquacq.py +++ b/pycona/active_algorithms/mquacq.py @@ -62,7 +62,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.membership_queries_count} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generation_time(gen_end - gen_start) diff --git a/pycona/active_algorithms/mquacq2.py b/pycona/active_algorithms/mquacq2.py index 2813b70..11ba0ea 100644 --- a/pycona/active_algorithms/mquacq2.py +++ b/pycona/active_algorithms/mquacq2.py @@ -69,7 +69,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.membership_queries_count} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generated_queries() diff --git a/pycona/active_algorithms/pquacq.py b/pycona/active_algorithms/pquacq.py index 6cf579d..b591085 100644 --- a/pycona/active_algorithms/pquacq.py +++ b/pycona/active_algorithms/pquacq.py @@ -62,7 +62,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.membership_queries_count} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generation_time(gen_end - gen_start) diff --git a/pycona/active_algorithms/quacq.py b/pycona/active_algorithms/quacq.py index 31352bd..b28c4d6 100644 --- a/pycona/active_algorithms/quacq.py +++ b/pycona/active_algorithms/quacq.py @@ -58,7 +58,6 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos if self.env.verbose >= 1: print(f"\nLearned {self.env.metrics.cl} constraints in " f"{self.env.metrics.membership_queries_count} queries.") - self.env.instance.bias = [] return self.env.instance self.env.metrics.increase_generation_time(gen_end - gen_start) From 13e8d16d27f5bf5d95cef70b6c4ea3e3ba0d30c3 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 20:24:40 +0200 Subject: [PATCH 2/8] Add implied constraints from bias to cl --- pycona/active_algorithms/growacq.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pycona/active_algorithms/growacq.py b/pycona/active_algorithms/growacq.py index a3fc740..ba2c2b9 100644 --- a/pycona/active_algorithms/growacq.py +++ b/pycona/active_algorithms/growacq.py @@ -67,6 +67,10 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos print(f"\nGrowAcq: calling inner_algorithm for {len(Y)}/{n_vars} variables") self.env.instance = self.inner_algorithm.learn(self.env.instance, oracle, verbose=verbose, X=Y, metrics=self.env.metrics) + # Add implied constraints from bias to cl + self.env.instance.cl.extend(self.env.instance.bias) + self.env.instance.bias = [] # clear bias + if verbose >= 3: print("C_L: ", len(self.env.instance.cl)) print("B: ", len(self.env.instance.bias)) From 22fec1a444b0cd9c4d42a32ab901f04126c8e5cb Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 20:44:31 +0200 Subject: [PATCH 3/8] fix when bias is given and not generated in growacq --- pycona/active_algorithms/growacq.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pycona/active_algorithms/growacq.py b/pycona/active_algorithms/growacq.py index ba2c2b9..a1bdbfe 100644 --- a/pycona/active_algorithms/growacq.py +++ b/pycona/active_algorithms/growacq.py @@ -7,7 +7,7 @@ from ..answering_queries import Oracle, UserOracle from .. import Metrics from ..ca_environment import ProbaActiveCAEnv - +from ..utils import get_con_subset class GrowAcq(AlgorithmCAInteractive): """ @@ -68,8 +68,9 @@ def learn(self, instance: ProblemInstance, oracle: Oracle = UserOracle(), verbos self.env.instance = self.inner_algorithm.learn(self.env.instance, oracle, verbose=verbose, X=Y, metrics=self.env.metrics) # Add implied constraints from bias to cl - self.env.instance.cl.extend(self.env.instance.bias) - self.env.instance.bias = [] # clear bias + implied_constraints = get_con_subset(self.env.instance.bias, Y) + self.env.instance.cl.extend(implied_constraints) + self.env.instance.bias = [c for c in self.env.instance.bias if c not in set(implied_constraints)] # remove implied constraints from bias if verbose >= 3: print("C_L: ", len(self.env.instance.cl)) From d7840e63fd2d06b82ebc117e38ac3480f1d61610 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 20:44:45 +0200 Subject: [PATCH 4/8] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 24c8d48..af16f01 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ notebooks/.ipynb_checkpoints/Prediction-based CA system-checkpoint.ipynb dist/pycona-0.2.4-py3-none-any.whl dist/pycona-0.2.4.tar.gz notebooks/.ipynb_checkpoints/Comparing different algorithms and methods-checkpoint.ipynb +testing.py From 1b33d6ab3ffa334b62373b8674a80b909dd0fbd6 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 20:55:49 +0200 Subject: [PATCH 5/8] test findc2 also on growacq --- tests/test_finc.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_finc.py b/tests/test_finc.py index 3ac5455..ca7e98f 100644 --- a/tests/test_finc.py +++ b/tests/test_finc.py @@ -77,5 +77,19 @@ def test_findc2_with_golomb4(self): learned_not_oracle += cp.any([~c for c in oracle.constraints]) assert not learned_not_oracle.solve() + # test growacq + alg = ca.GrowAcq(ca_env, alg) + li2 = alg.learn(instance, oracle) + + # oracle model imply learned? + oracle_not_learned = cp.Model(oracle.constraints) + oracle_not_learned += cp.any([~c for c in li2._cl]) + assert not oracle_not_learned.solve() + + # learned model imply oracle? + learned_not_oracle = cp.Model(li2._cl) + learned_not_oracle += cp.any([~c for c in oracle.constraints]) + assert not learned_not_oracle.solve() + From f7a8e13e14d42b26b18054073f75e7daecd0d5b7 Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Fri, 8 Aug 2025 21:25:24 +0200 Subject: [PATCH 6/8] leftover input in nqueens --- pycona/benchmarks/nqueens.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pycona/benchmarks/nqueens.py b/pycona/benchmarks/nqueens.py index cc3bfd9..976554f 100644 --- a/pycona/benchmarks/nqueens.py +++ b/pycona/benchmarks/nqueens.py @@ -3,7 +3,7 @@ from ..answering_queries.constraint_oracle import ConstraintOracle from ..problem_instance import ProblemInstance, absvar -def construct_nqueens_problem(n): +def construct_nqueens_problem(n=8): parameters = {"n": n} @@ -43,6 +43,4 @@ def construct_nqueens_problem(n): for c in oracle.constraints: print(c) - input("Press Enter to continue...") - return instance, oracle From 109d46437eb39c7c19aad27557d0005ed059015a Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Sun, 10 Aug 2025 15:40:18 +0100 Subject: [PATCH 7/8] fix environment issue --- tests/test_algorithms.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/test_algorithms.py b/tests/test_algorithms.py index ed24c00..cddfdce 100644 --- a/tests/test_algorithms.py +++ b/tests/test_algorithms.py @@ -11,7 +11,7 @@ # Modify the problem generators for fast tests fast_problem_generators = [construct_murder_problem()] # Keep only the smallest problem -problem_generators = [construct_murder_problem(), construct_examtt_simple(), construct_nurse_rostering()] +problem_generators = [construct_murder_problem(), construct_examtt_simple(3,3,3,6), construct_nurse_rostering(3,3,6,1)] classifiers = [DecisionTreeClassifier(), RandomForestClassifier()] algorithms = [ca.QuAcq(), ca.MQuAcq(), ca.MQuAcq2(), ca.MineAcq(), ca.PQuAcq(), ca.GenAcq()] @@ -33,7 +33,6 @@ def _generate_base_inputs(fast=False): for comb in combs: yield comb - def _generate_proba_inputs(fast=False): if fast: combs = product(_generate_fast_benchmarks(), fast_tests_algorithms, [DecisionTreeClassifier()]) # Use minimal combinations @@ -116,6 +115,7 @@ def test_base_algorithms_with_initial_cl(self, bench, algorithm): (instance, oracle) = bench # Create a copy of the instance to avoid modifying the original instance = instance.copy() + env = ca.ActiveCAEnv() # Get some constraints from the oracle's constraint set initial_constraints = oracle.constraints[:len(oracle.constraints)//2] # Take half of the constraints @@ -123,6 +123,7 @@ def test_base_algorithms_with_initial_cl(self, bench, algorithm): initial_cl_size = len(instance.cl) ca_system = algorithm + ca_system.env = env learned_instance = ca_system.learn(instance=instance, oracle=oracle) assert ca_system.env.metrics.converged assert learned_instance.get_cpmpy_model().solve() @@ -162,7 +163,8 @@ def test_base_algorithms_with_bias(self, bench, algorithm): (instance, oracle) = bench # Create a copy of the instance to avoid modifying the original instance = instance.copy() - + env = ca.ActiveCAEnv() + # Generate bias constraints for the instance instance.construct_bias() # Separate constraints into those from oracle and others @@ -172,6 +174,7 @@ def test_base_algorithms_with_bias(self, bench, algorithm): instance.bias = list(oracle_constraints) + other_constraints[:len(other_constraints)//2] ca_system = algorithm + ca_system.env = env learned_instance = ca_system.learn(instance=instance, oracle=oracle) assert len(learned_instance.cl) > 0 assert learned_instance.get_cpmpy_model().solve() From 294eb4719d4a047cca72d4f9ac75e5f86d3bcf4e Mon Sep 17 00:00:00 2001 From: Dimos Tsouros Date: Sun, 10 Aug 2025 15:40:29 +0100 Subject: [PATCH 8/8] rename test_findc --- tests/{test_finc.py => test_findc.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{test_finc.py => test_findc.py} (100%) diff --git a/tests/test_finc.py b/tests/test_findc.py similarity index 100% rename from tests/test_finc.py rename to tests/test_findc.py