【问题标题】:Trying to generate a random graph, and then generate another one until it is isomorphic with the first one尝试生成一个随机图,然后生成另一个,直到它与第一个同构
【发布时间】:2018-09-17 23:43:54
【问题描述】:

我是 python 新手,正在尝试编写一个程序,它可以将 1 和 0 的矩阵作为输入,从中创建一个图,然后继续生成另一个随机图,直到找到同构对。

我不断地弄乱我的逻辑,不断地陷入无限循环或无法完成我想要完成的事情的循环。任何帮助将不胜感激。

这是我的程序中存在问题的部分

i = 0
for i in range(counterP):
    g4 = numpy.reshape(numpy.random.random_integers(0, 1, size=matrix_sizeP), (vertex_countP, vertex_countP))
    g5 = numpy.reshape(numpy.random.random_integers(0, 1, size=matrix_sizeP), (vertex_countP, vertex_countP))
    G4 = nx.Graph(g4)
    G5 = nx.Graph(g5)
    G4G5 = iso.GraphMatcher(G4,G5)
    isomP = G4G5.is_isomorphic()

    if isomP is True:
        ed = nx.number_of_edges(G4)
        print("Iteration", i, ":", ed, "edges")
        print(G4G5.mapping)
        i = i + 1
    else:
        g5 = numpy.reshape(numpy.random.random_integers(0, 1, size=matrix_sizeP), (vertex_countP, vertex_countP))
        G5 = nx.Graph(g5)
        isomP = G4G5.is_isomorphic()

【问题讨论】:

  • 你为什么要这么做?这似乎是一种极其低效的方法来解决我能想象到的任何问题。
  • 最终结果将是一个随机同构图。通过随机排列顶点来生成随机同构图要容易得多。
  • 你有任何链接到一个好的来源吗?对所有这些都是新的
  • 我正在协助我大学的教授进行图论研究,这是他们分配给我的任务
  • 也许他们最终对 graphmatcher 感兴趣,而他们要求您编写的循环是为了作为一个测试框架?

标签: python-3.x numpy graph networkx isomorphic


【解决方案1】:

你的程序逻辑确实有点不对劲。这是我理解你想要的版本:

import numpy as np
import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher

def brute_force_find_iso_pair(shape, maxiter, template=None):
    def make_random_graph():
        return nx.Graph(np.random.random_integers(0, 1, shape))
    G4 = make_random_graph() if template is None else template
    def check_iso(G5):
        return GraphMatcher(G4, G5).is_isomorphic()
    for n in range(maxiter):
        G5 = make_random_graph()
        if check_iso(G5):
            break
    else:
        G5 = None
    return G4, G5, n + 1

# example
G4, G5, n = brute_force_find_iso_pair((4, 4), 50)
print(f"""After {n} iterations:
template: {G4.adj}
match:    {G5 and G5.adj}
""")

示例运行:

After 43 iterations:
template: {0: {1: {'weight': 1}, 3: {'weight': 1}, 2: {'weight': 1}}, 1: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 2: {1: {'weight': 1}, 0: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 3: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}}}
match:    {0: {2: {'weight': 1}, 1: {'weight': 1}, 3: {'weight': 1}}, 1: {0: {'weight': 1}, 3: {'weight': 1}, 2: {'weight': 1}}, 2: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 3: {1: {'weight': 1}, 0: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}}

After 50 iterations:
template: {0: {1: {'weight': 1}, 2: {'weight': 1}}, 1: {0: {'weight': 1}, 3: {'weight': 1}, 2: {'weight': 1}}, 2: {0: {'weight': 1}, 1: {'weight': 1}, 3: {'weight': 1}}, 3: {1: {'weight': 1}, 2: {'weight': 1}}}
match:    None

After 25 iterations:
template: {0: {1: {'weight': 1}, 3: {'weight': 1}, 2: {'weight': 1}}, 1: {0: {'weight': 1}, 2: {'weight': 1}}, 2: {1: {'weight': 1}, 0: {'weight': 1}, 2: {'weight': 1}}, 3: {0: {'weight': 1}}}
match:    {0: {1: {'weight': 1}}, 1: {0: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 2: {1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 3: {1: {'weight': 1}, 2: {'weight': 1}}}

After 2 iterations:
template: {0: {0: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 1: {2: {'weight': 1}, 3: {'weight': 1}}, 2: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 3: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}}}
match:    {0: {2: {'weight': 1}, 3: {'weight': 1}}, 1: {1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 2: {0: {'weight': 1}, 1: {'weight': 1}, 3: {'weight': 1}}, 3: {0: {'weight': 1}, 1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}}

After 32 iterations:
template: {0: {2: {'weight': 1}, 3: {'weight': 1}}, 1: {2: {'weight': 1}, 3: {'weight': 1}}, 2: {1: {'weight': 1}, 0: {'weight': 1}, 3: {'weight': 1}}, 3: {1: {'weight': 1}, 2: {'weight': 1}, 0: {'weight': 1}}}
match:    {0: {1: {'weight': 1}, 2: {'weight': 1}, 3: {'weight': 1}}, 1: {0: {'weight': 1}, 2: {'weight': 1}}, 2: {0: {'weight': 1}, 1: {'weight': 1}, 3: {'weight': 1}}, 3: {0: {'weight': 1}, 2: {'weight': 1}}}

【讨论】:

  • 哇,这真是太棒了,这正是我正在寻找的东西,在这样做的过程中,你还教了我一些关于如何在 python 中定义函数的知识,以及更多关于这些循环背后的逻辑。真的,谢谢你,非常感谢!
  • 您介意解释一下输出吗?我假设它是一个映射,我只是无法准确地遵循它。谢谢
  • @Jrubinstein 是的,它是一个嵌套的类字典映射,表示图形。每个顶点都映射到从它的每个邻居到从连接边的属性到它们的值的映射。见here
猜你喜欢
  • 1970-01-01
  • 2022-11-21
  • 2013-05-20
  • 2022-10-18
  • 2018-04-21
  • 2021-12-02
  • 2023-01-03
  • 1970-01-01
  • 2011-12-16
相关资源
最近更新 更多