华容道高性能计算引擎
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

95 lines
2.7 KiB

#!/usr/bin/env python3
import os
from typing import override
from dataclasses import dataclass
import igraph as ig
from lxml import etree
from graphml import INode, IEdge, Config, GraphML
@dataclass(frozen=True)
class Node(INode):
tag: str
step: int
codes: list[str]
@staticmethod
@override
def add_keys(graphml: etree.Element, cfg: Config) -> None:
etree.SubElement(graphml, 'key', attrib={
'id': 'step',
'for': 'node',
'attr.name': 'step',
'attr.type': 'int'
})
etree.SubElement(graphml, 'key', attrib={
'id': 'codes',
'for': 'node',
'attr.name': 'codes',
'attr.type': 'string'
})
if cfg.is_yed:
INode._add_yed_key(graphml)
@override
def render(self, cfg: Config) -> etree.Element:
node_xml = etree.Element('node', id=self.tag)
etree.SubElement(node_xml, 'data', key='step').text = str(self.step)
etree.SubElement(node_xml, 'data', key='codes').text = '+'.join(self.codes)
if cfg.is_yed:
color = cfg.colors[self.step]
label = f'{self.tag}
({self.step})'
node_xml.append(self._yed_render(cfg, color, label))
return node_xml
@dataclass(frozen=True)
class Edge(IEdge):
src: str
dst: str
@staticmethod
@override
def add_keys(graphml: etree.Element, cfg: Config) -> None:
pass
@override
def render(self, is_yed: bool) -> etree.Element:
return etree.Element('edge', source=self.src, target=self.dst)
def to_graphml(tag: str, file: str, output: str, is_yed: bool) -> None:
print(f'Convert graph {file} into {output}')
g = ig.Graph.Read_Pickle(file)
nodes = []
for v in g.vs:
node = Node(v['tag'], v['step'], v['codes'])
nodes.append(node)
edges = []
for n1, n2 in g.get_edgelist():
node_1 = nodes[n1]
node_2 = nodes[n2]
if node_1.step < node_2.step:
node_1, node_2 = node_2, node_1
edges.append(Edge(node_1.tag, node_2.tag))
gml = GraphML(tag, nodes, edges)
colors = GraphML.build_colors(max(x.step for x in nodes) + 1, ['#0000ff', '#e8daef', '#ff0000'])
cfg = Config(is_yed=is_yed, colors=colors)
gml.save_graphml(output, cfg)
if __name__ == '__main__':
os.makedirs('output-combine-gml', exist_ok=True)
for name in sorted(os.listdir('output-combine')):
name = name.removesuffix('.pkl')
tag = name.split('_')[0] if '_' in name else name
to_graphml(tag, f'output-combine/{name}.pkl', f'output-combine-gml/{name}.graphml', False)
to_graphml(tag, f'output-combine/{name}.pkl', f'output-combine-gml/{name}-yed.graphml', True)