Algorithm 最优化问题-寻找最大值

Algorithm 最优化问题-寻找最大值,algorithm,optimization,discrete-mathematics,Algorithm,Optimization,Discrete Mathematics,我手头有个问题,可以归结为这样的问题: 假设二维平面X-Y中有一组随机点,其中每个Y上可能有多个点,每个X上可能有多个点 无论何时选择一个点(席,Yi),都不需要选择x=席或y=易的其他点。我们必须选择最大点数。这不是唯一的选择吗 创建一个n×n矩阵,0位于标记的顶点,1位于未标记的顶点。该算法将选择n个顶点,每行和每列一个,这将最小化它们的总和。只需计算所有选择的等于0的顶点,就可以得到答案 from munkres import Munkres matrix = [[0, 0, 1],

我手头有个问题,可以归结为这样的问题:

假设二维平面X-Y中有一组随机点,其中每个Y上可能有多个点,每个X上可能有多个点

无论何时选择一个点(席,Yi),都不需要选择x=席或y=易的其他点。我们必须选择最大点数。

这不是唯一的选择吗

创建一个n×n矩阵,0位于标记的顶点,1位于未标记的顶点。该算法将选择n个顶点,每行和每列一个,这将最小化它们的总和。只需计算所有选择的等于0的顶点,就可以得到答案

from munkres import Munkres

matrix = [[0, 0, 1],
          [0, 1, 1],
          [1, 0, 0]]

m = Munkres()
total = 0
for row, column in m.compute(matrix):
    if matrix[row][column] == 0:
        print '(%i, %i)' % (row, column)
        total += 1

print 'Total: %i' % total

它以O(n3)时间运行,其中n是矩阵中的行数。最大流解决方案在O(V3)中运行,其中V是顶点数。只要选择的交叉口超过n个,速度就会更快;事实上,随着所选顶点数量的增加,它的运行速度会加快几个数量级。

对于每个点,确定因选择该点而不合格的其他点(N)的数量(即具有相同X或Y值的点)。然后,按N个不合格点数的增加顺序迭代非不合格点数。完成后,您将删除最大点数。

这可以简化为简单的最大流量问题。如果你有一个点(席,彝),在图中它应该用从源S到点席的路径表示,从席到彝,从彝到最后一个节点(汇)T.< 注意,如果我们有点(2,2)和(2,5),从s到x2仍然只有一条路径。所有路径(边)的容量为1

这个网络中的流量就是答案

关于一般问题

更新
我现在并没有图形编辑器来可视化这个问题,但你们可以很容易地用手画出例子。比如说,点是(3,3)(3,5)(2,5)

那么边(路径)将是
S->x2,S->x3
y3->T,y5->T
x3->y3,x3->y5,x2->y5

流程:S->x2->y5->T和S->x3->y3->T
从源到汇的“水”量是2,答案也是如此

还有一个关于最大流量算法的教程

这似乎是一个可以用计算机解决的问题。查看最长公共子串的算法,或者。XY平面是一条红鲱鱼。将其表述为一组元素,每个元素都有一组相互排斥的元素

然后,该算法变为深度优先搜索。在每个级别,对于每个候选节点,计算排除的元素集,即当前排除的元素与候选节点排除的元素的并集。按排除元素最少到最多的顺序尝试候选节点。跟踪到目前为止最好的解决方案(排除的节点最少)。修剪比当前最佳值更差的任何子树


作为以可能遗漏的解决方案为代价的轻微改进,您可以使用Bloom过滤器跟踪排除的集合。

不同的解决方案。事实证明,这里有很多对称性,答案比我最初想象的要简单得多。你能做的最多的事情是唯一的X和唯一的Y中的最小值,如果你只想得到结果的话,这就是O(NlogN)

每一个其他形状都相当于一个包含点的矩形,因为从矩形中心拉取多少点并不重要,顺序也不重要(如果按以下方式处理)从现在开始拾取点的任何形状都有一个不唯一的X和一个不唯一的Y,就像矩形一样

所以最优解与连通性无关。选择最小尺寸边缘上的任何点(即,如果len(唯一Xs)>len(唯一Ys),则选择具有最大或最小X的任何点)。不管它有多少个连接,哪一个维度是最大的,这都可以在查看上面创建的排序的唯一列表时轻松完成。如果保留一个unique-x和unique-y计数器,并在删除列表中该元素中的所有唯一节点时将其递减,则每次删除为O(1),重新计算长度为O(1)。因此,重复这N次最坏是O(N),最终的复杂度是O(NlogN)(完全由于排序)

您可以沿最短边拾取任何点,因为:

  • 如果这条边上只有一条,你最好现在就把它挑出来,否则其他东西会把它消除
  • 如果有一个以上的边缘,谁在乎,你会消除所有与你的选择无论如何
基本上,您在每个点上都最大化了“max(uniqX,uniqY)”

更新:捕获到边缘案例:

如果尺寸相等,则取点最少的边。即使它们不相等,也要从点数最少的唯一堆栈中选取顶部或底部

例如:

第1轮:

  • 要点:
    (1,2);(3, 5); (10, 5); (10, 2); (10,3)
  • 有3个唯一的X:
    1、3、10
  • 有3个唯一的Y:
    2、3、5
  • “边界框”是
    (1,5)、(10,5)、(10,2)、(1,2)
反应1:

  • 点最少的“外边缘”(最外面的唯一点或唯一点列表)位于左侧。基本上,看看x=1,x=10和y=2,y=5中的点集。x=1的集合是最小的:一个点。选择x=1的唯一点->
    (1,2)
  • 这也消除了
    (10,2)
第二轮:

  • 要点:
    (3,5);(10, 5); (10,3)
  • 有两个唯一的X:
    3,10
  • 有两个唯一的Y:
    3,5
  • “边界框”是
    (3,5)、(10,5)、(10,3)、(3,3)
反应2:

  • 具有以下属性的边界框的“边”
    points = {
        0 : [0, 1],
        1 : [0],
        2 : [1, 2],
    }
    
    selected = bipartiteMatch(points)[0]
    
    for x, y in selected.iteritems():
        print '(%i, %i)' % (x, y)
    
    print 'Total: %i' % len(selected)