【发布时间】:2013-03-27 00:08:55
【问题描述】:
我需要比较许多图表(最多几百万个图表比较),我想知道最快的方法是什么。
图的顶点最多可以有 8 个邻居/边,并且顶点的值可以是 0 或 1。旋转图仍然是同一个图,每个图都有相同数量的顶点。
图表可能如下所示:
现在我通过从第一个图中获取一个顶点并将其与第二个图中的每个顶点进行比较来比较图。如果找到相同的顶点,则检查两个顶点的邻居是否相同,然后重复此操作,直到知道图形是否相同为止。
这种方法太慢了。在不丢弃肯定不同的图的情况下,比较几千个图和大约一百个顶点需要 40 多秒。
我正在考虑计算每个图表的唯一值,然后只比较值。我试图这样做,但我只设法提出如果相等则图形可能相等的值,如果值不同则图形也不同。
如果我的程序比较这些值,那么它会在大约 2.5 秒内计算所有内容(这仍然太慢)。
向该图添加顶点并更新边的最佳/最快方法是什么?现在我将此图存储在 std::map< COORD, Vertex > 中,因为我认为这样搜索顶点更容易/更快。
COORD 是游戏板上的顶点位置(顶点位置与比较图无关),顶点是:
struct Vertex
{
Player player; // Player is enum, FIRST = 0, SECOND = 1
Vertex* neighbours[8];
};
此图表示 Gomoku 的当前棋盘状态,在棋盘边缘环绕,棋盘大小为 n*n,其中 n 最大为 2^16。
我希望我在写这篇文章时没有犯太多错误。我希望有人可以帮助我。
【问题讨论】:
-
我无法证明这一点,但我认为可能有一种方法可以创建图形的标准化表示。然后,您需要一个将图形映射到其规范化形式的转换函数。证明所有等效图具有相同的归一化形式,然后您可以将问题简化为两次转换和一次比较。
-
要判断两个图是否相似,可以检查以下因素:顶点数,边数,入度和出度,欧拉环,欧拉路径..等
-
你的问题没有很好的定义。什么时候两张图“相同”?是不是它们同构为未标记的图?然后你试图解决图同构问题,它是 NP,但不知道是 P 或 NP-hard。有一个名为“nauty”的库为其实现标准算法。
-
另一条评论:为什么要将五子棋棋盘存储为如此复杂的结构而不是二维数组?可以使用模运算来实现板边缘的环绕。
-
只是一个建议。如果您愿意改用 boost 图形库,这对您来说可能会很有趣。 boost.org/doc/libs/1_39_0/libs/graph/doc/isomorphism.html
标签: c++ algorithm data-structures graph