Algorithm &引用;“稳定”;k-最大元素算法

Algorithm &引用;“稳定”;k-最大元素算法,algorithm,sorting,selection,Algorithm,Sorting,Selection,相关的: 我正在寻找一种算法,该算法从列表中返回k个最大元素,但不改变k个最大元素的顺序,例如,对于k=4,给定5,9,1,3,7,2,8,4,6,该算法应返回9,7,8,6 更多背景信息,我的输入数据约为200对(距离,重要性),按w.r.t距离排序,我需要选择其中最重要的32对。性能在这里至关重要,因为我必须运行这个选择算法几千次 到目前为止,我有以下两个想法,但它们似乎都不是最好的 迭代删除最小元素,直到剩下32个元素(即进行选择排序) 使用quickselect或中值搜索第32大元素。

相关的:


我正在寻找一种算法,该算法从列表中返回k个最大元素,但不改变k个最大元素的顺序,例如,对于
k=4
,给定
5,9,1,3,7,2,8,4,6
,该算法应返回
9,7,8,6

更多背景信息,我的输入数据约为200对
(距离,重要性)
,按w.r.t
距离排序,我需要选择其中最重要的32对。性能在这里至关重要,因为我必须运行这个选择算法几千次

到目前为止,我有以下两个想法,但它们似乎都不是最好的

  • 迭代删除最小元素,直到剩下32个元素(即进行选择排序)
  • 使用quickselect或中值搜索第32大元素。然后,按w.r.t.距离再次对其余31个元素进行排序

  • 我需要在C++中实现这一点,所以如果有人想编写一些代码,不知道使用哪种语言,C++是一个选项。

    < P>使用基于堆的算法来求K最大值,即使用一个不超过K的大小的<强> min <强>堆(不是最大堆)。一旦它超过了这个大小,就继续从中拔出根来将它恢复到k的大小

    最后,堆的根将是k最大值。我们叫它m

    然后可以再次扫描原始输入,以收集至少等于m的所有值。这样你就可以按照原来的顺序来做了

    如果m不是唯一的,则可能收集了太多的值。因此,检查结果的大小并确定它比k长多少。向后浏览该列表,并将值为m的列表标记为已删除,直到达到正确的大小。最后收集未删除的项目


    所有这些扫描都是O(n)。最昂贵的步骤是第一步:O(nlogk)。

    使用基于堆的算法来查找k个最大值,即使用从不超过k的min堆(而不是最大堆)。一旦它超过了这个大小,就继续从中拔出根来将它恢复到k的大小

    最后,堆的根将是k最大值。我们叫它m

    然后可以再次扫描原始输入,以收集至少等于m的所有值。这样你就可以按照原来的顺序来做了

    如果m不是唯一的,则可能收集了太多的值。因此,检查结果的大小并确定它比k长多少。向后浏览该列表,并将值为m的列表标记为已删除,直到达到正确的大小。最后收集未删除的项目


    所有这些扫描都是O(n)。最昂贵的步骤是第一步:O(nlogk)。

    @trincot解决方案的启发,我提出了一个与工作实现略有不同的变化

    算法

    >P>使用弗洛依德的算法建立最大堆,或者在C++中使用与构造函数<强> > PrimyItQueIs/Stult>相同的构造函数,我们可以同时传递整个数组/向量,而不是单独添加元素。如果内置O(N)时间复杂度,则最大堆

  • 现在,从最大堆中弹出项目K-1次,直到我们得到第K个最大重要性项目。将第k个最大重要性项的值存储在变量
    Kth\u Max\u Importance\u Item

  • 扫描原始输入中重要性值大于第k个最大重要性项重要性值的所有节点,并将其推入输出向量

  • 通过从
    k
    中减去输出向量的当前大小,计算重要性值等于
    Kth_Max_importance_Item
    重要性值的必需项的剩余计数。将其存储在变量
    left\u Over\u Count

  • 扫描原始输入中重要性值等于第k个最大重要性项的重要性值的项目数,并将其推入输出向量

  • 注意:如果
    重要性
    值不是唯一的,则该条件由算法的步骤34处理


    时间复杂度:O(N+K*log(N))。假设K受到@trincot解决方案的启发,我在工作实现方面提出了一个稍微不同的变化

    算法

    >P>使用弗洛依德的算法建立最大堆,或者在C++中使用与构造函数<强> > PrimyItQueIs/Stult>相同的构造函数,我们可以同时传递整个数组/向量,而不是单独添加元素。如果内置O(N)时间复杂度,则最大堆

  • 现在,从最大堆中弹出项目K-1次,直到我们得到第K个最大重要性项目。将第k个最大重要性项的值存储在变量
    Kth\u Max\u Importance\u Item

  • 扫描原始输入中重要性值大于第k个最大重要性项重要性值的所有节点,并将其推入输出向量

  • 通过从
    k
    中减去输出向量的当前大小,计算重要性值等于
    Kth_Max_importance_Item
    重要性值的必需项的剩余计数。将其存储在变量
    left\u Over\u Count

  • 扫描原始输入中重要性值等于第k个最大重要性项的重要性值的项目数,并将其推入输出向量

  • 注意:如果
    重要性
    值不是唯一的,则该情况由步骤3和处理#include <iostream> #include <vector> #include <queue> #include <math.h> typedef struct Item{ int distance; double importance; }Item; struct itemsCompare{ bool operator() (const Item& item1, const Item& item2){ return ((item1.importance < item2.importance) ? true : false); } }; bool compareDouble(const double& a, const double& b){ return (fabs(a-b) < 0.000001) ? true : false; } int main(){ //Original input std::vector<Item> items{{10, 2.1}, {9, 2.3}, {8, 2.2}, {7, 2.2}, {6, 1.5}}; int k = 4; //Min Heap std::priority_queue<Item, std::vector<Item>, itemsCompare> maxHeap (items.begin(), items.end()); //Checking if the order of original input is intact /*for(int i=0;i<items.size();i++){ std::cout<<items[i].distance<<" "<<items[i].importance<<std::endl; }*/ //Pulling the nodes until we get Kth Max Importance Node int count = 0; while(!maxHeap.empty()){ if(count == k-1){ break; } maxHeap.pop(); count++; } Item Kth_Max_Importance_Item = maxHeap.top(); //std::cout<<Kth_Max_Importance_Item.importance<<std::endl; //Scanning all the nodes from original input whose importance value is greater than the importance value of Kth_Max_Importance_Item. std::vector<Item> output; for(int i=0;i<items.size();i++){ if(items[i].importance > Kth_Max_Importance_Item.importance){ output.push_back(items[i]); } } int left_Over_Count = k - output.size(); //std::cout<<left_Over_Count<<std::endl; //Adding left_Over_Count number of values of items whose importance value if equal to importance value of Kth_Max_Importance_Item for(int i=0;i<items.size();i++){ if(compareDouble(items[i].importance, Kth_Max_Importance_Item.importance)){ output.push_back(items[i]); left_Over_Count--; } if(!left_Over_Count){ break; } } //Printing the output: for(int i=0;i<output.size();i++){ std::cout<<output[i].distance<<" "<<output[i].importance<<std::endl; } return 0; }
    9 2.3
    8 2.2
    7 2.2
    10 2.1