我有一个圆圈集合,每个圆圈可能会也可能不会与集合中的一个或多个其他圆圈相交。我想将这些圈子分组,以便每个"组"包含所有圆圈,使得该组的每个成员与该组的至少一个其他成员相交,并且使得任何组的任何成员都不与任何其他组的任何成员相交。我已经提出了以下VB.NET /pseudocode算法来解决单个线程上的这个问题:
Dim groups As New List(Of List(Of Circle))
For Each circleToClassify In allCircles
Dim added As Boolean
For Each group In groups
For Each circle In group
If circleToClassify.Intersects(circle) Then
group.Add(circleToClassify)
added = True
Exit For
End If
Next
If added Then
Exit For
End If
Next
If Not added Then
Dim newGroup As New List(Of Circle)
newGroup.Add(circleToClassify)
groups.Add(newGroup)
End If
Next
Return groups
或者用英语
我希望能够做的是使用任意数量的线程来执行此任务。然而,我并没有像我所有的解决方案那样做得很远到目前为止,由于锁定而最终会以串行方式执行。
任何人都可以提供关于我想要实现这种多线程的想法吗?
答案 0 :(得分:1)
一种方法是将图像划分为块,在不同的线程上独立运行每个块的算法(即仅考虑其中心位于该块中的圆圈),然后加入组来自具有交叉圆的不同块。
另一种方法是使用图形来表示问题,其中节点表示圆,并且如果相应的圆相交,则在两个节点之间存在边。我们需要找到此图表的connected components。这忽略了问题的几何方面,但是,有一些通用的算法可能是有用的(例如你可以考虑this link的最后一张幻灯片。)
答案 1 :(得分:1)
在进行多线程开发时,一等奖是以最小化锁定数量的方式实现线程。在最简单的情况下:如果他们不共享任何数据,他们根本不需要锁。但是,如果您可以保证在线程运行时不会修改共享数据 :那么在这种情况下您也不需要锁。
在您的问题中,您无需修改您的圆圈输入列表。您遇到的问题是您正在构建共享圈组列表。基本上,您正在共享结果空间并需要锁定以确保结果的完整性。
这种情况下的一种技术是“分区和合并”。作为一个简单的例子,考虑找到一大堆数字的最大值。天真(和理想的单线程解决方案)是:
多线程的问题发生在更新共享结果时。一种解决方案是:
p
个线程分区列表; p
分区最大值的最大值,可以轻而易举地获得最终结果。对单线程解决方案的权衡涉及权衡分配工作负载的难易程度和每线程结果的合并与通常更简单的单线程方法相比。
作为旁注:注意你的问题本质上是一个图论问题,这样:每个圆都是一个节点;如果任何2个圆相交,则它们之间存在无向边;并且您正在尝试确定图表的连接组件 显然,这提供了一个可以研究更多想法/信息的领域。但更重要的是,通过简单的布尔评估2个圆是否相交,可以更容易地分析问题 还要注意通过首先将您的圈子预处理为合适的图表结构来改善潜在的效果。
假设您有8个圆圈(A-H),下表中的1表示2个圆相交。
ABCDEFGH A11000110 B11000000 C00100000 D00010101 E00001110 F10011100 G10001010 H00010001
一个分区的想法是通过仅考虑圆圈的子集及其所有直接连接来确定连接的内容。
ABCDEFGH A11000110 p1 [AB] B11000000 --------- C00100000 p2 [CD] D00010101 --------- E00001110 p3 [EF] F10011100 --------- G10001010 p4 [GH] H00010001
NB 即使线程正在共享数据(例如,2个线程可能同时考虑圆圈A和F之间的交集),该共享是只读的,不需要锁定。
假设[AB][CD][EF][GH]
的4个分区(和4个线程)。每个分区的连接组件将按如下方式细分:
[AB]: ABFG [CD]: C DFH [EF]: ADEFG [GH]: AEG DH
您现在有一个可能重叠的连接组件列表。合并涉及迭代列表以查找重叠。如果找到,则取2联的组合是一个新的连接组件。这将最终产生:ABFGDHE和C
需要考虑的一些优化技术:
Connected(A) = ABFG Connected(B) = B Connected(AB) = ABFG Connected(C) = C Connected(D) = DFH Connected(CD) = C,DFH Connected(ABCD) = ABFGDH,C Connected(E) = EFG Connected(F) = F Connected(EF) = EFG Connected(G) = G Connected(H) = H Connected(GH) = G,H Connected(EFGH) = EFG,H Connected(ABCDEFGH) = ABFGDHE,C
非常NB 您需要确保选择适当的数据结构和算法,否则会遇到极差的性能。例如。一个天真的交集实现可能需要O(n ^ 2)个操作来确定两个中间连接的组件是否相交并完全破坏你的目标,从而导致所有这些额外的复杂性。