Algorithm 在直方图上分布值的快速算法?

Algorithm 在直方图上分布值的快速算法?,algorithm,performance,time-complexity,Algorithm,Performance,Time Complexity,我正在寻找一种快速算法(从复杂性(问题的大小可能接近2^32)和常数两方面来看),它不一定要计算最优解(因此,如果启发式算法产生的结果“接近”最优,并且具有“相当大”的解度,那么启发式算法是可以接受的与计算特定问题的最优解相比,在计算时间方面具有优势 我有一个整数直方图A:| A |=n,A[I]>0;值R:0将柱状图转换为(值、索引)对的数组,然后将其转换为。此操作是O(n) 现在,您的C将把一些值设置为0,将一些值减少到最大值,将其余值减少到最大值的1。您希望减少所有内容的最大金额很容易计算

我正在寻找一种快速算法(从复杂性(问题的大小可能接近2^32)和常数两方面来看),它不一定要计算最优解(因此,如果启发式算法产生的结果“接近”最优,并且具有“相当大”的解度,那么启发式算法是可以接受的与计算特定问题的最优解相比,在计算时间方面具有优势


我有一个整数直方图A:
| A |=n,A[I]>0
;值R:
0将柱状图转换为
(值、索引)
对的数组,然后将其转换为。此操作是
O(n)

现在,您的
C
将把一些值设置为
0
,将一些值减少到最大值,将其余值减少到最大值的1。您希望减少所有内容的最大金额很容易计算,它是向上取整的
R/n

现在检查一下堆。只要堆底部的值是
,该索引处的该值将设置为零,并在时间
O(log(n))
中将其从堆中移除。循环完成后,可以将最大值和小于最大值的1随机分配给其余值


这将在
O(n log(n))
最坏时间运行。当
O(n)
元素必须归零时,您将遇到最坏的情况。

我在O(n*log(n))时间内想出了一个非常简单的贪婪算法(如果有人能在O(n)时间内解决它,尽管我很高兴听到)

算法:

  • 给定:整数数组:
    A[0],…,A[|A |-1]:A[i]>=0
    ;整数:
    R0:00)A[|A |-1]=R;返回A

  • 非正式解决方案最佳性证明:

    n=|A |

    案例0:
    n==1->C[0]=R

    案例1:
    n>1&&A[i]>=q&&A[j]>=q+1代表j>=max(0,n-r)

    对于i=n-r
    ,最优解由
    C[i]=q给出。
    假设有另一个由
    C'[i]=C[i]+E[i]
    给出的最优解,其中
    E
    的约束为:
    E[0]+…+E[m-1]=0
    (否则
    C'
    将违反
    C'[0]+…+C'[n-1]=R
    C[i]>=-E[i]
    (否则
    C'[i]
    将违反非负性约束),
    E[i]=0

    最后一个不等式是正确的,因为对于每个项
    2*E[n-i],1=q-1
    。假设没有这样的
    i
    ,那么
    C'[k]==C[n-1]
    ,和
    C'[0]+…+C'[n-1]q&&C[j-1]2*(1-1)=0
    。最后一个不等式来自
    (C'[i]L_2'
    ,如果我们增加
    C[i]:C[i]=i
    ,这意味着
    A[i]如果你告诉我们你需要它做什么,我们中的一些人可能会理解你想要实现什么?你想解决什么更大的问题?我有一个双精度直方图,需要映射到定点整数。定点整数直方图的值应该是
    (a[0]+…+a[n])/n
    正好等于平均值(这也是从double转换而来的,这就是我的R来自R=| sum-n*mean |)。为了在从整数表示法转换回直方图时最小化L2和max错误,最好“很好地”分布R在柱状图上。谢谢你的快速回答。我一定会调查这件事。你知道这件事在实践中的表现吗n@lightxbulb我想你会在内存访问上大吃一惊。如果直方图有那么多条目,它有多少不同的值?我不确定,这取决于所使用的数据,但最重要的是east我可以保证条目的上界是2^32。目前我只是使用O(n^2)算法进行固定数量的迭代,然后我只是转储R的剩余部分,而没有适当地分配它。不过我更希望得到最佳解决方案,O(n*log(n))听起来不错,但这实际上取决于这些操作的常量。我必须以任何一种方式访问内存,因此无法回避这一点。如果可以并行实现,这可能是值得的。@lightxbulb排序可以并行化。堆位不能。但希望堆位在您的数据中相对较少。我把它四舍五入,因为一旦所有的东西都是那个尺寸,其余的就可以随机分配。如果我有太多的东西被四舍五入,我需要取更多的剩余。一个潜在的优化是形成一个直方图,显示不同值形成的频率(可能与实际值相关联)。这可以与map reduce并行化。然后对其进行排序。这也可以并行化。现在遍历结果数组并做出决策的速度非常快。现在最好的情况是
    O(n log(n))
    ,但大多数情况下并行性非常好。
    if(A[i]>=d) 
    { 
        R-=d; 
        A[i]-=d; 
    }
    else 
    { 
        R-=A[i]; 
        A[i] = 0; 
        n = |A|-(i+1); 
        q = floor(R/n);
        d = q;
        r = R - q*n; 
    }