def get_problem_class( active_degree: int, passive_degree: int, label_count: int, is_directed_or_rooted: bool, actives_all_same: bool = False, passives_all_same: bool = False, is_tree: bool = False, is_cycle: bool = False, is_path: bool = False, count_limit: Optional[int] = None, skip_count: Optional[int] = None, ) -> List[GenericProblem]: flags = ProblemFlags( is_tree=is_tree, is_cycle=is_cycle, is_path=is_path, is_directed_or_rooted=is_directed_or_rooted, ) props = ProblemProps( active_degree, passive_degree, label_count, actives_all_same=actives_all_same, passives_all_same=passives_all_same, flags=flags, ) query = Query(props) return [p.to_problem() for p in get_classified_problem_objs(query)]
def problem(args): p = GenericProblem( args["active_constraints"], args["passive_constraints"], args["leaf_constraints"], args["root_constraints"], leaf_allow_all=(args["leaf_constraints"] == []), root_allow_all=(args["root_constraints"] == []), flags=ProblemFlags(is_tree=args["is_tree"], is_cycle=args["is_cycle"], is_path=args["is_path"]), ) classified_problem = get_classified_problem_obj(p) if classified_problem is not None: return jsonify({ "problem": classified_problem.to_problem().dict(), "result": classified_problem.to_response().dict(), }) else: res = classify(p) if not (res.det_lower_bound == CONST and res.det_upper_bound == UNSOLVABLE and res.rand_lower_bound == CONST and res.rand_upper_bound == UNSOLVABLE): store_problem_and_classification(p, res) return jsonify({"problem": p.dict(), "result": res.dict()})
def test_brt0(self): binary_rooted_tree_problem0 = GenericProblem( ["a : a a"], ["a : a"], flags=ProblemFlags(is_tree=True)) res = classify(binary_rooted_tree_problem0) self.assertEqual(res.det_lower_bound, CONST) self.assertEqual(res.det_upper_bound, CONST) self.assertEqual(res.rand_upper_bound, CONST) self.assertEqual(res.rand_lower_bound, CONST)
def query(args): query = Query( props=ProblemProps( active_degree=args["active_degree"], passive_degree=args["passive_degree"], label_count=args["label_count"], actives_all_same=args["actives_all_same"], passives_all_same=args["passives_all_same"], flags=ProblemFlags( is_tree=args["is_tree"], is_cycle=args["is_cycle"], is_path=args["is_path"], is_directed_or_rooted=args["is_directed_or_rooted"], is_regular=args["is_regular"], ), ), bounds=Bounds( rand_upper_bound=args["rand_upper_bound"], rand_lower_bound=args["rand_lower_bound"], det_upper_bound=args["det_upper_bound"], det_lower_bound=args["det_lower_bound"], ), exclude_include=QueryExcludeInclude( exclude_if_config_has_all_of=args["exclude_if_config_has_all_of"], exclude_if_config_has_some_of=args[ "exclude_if_config_has_some_of"], include_if_config_has_all_of=args["include_if_config_has_all_of"], include_if_config_has_some_of=args[ "include_if_config_has_some_of"], return_largest_problem_only=args["largest_problem_only"], return_smallest_problem_only=args["smallest_problem_only"], completely_rand_unclassifed_only=args[ "completely_rand_unclassified_only"], partially_rand_unclassified_only=args[ "partially_rand_unclassified_only"], completely_det_unclassifed_only=args[ "completely_det_unclassified_only"], partially_det_unclassified_only=args[ "partially_det_unclassified_only"], ), ) problems = get_classified_problem_objs(query) stats = compute_stats(problems) batches = get_batch_classification_by_query(query) is_response_complete = is_query_response_complete(batches) response = { "problems": (None if args["fetch_stats_only"] else [{ **p.to_unparsed_problem().dict(), **p.to_response().dict() } for p in problems]), "stats": stats.dict(), "is_complete": is_response_complete, } return jsonify(response)
def test_cycle_path4(self): # -undir -n "{ 11, 22, 33 }" -e "{ 12, 21, 13, 31, 23, 32 }" # cycle path classifier cycle_path_problem4 = GenericProblem( ["A A", "B B", "C C"], ["A B", "B A", "A C", "C A", "B C", "C B"], flags=ProblemFlags(is_cycle=True, is_path=False, is_tree=False), ) res = classify(cycle_path_problem4) self.assertEqual(res.det_lower_bound, ITERATED_LOG) self.assertEqual(res.det_upper_bound, ITERATED_LOG) self.assertEqual(res.rand_upper_bound, ITERATED_LOG) self.assertEqual(res.rand_lower_bound, ITERATED_LOG)
def test_cycle_path1(self): # 3-coloring on a rooted trees (degree not known i.e. not just binary) # 12, 13, 23, 21, 31, 32 in automata-theoretic formalism # cycle path classifier cycle_path_tree_problem1 = GenericProblem( ["a : a a a a", "b : b b b b", "c : c c c c"], ["a : b", "a : c", "b : c", "b : a", "c : a", "c : b"], flags=ProblemFlags(is_tree=True, ), ) res = classify(cycle_path_tree_problem1) self.assertEqual(res.det_lower_bound, ITERATED_LOG) self.assertEqual(res.det_upper_bound, ITERATED_LOG) self.assertEqual(res.rand_upper_bound, ITERATED_LOG) self.assertEqual(res.rand_lower_bound, ITERATED_LOG)
def reclassify_problem_class( active_degree: int, passive_degree: int, label_count: int, is_directed_or_rooted: bool, actives_all_same: bool = False, passives_all_same: bool = False, is_tree: bool = False, is_cycle: bool = False, is_path: bool = False, count_limit: Optional[int] = None, skip_count: Optional[int] = None, ): """ Reclassify a class of already existing problems that are stored in the DB. This is much faster than generating the class of problems all over again and classifying them. This is mainly because the generation step takes very long for big (even if partial) problem classes """ flags = ProblemFlags( is_tree=is_tree, is_cycle=is_cycle, is_path=is_path, is_directed_or_rooted=is_directed_or_rooted, ) props = ProblemProps( active_degree, passive_degree, label_count, actives_all_same, passives_all_same, flags=flags, ) query = Query(props) responses = get_classified_problem_objs(query) ps_with_ids = [r.to_problem() for r in responses] classify_and_store( ps_with_ids, props=props, count_limit=count_limit if count_limit is None else len(ps_with_ids), skip_count=skip_count, ) res = get_classified_problem_objs(query) stats = compute_stats(res) pretty_print(stats)
def test_brt3(self): # "121", # "131" # "132" # decider, tree-classification # output: unsolvable binary_rooted_tree_problem3 = GenericProblem( ["b : a a", "c : a a", "c : a b"], ["a : a", "b : b", "c : c"], flags=ProblemFlags(is_tree=True), ) res = classify(binary_rooted_tree_problem3) self.assertEqual(res.det_lower_bound, UNSOLVABLE) self.assertEqual(res.det_upper_bound, UNSOLVABLE) self.assertEqual(res.rand_upper_bound, UNSOLVABLE) self.assertEqual(res.rand_lower_bound, UNSOLVABLE)
def test_brt2(self): # "121", # "132", # "213" # decider, tree-classification # output: O(log n) binary_rooted_tree_problem2 = GenericProblem( ["b : a a", "c : a b", "a : b c"], ["a : a", "b : b", "c : c"], flags=ProblemFlags(is_tree=True), ) res = classify(binary_rooted_tree_problem2) self.assertEqual(res.det_lower_bound, LOG) self.assertEqual(res.det_upper_bound, LOG) self.assertEqual(res.rand_upper_bound, LOG) self.assertEqual(res.rand_lower_bound, LOG)
def test_brt1(self): # "111", # "121", # "131" # "132" # decider, tree-classification # output: O(1) binary_rooted_tree_problem1 = GenericProblem( ["a : a a", "b : a a", "c : a a", "c : a b"], ["a : a", "b : b", "c : c"], flags=ProblemFlags(is_tree=True), ) res = classify(binary_rooted_tree_problem1) self.assertEqual(res.det_lower_bound, CONST) self.assertEqual(res.det_upper_bound, CONST) self.assertEqual(res.rand_upper_bound, CONST) self.assertEqual(res.rand_lower_bound, CONST)
def test_classifier3(self): active_degree = 2 passive_degree = 2 label_count = 3 actives_all_same = False passives_all_same = False flags = ProblemFlags(is_tree=False, is_cycle=False, is_path=True, is_directed_or_rooted=False) ps = generate( active_degree, passive_degree, label_count, actives_all_same, passives_all_same, flags, ) self.__runTest("test_data/classifications3.pickle", ps)
def to_problem(self) -> GenericProblem: p = GenericProblem(["A A"], ["A A"]) p.id = self.id p.active_constraints = self.active_constraints p.passive_constraints = self.passive_constraints p.leaf_constraints = self.leaf_constraints p.root_constraints = self.root_constraints alphabet = p.get_alphabet() p.leaf_allow_all = (set(flatten(p.leaf_constraints)) - {" "}) == set(alphabet) p.root_allow_all = (set(flatten(p.root_constraints)) - {" "}) == set(alphabet) p.flags = ProblemFlags( is_tree=self.is_tree, is_cycle=self.is_cycle, is_path=self.is_path, is_directed_or_rooted=self.is_directed_or_rooted, is_regular=self.is_regular, ) return p
def test_cycle_path3(self): # -dir -n "{00, 1M}" -e "{01, 10, 11, MM}" # --start-constr "{ 1 }" --end-constr "{ 0 }" # cycle path classifier cycle_path_problem3 = GenericProblem( ["A : A", "B : M"], # node constraints ["A : B", "B : A", "B : B", "M : M"], # edge constraints leaf_constraints=["B"], leaf_allow_all=False, # leaf constraint = end-constr root_constraints=["B"], root_allow_all=False, # root constraint = start-constr flags=ProblemFlags( is_cycle=False, is_path=True, is_tree=False, ), ) res = classify(cycle_path_problem3) self.assertEqual(res.det_lower_bound, CONST) self.assertEqual(res.det_upper_bound, CONST) self.assertEqual(res.rand_upper_bound, CONST) self.assertEqual(res.rand_lower_bound, CONST)
def measure_problem_query( active_degree: int, passive_degree: int, label_count: int, is_directed_or_rooted: bool, actives_all_same: bool = False, passives_all_same: bool = False, is_tree: bool = False, is_cycle: bool = False, is_path: bool = False, ) -> None: flags = ProblemFlags( is_tree=is_tree, is_cycle=is_cycle, is_path=is_path, is_directed_or_rooted=is_directed_or_rooted, ) props = ProblemProps( active_degree, passive_degree, label_count, actives_all_same=actives_all_same, passives_all_same=passives_all_same, flags=flags, ) query = Query(props) repeats = 1 r = timeit.timeit( "get_classified_problem_objs(query)", "gc.enable()", number=repeats, globals={ "query": query, "get_classified_problem_objs": get_classified_problem_objs, "gc": gc, }, ) print("Query fetch time was %s" % (r / repeats))
def generate_problem_class( active_degree: int, passive_degree: int, label_count: int, is_directed_or_rooted: bool, actives_all_same: bool = False, passives_all_same: bool = False, is_tree: bool = False, is_cycle: bool = False, is_path: bool = False, count_limit: Optional[int] = None, skip_count: Optional[int] = None, ): print("Press Enter to generate next class of problems...") input() print("Generating the following:") print(" active_degree = %s," % active_degree) print(" passive_degree = %s," % passive_degree) print(" label_count = %s," % label_count) print(" is_directed_or_rooted = %s" % is_directed_or_rooted) flags = ProblemFlags( is_tree=is_tree, is_cycle=is_cycle, is_path=is_path, is_directed_or_rooted=is_directed_or_rooted, ) props = ProblemProps( active_degree, passive_degree, label_count, actives_all_same, passives_all_same, flags=flags, ) query = Query(props) ps = generate( active_degree, passive_degree, label_count, actives_all_same, passives_all_same, flags, count_limit=(sys.maxsize if count_limit is None else count_limit), skip_count=(0 if skip_count is None else skip_count), ) problems_with_id = (store_problem_and_get_with_id(p) for p in ps) classify_and_store( # TODO: replace the classification part with generators-based pipeline too list(problems_with_id), props=props, count_limit=count_limit if count_limit is None else len(ps), skip_count=skip_count, ) res = get_classified_problem_objs(query) stats = compute_stats(res) pretty_print(stats)