From d284222a14e2453119cb87df31a97fcc8899a7b3 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 7 Dec 2024 14:39:47 +0800 Subject: [PATCH] feat: graph circle demo in marimo --- graph/circle.py | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100755 graph/circle.py diff --git a/graph/circle.py b/graph/circle.py new file mode 100755 index 0000000..9dac342 --- /dev/null +++ b/graph/circle.py @@ -0,0 +1,175 @@ +import marimo + +__generated_with = "0.9.27" +app = marimo.App(width="medium") + + +@app.cell +def __(): + import klotski + + code = klotski.CommonCode(0x1A9BF0C00) + + code.to_string(shorten=True) # just demo + return code, klotski + + +@app.cell(hide_code=True) +def __(): + import igraph as ig + + g = ig.Graph.Read_Pickle('main_combined.pkl') + + for i in range(g.vcount()): + g.vs[i]['codes'] = ['|'.join(g.vs[i]['codes'])] + + g.summary() + return g, i, ig + + +@app.cell +def __(): + # loop = g.girth(return_shortest_circle=True) + + # [(g.vs[x].degree(), g.vs[x]) for x in loop] # 8852(78) / 8923(79) / 8848(78) / 8922(79) + return + + +@app.cell +def __(): + # print(g.vs[8852].degree() + g.vs[8848].degree()) # endpoint pattern 1 -> 10 + # print(g.vs[8923].degree() + g.vs[8922].degree()) # endpoint pattern 2 -> 8 + return + + +@app.cell(hide_code=True) +def __(): + import marimo as mo + return (mo,) + + +@app.cell(hide_code=True) +def __(mo): + mo.md( + r""" + `endpoints: 8852 <---> 8848` + + So, we should try to combine `8923` and `8922`, the step are both `79`. + """ + ) + return + + +@app.cell +def __(): + # neigh_a = g.vs[8923].neighbors() + # neigh_b = g.vs[8922].neighbors() + # neigh = sorted(set(neigh_a) | set(neigh_b)) + + # print([x.index for x in neigh_a]) + # print([x.index for x in neigh_b]) + # print([x.index for x in neigh]) + + # new_point = g.add_vertex() + + # assert g.vs[8923]['step'] == g.vs[8922]['step'] + + # new_point['step'] = g.vs[8923]['step'] + # new_point['codes'] = g.vs[8923]['codes'] + g.vs[8922]['codes'] + + # new_point + return + + +@app.cell +def __(g): + # edges = [(x.index, new_point.index) for x in neigh] + + # print(edges) + + # g.add_edges(edges) + + # g.delete_vertices([8923, 8922]) + + g.summary() + return + + +@app.cell +def __(g): + def find_combine_points(circle_points: list[int]) -> list[tuple[int, int]]: + step_list = [g.vs[x]['step'] for x in circle_points] + + # step_list = [53, 52, 51, 52, 53, 54, 55, 56, 57, 56, 55, 54] + size = len(step_list) + assert size % 2 == 0 + half_size = int(size / 2) + + target = -1 + search_list = step_list + step_list + step_list + for index in range(size, size * 2): + right = search_list[index+1:index+half_size] + left = list(reversed(search_list[index+1-half_size:index])) + # print(f'{search_list[index]}: {left} vs {right} ({left == right})') + if left == right: + target = index - size + break + + # TODO: check degree() value + assert target != -1 + # print(target, step_list[target]) + + def fix_index(val: int): + if val < 0: + return val + size + if val >= size: + return val - size + return val + + combine_points = [] + for index in range(target + 1, target + half_size): + mirror = target * 2 - index + combine_points.append((fix_index(index), fix_index(mirror))) + + return [(circle_points[x], circle_points[y]) for x, y in combine_points] + + # find_combine_points([8852, 8923, 8848, 8922]) + return (find_combine_points,) + + +@app.cell +def __(find_combine_points, g): + # NOTE: only for mirror circle pattern + def combine_points(point_pairs: list[tuple[int, int]]): + g.vs['id'] = range(g.vcount()) + + for id_a, id_b in point_pairs: + point_a = [x for x in g.vs if x['id'] == id_a][0] + point_b = [x for x in g.vs if x['id'] == id_b][0] + assert point_a['step'] == point_b['step'] + print('combine:', point_a, point_b) + + neigh_a = point_a.neighbors() + neigh_b = point_b.neighbors() + neigh = sorted(set(neigh_a) | set(neigh_b)) + + new_point = g.add_vertex() + new_point['step'] = point_a['step'] + new_point['codes'] = point_a['codes'] + point_b['codes'] + # print(new_point) + g.add_edges([(x.index, new_point.index) for x in neigh]) + g.delete_vertices([point_a.index, point_b.index]) + + for i_ in range(146): + print(g.summary()) + loop = g.girth(return_shortest_circle=True) + print('circle:', loop) + combine_points(find_combine_points(loop)) + + print(g.summary()) + g.write_pickle('main_circle.pkl') + return combine_points, i_, loop + + +if __name__ == "__main__": + app.run()