проблема изоморфизма
есть 2 (стула, зачеркнуто) графа.
В общем случае они представлены матрицей смежности
0, 1, 1, 1, 0, 0,
1, 0, 1, 0, 1, 0,
1, 1, 0, 0, 0, 1,
1, 0, 0, 0, 1, 1,
0, 1, 0, 1, 0, 1,
0, 0, 1, 1, 1, 0,
или файлом в специальном формате, где указано количество вершин, количество ребер и перечислены связи между ребрами
p edge 16 76
e 1 3
e 1 4
e 1 6
e 1 8
e 1 9
...
по известным алгоритмам одно представление переходит в другое.
если в матрице смежности поменять местами 2 строки и 2 столбца с теми же индексами, то мы получим изоморфный граф.
задача состоит в том чтобы в первой матрице поменять строки и столбцы так чтоб она совпала со второй. если менять только первую матрицу а вторую не трогать то в общем случае это займет n факториал перестановок, что очень много.
сократим количество перебора.
преобразуем матрицу смежности в матрицу расстояний.
0, 1, 1, 1, 2, 2
1, 0, 1, 2, 1, 2
1, 1, 0, 2, 2, 1
1, 2, 2, 0, 1, 1
2, 1, 2, 1, 0, 1
2, 2, 1, 1, 1, 0
для каждой строки построим индекс, (это уже другой граф)
[0, 1, 2, 2, 2, 3, 3, 3, 3, '0', '|1-1-3-4'],
[1, 0, 1, 1, 1, 2, 2, 2, 2, '5', '|1-4-4-0'],
[2, 1, 0, 1, 2, 1, 2, 1, 1, '2', '|1-5-3-0'],
[2, 1, 1, 0, 2, 2, 1, 2, 2, '3', '|1-3-5-0'],
[2, 1, 2, 2, 0, 3, 3, 3, 3, '4', '|1-1-3-4'],
[3, 2, 1, 2, 3, 0, 3, 2, 2, '1', '|1-1-4-3'],
[3, 2, 2, 1, 3, 3, 0, 3, 3, '6', '|1-1-2-5'],
[3, 2, 1, 2, 3, 2, 3, 0, 2, '7', '|1-1-4-3'],
[3, 2, 1, 2, 3, 2, 3, 2, 0, '8', '|1-1-4-3']
здесь мы видим матрицу расстояний, передпоследний столбец - номер строки, чтобы знать какую вершину какой сопоставлять, последний столбец - индекс, каждая позиция это количество вершин которые можно достичь за указаное количество шагов.
если индекс уникален, то он, однозначно определяет вершину.
меняем строки и столбцы, чтоб уникальные вершины были сверху, потом перестраиваем индекс.
индекс состоит из 2-х частей, фиксированная и плавающая.
то что до слеша фиксированная, что после слеша, плавающая.
когда мы определили первые n строк, то в каждой строке первые n растояний не будут меняться никогда
и мы получаем следующий индекс
[0, 1, 2, 2, 3, 3, 3, 3, 3, '6', '|1-1-2-5'],
[1, 0, 1, 1, 2, 2, 2, 2, 2, '3', '|1-3-5-0'],
[2, 1, 0, 1, 1, 2, 1, 2, 2, '5', '|1-4-4-0'],
[2, 1, 1, 0, 2, 1, 2, 1, 1, '2', '|1-5-3-0'],
[3, 2, 1, 2, 0, 3, 2, 3, 3, '4', '3-2-1-2|1-0-1-3'],
[3, 2, 2, 1, 3, 0, 3, 2, 2, '1', '3-2-2-1|1-0-2-2'],
[3, 2, 1, 2, 2, 3, 0, 3, 3, '0', '3-2-1-2|1-0-1-3'],
[3, 2, 2, 1, 3, 2, 3, 0, 2, '7', '3-2-2-1|1-0-2-2'],
[3, 2, 2, 1, 3, 2, 3, 2, 0, '8', '3-2-2-1|1-0-2-2']
первые 4 вершины, это уникальные, для остальных построен индекс, который более однозначно определяет вершины
после сортировки у нас вершины делятся на 2 группы, в одной 2 вершины в друго 3.
Для планарных графов это вершины которые взаимо заменяемы(утверждение спорно, нужно или доказать или опровергнуть)
после каждой итерации смотрим совпадают ли индексы левой и правой матрицы, если совпадают, можно сортировать и переходить к следующей итерации, если не совпадают, то изоморфизм невозможен(утверждение верно для планарных графов, математического доказательства нет, утверждение никто в общем случае не проверял)
вначале мы имеем матрицы каждая из которых состоит из 2-х частей, неизменяемая и возможная, с каждым шагом неизменяемая часть увеличевается, возможная уменьшается(та что в индексе после вертекальной черты)
я назвал свой алгоритм метод зонной плавки
https://ru.wikipedia.org/wiki/Зонная_плавка Метод является разновидностью направленной кристаллизации, от которой отличается тем, что в каждый момент времени расплавленной является некоторая небольшая часть образца.
код лежит
здесьzone_melting.py - основной файл который находит или не находит решение, на вход пеердаются 2 матрицы смежности, в ответ решение или невозможность решения
также написаны 2 обертки
iso_solver_graphml.py
iso_solver.py
первая для графов постороеных в
http://graphonline.ru (граф->экспорторовать грф)
нарисуйте 2 предположительно изоморфных графа,
запустите
python iso_solver_graphml.py -i palm2.graphml
в ответ увидете
matrix size:9 iteration:6
и файл, out.graphml, который импортировав в
http://graphonline.ru можно увидеть над вершинами индексы которые можно сопоставить и убедиться в изоморфности
второй файл для файлов в формате
p edge 16 76
e 1 3
e 1 4
e 1 6
e 1 8
e 1 9
...
python iso_solver.py -i1 cfi-rigid-t2-0016-04-1 -i2 cfi-rigid-t2-0016-04-2
для каждого файла есть справка
python iso_solver.py -h
usage: iso_solver.py [-h] -i1 I1 -i2 I2 [-o O]
optional arguments:
-h, --help show this help message and exit
-i1 I1 first file
-i2 I2 second file
-o O output file