import json from time import perf_counter from canonical_orbit import (all_permutations, product_group, exhaustive, canonical, canonical_dfs, orbit) def run(): n, k = 8, 4 blocks = [tuple(range(4)), tuple(range(4, 8))] group = product_group(blocks) masks = exhaustive(n, k) # Exact symmetry: every channel in block 0 has importance 3, and every # channel in block 1 has importance 1. Thus orbit-related masks score alike. score = lambda s: sum(3 if i < 4 else 1 for i in s) t0 = perf_counter() exhaustive_best = max((score(s), s) for s in masks) exhaustive_sec = perf_counter() - t0 t0 = perf_counter() reps = canonical_dfs(n, k, group) canonical_sec = perf_counter() - t0 canonical_best = max((score(s), s) for s in reps) reps_set = set(reps) covered = set().union(*(orbit(r, group) for r in reps_set)) orbit_invariance = all(score(s) == score(canonical(s, group)) for s in masks) return { "n": n, "k": k, "group_size": len(group), "all_masks": len(masks), "canonical_representatives": len(reps), "evaluation_reduction": len(masks) / len(reps), "exhaustive_best_score": exhaustive_best[0], "canonical_best_score": canonical_best[0], "same_best_score": exhaustive_best[0] == canonical_best[0], "orbit_coverage": covered == set(masks), "score_orbit_invariant": orbit_invariance, "exhaustive_scan_sec": exhaustive_sec, "canonical_dfs_sec": canonical_sec, } if __name__ == '__main__': print(json.dumps(run(), sort_keys=True))