C++ 基于Boost图库的二部图组合子图的高效迭代

C++ 基于Boost图库的二部图组合子图的高效迭代,c++,algorithm,boost,graph,combinatorics,C++,Algorithm,Boost,Graph,Combinatorics,基本问题: 我有一个概率矩阵,其中行是“蓝色”,列是“红色”。矩阵通常非常稀疏,但我们无法保证其稀疏性。我正在对这个由概率and和OR组成的矩阵进行概率分析;基本上我需要做每一个组合的蓝调,每一个“N选择K”组合的红色。我决定尝试使用一个图来实现这一点,特别是使用Boost图的二部图。仅当值大于0时才插入边 例如: 矩阵: Red Blue 0.01 0.04 0.07 0.02 0.05 0.08 0.03 0.06

基本问题:

我有一个概率矩阵,其中行是“蓝色”,列是“红色”。矩阵通常非常稀疏,但我们无法保证其稀疏性。我正在对这个由概率and和OR组成的矩阵进行概率分析;基本上我需要做每一个组合的蓝调,每一个“N选择K”组合的红色。我决定尝试使用一个图来实现这一点,特别是使用Boost图的二部图。仅当值大于0时才插入边

例如:

矩阵:

        Red
Blue   0.01    0.04    0.07
       0.02    0.05    0.08
       0.03    0.06    0.09
图:具有3个红色和3个蓝色顶点的二分图

R1 --> B1 (edge weight 0.01)
R2 --> B1 (edge weight 0.04)
R3 --> B1 (edge weight 0.07)
...
继续解释

我通过将顶点ID存储在向量中来跟踪红色顶点和蓝色顶点。我通过基于N选择K(使用“布尔向量置换”方法)将红色顶点标记为黑色或白色来生成组合。然后,我使用递归遍历每个蓝色边的组合,以获得每个有效的Bx->Ry边组合

每个蓝色(或者更准确地说,每个连接到“白色”红色顶点的蓝色)都有一条边。这使得对蓝调进行分析变得容易得多;通过这样做,我使用递归并简单地在每一条边上使用for循环,蓝色必须生成所有有效的B->R组合的有效集合

对于上述示例:

对于3,选择红色的2:

第一次迭代:
白色:R1,R2黑色:R3

生成前往R1或R2的所有有效B组合,其中R1和R2在组合集中的每个组合中至少表示一次

第二次迭代:
白色:R1,R3黑色:R2

生成前往R1或R3的所有有效B组合,其中R1和R3在组合集合中的每个组合中至少表示一次

第三次迭代:
白色:R2,R3黑色:R1

生成通向R2或R3的所有有效B组合,其中R2和R3在组合集中的每个组合中至少表示一次

为第一次迭代设置:
{{B1R1,B2R1,B3R2},{B1R1,B2R2,B3R2},…}

(每个列必须至少有一条边,因此
{B1R1,B2R1,B3R1}
不是有效的组合;此外,该组合中只能包含给定蓝色顶点的一条边,因此
{B1R1B1R2…}
也无效。)

问题是:

现在,我通过在蓝色上递归时检查边的目标来过滤掉“黑色”红色顶点(不在边上运行概率计算)。虽然这工作得很好,但效率很低,常常导致无法接受的运行时间。对于非常稀疏的矩阵,这会在大量节点和边上浪费O(N!)时间。对于较小或非常稀疏的矩阵,这不是问题。但对于大型“不够稀疏”矩阵,运行时会爆炸。“良好”运行时间通常在100ms左右,通常接近10ms;“坏”可能需要几个小时(一次跑步需要八个多小时,但没有完成)。实际上,我正在对蓝色进行DFS,并删除任何包含无效(“黑色”红色)顶点的组合

问题是:

希望我对这个问题已经足够清楚了

我只能找到两种可能的解决方案来提高效率,但我希望读者有另一种想法:

1) 生成组合子图并使用当前方法迭代这些子图。示例:对于上面的“第一次迭代”,复制图形并删除所有转到R3的边。然后,根据定义,递归中的所有边都是“有用”边

2) 找出一种方法,通过迭代红色来生成相同的组合(根据定义,所有进入“白色”红色顶点的边都是有效的)

我对过滤图工作方式的理解是,它们基本上会做与我现在做的相同的事情(过滤“动态”而不是预过滤),因此它实际上不会改善我的时间

有什么想法吗

更新:


选项1比我想象的要好;我能够在不到两秒钟的时间内让一个100 x 100的矩阵工作。但仍在寻找是否有人对选项2有想法。

我认为有些人可能倾向于查看您的实际代码。这听起来像是一项调整自定义图形容器的工作(可能基于(一些)实际边的boost侵入式视图?)。不幸的是,代码太大,无法在这里发布。即使只是相关的片段。。。