diff --git a/misc/all-graph/spilt.py b/misc/all-graph/00-spilt_groups.py similarity index 100% rename from misc/all-graph/spilt.py rename to misc/all-graph/00-spilt_groups.py diff --git a/misc/all-graph/build_json.py b/misc/all-graph/01-build_json.py similarity index 100% rename from misc/all-graph/build_json.py rename to misc/all-graph/01-build_json.py diff --git a/misc/all-graph/dump_igraph.py b/misc/all-graph/02-dump_igraph.py similarity index 100% rename from misc/all-graph/dump_igraph.py rename to misc/all-graph/02-dump_igraph.py diff --git a/misc/all-graph/build.py b/misc/all-graph/build.py deleted file mode 100755 index 7f61cee..0000000 --- a/misc/all-graph/build.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/env python3 - -import json -import igraph as ig -from klotski import Group, Layout, FastCal - - -def layout_to_str(layout: Layout) -> str: - code = str(layout) - assert len(code) == 9 and code.endswith('00') - return code[:7] - - -def build_graph(group: Group, targets: set[Layout], ignores: set[Layout]) -> dict[Layout, dict]: - steps = {x: [] for x in list(group.cases())} - assert len(steps) == group.size - - for target in targets: - fc = FastCal(target) - fc.build_all() - layers = fc.exports() - assert sum(len(x) for x in layers) == group.size - - for step, layouts in enumerate(layers): - [steps[x].append(step) for x in layouts] - - graph = {} - for layout in steps: - assert len(steps[layout]) == len(targets) - graph[layout] = {'step': min(steps[layout]), 'next': set()} - - for layout, info in graph.items(): - for x in layout.next_cases(): - if graph[x]['step'] == info['step'] + 1: - info['next'].add(x) - - # print('valid', graph[Layout('DAFA730')]) - # print('invalid', graph[Layout('D0ABDBC')]) - # print('normal', graph[Layout('1a9bf0c')]) - - # print('D0ABDBC', graph[Layout('D0ABDBC')]) - # print('DCA8DBC', graph[Layout('DCA8DBC')]) - # print('DFA81BC', graph[Layout('DFA81BC')]) - # print('DFA21BC', graph[Layout('DFA21BC')]) - # print('DFAA4CC', graph[Layout('DFAA4CC')]) - - for ignore in ignores: - assert ignore in graph - for x in graph[ignore]['next']: - assert x in ignores - - for layout, info in graph.items(): - if ignore in info['next'] and layout not in ignores: - assert layout in targets - - for ignore in ignores: - del graph[ignore] - - for layout, info in graph.items(): - need_remove = [] - for x in info['next']: - if x in ignores: - assert layout in targets - need_remove.append(x) - for x in need_remove: - info['next'].remove(x) - - for layout, info in graph.items(): - for x in info['next']: - assert x in graph - - return graph - - -def dump_json(graph: dict[Layout, dict]) -> str: - data = {} - for layout, info in graph.items(): - data[layout_to_str(layout)] = { - 'step': info['step'], - 'next': [layout_to_str(x) for x in info['next']] - } - return json.dumps(data, separators=(',', ':')) - - -def dump_igraph(graph: dict[Layout, dict]) -> ig.Graph: - index_map = {x: i for i, x in enumerate(graph)} - g = ig.Graph(len(graph)) - for index, (layout, info) in enumerate(graph.items()): - g.vs[index]['code'] = layout_to_str(layout) - g.vs[index]['step'] = info['step'] - g.add_edges([(index, index_map[x]) for x in info['next']]) - return g - - -def load_and_dump(info: dict, path_prefix: str) -> None: - targets = [Layout(x) for x in info['solutions']['valid']] - ignores = set(Layout(x) for x in info['solutions']['invalid']) - graph = build_graph(targets[0].group, set(targets), ignores) - - with open(f'{path_prefix}.json', 'w') as fp: - fp.write(dump_json(graph)) - - ig_graph = dump_igraph(graph) - ig_graph.write_pickle(f'{path_prefix}.pickle') - # ig_graph.write_picklez(f'{path_prefix}.picklez') - ig_graph.write_graphml(f'{path_prefix}.graphml') - # ig_graph.write_graphmlz(f'{path_prefix}.graphmlz') - - -if __name__ == '__main__': - raw = json.loads(open('data.json').read()) - # raw = {'1-00M': raw['1-00M']} - - for name, info in raw.items(): - print(name) - load_and_dump(info, f'./output/{name}') diff --git a/misc/all-graph/compare_ig.py b/misc/all-graph/compare_ig.py new file mode 100644 index 0000000..828b60a --- /dev/null +++ b/misc/all-graph/compare_ig.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import os +import igraph as ig + + +def compare(file_1: str, file_2: str) -> None: + print(f'{file_1} vs {file_2}') + g1 = ig.Graph.Read_Pickle(file_1) + g2 = ig.Graph.Read_Pickle(file_2) + + assert g1.vcount() == g2.vcount() + assert g1.ecount() == g2.ecount() + assert g1.isomorphic(g2) + + for edge in g1.es: + assert edge.attributes() == {} + + for edge in g2.es: + assert edge.attributes() == {} + + for i in range(g1.vcount()): + assert g1.vs[i].attributes() == g2.vs[i].attributes() + + +if __name__ == '__main__': + for name in sorted(os.listdir('output-ig')): + compare(f'output/{name}', f'output-ig/{name}') diff --git a/misc/all-graph/compare_json.py b/misc/all-graph/compare_json.py new file mode 100644 index 0000000..746ea06 --- /dev/null +++ b/misc/all-graph/compare_json.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +import os +import json + + +def format_1(raw: str) -> str: + graph = json.loads(raw) + assert sorted(graph) == list(graph) + for layout, info in graph.items(): + info['next'] = sorted(info['next']) + return json.dumps(graph) + + +def format_2(raw: str) -> str: + graph = json.loads(raw)['graph'] + for layout, info in graph.items(): + graph[layout] = {'step': info['step'], 'next': info['next']} + return json.dumps(graph) + + +def compare(file_1: str, file_2: str) -> None: + print(f'{file_1} vs {file_2}') + data_1 = format_1(open(file_1).read()) + data_2 = format_2(open(file_2).read()) + assert data_1 == data_2 + + +if __name__ == '__main__': + for name in sorted(os.listdir('output-json')): + compare(f'output/{name}', f'output-json/{name}')