我正在寻找一种快速方法来对81个数字进行部分排序 - 理想情况下,我希望提取最低的16个值(16这个值不是绝对正确的顺序)。
目标是FPGA中的专用硬件 - 所以这有点复杂,因为我希望最终实现的区域尽可能小。我查看并实现了奇偶合并排序算法,但我理想地寻找可能对我的需求更有效的任何东西(交易算法实现大小为部分排序给出最低16,不一定按顺序而不是a完全排序)
非常欢迎任何建议
非常感谢
答案 0 :(得分:8)
这可以在O(nlog_k)
时间内完成,在你的情况下,n = 81和k = 16.当处理大量元素而不是O(nlog_n)
时,这非常有效。
算法如下:
n
与堆中的max进行比较(如果大于最大值则跳过,如果小于最大值,则删除max
并添加n
。)< / LI>
这种方式在每次迭代时都会跟踪当前处理过的部分列表中最小的k个数字。
答案 1 :(得分:2)
这听起来像某种信号处理内核。如果不知道设计中的确切数据流,很难帮助解决这个问题。任何涉及排序的算法都有地址解码成本,因为您需要能够写入和读取81个元素的内存。如果这些数据在存储器中,则已经支付了这笔费用,但是如果它在不同的寄存器中,那么写入它们会带来面积成本。
假设数据在内存中,您可以使用冒泡排序并获取底部16个值。下面的代码假定一个双端口存储器,但它可以通过在每个时钟周期交替读写来使用单个端口,使用临时寄存器来存储写入值和写入索引。在内存中只有81个元素,这可能没有更大的区域效率。 或者,源存储器可以实现为两个单端口存储器,其中一个具有奇数索引而另一个具有偶数索引。
// Not working code
reg [15:0] inData [80:0]; // Must be two-port
reg [3:0] iterCount = 0;
reg [6:0] index = 0;
reg sorting;
always @(posedge clk)
begin
// Some condition to control execution
if(sorting)
begin
if(index == 80)
begin
// Stop after 16 iterations
if(iterCount == 15)
begin
sorting <= 0;
iterCount <= 0;
end
else
begin
iterCount <= iterCount+1;
index <= 0;
end
end
else
begin
// If this is smaller than next item
if(inData[index] < inData[index+1])
begin
// Swap with next item
inData[index+1] <= inData[index];
inData[index] <= inData[index+1];
end
index <= index + 1;
end
end
end
编辑:如果您受到延迟限制,只允许一个时钟域并且必须进行管道传输,那么问题仅限于选择排序网络并将其映射到管道。您无法使用资源共享,因此根据您的分拣网络,区域是固定的。
答案 2 :(得分:1)
如果您正在寻找通用算法,那么您可以使用Quicksort版本。 Quicksort对pivot元素周围的值进行排序。您选择一个轴并对阵列进行排序。然后你得到x值&lt;枢轴和(n-x-1)个较大的。根据x,您可以选择一个阵列来继续处理。如果x> 16,那么您知道您要查找的数字都在x数组中,您可以继续对其进行排序。如果没有,那么你知道x最低,现在可以递归地在另一个数组中寻找16-x其他。
答案 3 :(得分:0)
也许修改中位数选择是一种选择?否则,你只需寻找最少16次就可行吗?
答案 4 :(得分:0)
首先设置一个包含16个值的数组。并使用类似选择的东西: