![](/img/trans.png)
[英]What's the most efficient algo for finding the smallest/largest K elements in an unsorted array?
[英]Finding the K UNIQUE largest elements in an unsorted array of pairs
所以這是場景。 我有一個未分類的數組(非常大),稱為Gallery,其中包含成對的模板( std::vector<uint8_t>
)及其關聯的ID( std::string
)。
我有一個向我提供模板的函數,並且必須返回畫廊中k
最相似的模板的ID(我使用余弦相似度在模板之間生成相似度得分)。
我認為使用在討論堆這篇文章 。 但是,問題在於圖庫可以包含屬於一個ID的多個不同模板。 在我的函數中,我必須返回k
唯一 ID。
對於上下文,我正在做一個面部識別應用程序。 我可以在畫廊中擁有屬於一個人的多個不同模板(該人使用多個不同的圖像注冊了畫廊,因此,多個模板屬於他們的ID)。 搜索功能應將k
最相似的人返回給提供的模板(因此,一次返回相同的ID不得超過一次)。
將贊賞在C ++中執行此操作的高效算法。
編輯 :為我建議的堆解決方案剪斷了代碼(無法正確處理重復項)
std::priority_queue<std::pair<double, std::string>, std::vector<std::pair<double, std::string> >, std::greater<> > queue;
for(const auto& templPair : m_gallery) {
try{
double similairty = computeSimilarityScore(templPair.templ, idTemplateDeserial);
if (queue.size() < candidateListLength) {
queue.push(std::pair<double, std::string>(similairty, templPair.id));
} else if (queue.top().first < similairty) {
queue.pop();
queue.push(std::pair<double, std::string>(similairty, templPair.id));
}
} catch(...) {
std::cout << "Unable to compute similarity\n";
continue;
}
}
// CandidateListLength number of IDs with the highest scores will be in queue
這是一個希望對您有所幫助的示例。 為了簡單起見,我將假定已經為模板計算了相似性得分。
模板1:相似分數:0.4,ID:賽勒斯
范本2:相似分數:0.5,編號:James
模板3:相似度得分:0.9,ID:鮑勃
模板4:相似度得分:0.8,ID:賽勒斯
模板5:相似度得分:0.7,ID:凡妮莎
模板6:相似度得分:0.3,ID:Ariana
獲取前3個得分模板的ID將返回[Bob,Cyrus,Vanessa]
使用std :: set結構(平衡的BST)而不是堆。 它還可以按順序排列元素,讓您找到插入的最大和最小元素。 此外,使用插入功能時,它會自動檢測到重復項並將其忽略,因此內部的每個元素將始終是唯一的。 復雜度是完全一樣的(盡管由於常數較大,所以速度稍慢)。
編輯:我可能不正確理解該問題。 據我所知,您可以具有多個具有不同值的元素,這些元素應被視為重復項。
我會怎么做:
制作一個映射,其中key是ID,value是該集中當前模板的模板值。
如果要添加新模板:
實施了Maras的答案綱要。 似乎可以完成工作。
#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <string>
#include <set>
int main() {
int K = 3;
std::vector<std::pair<double, std::string>> data {
{0.4, "Cyrus"},
{0.5, "James"},
{0.9, "Bob"},
{0.8, "Cyrus"},
{0.7, "Vanessa"},
{0.3, "Ariana"},
};
std::set<std::pair<double, std::string>> mySet;
std::map<std::string, double> myMap;
for (const auto& pair: data) {
if (myMap.find( pair.second ) == myMap.end()) {
// The ID is unique
if (mySet.size() < K) {
// The size of the set is less than the size of search candidates
// Add the result to the map and the set
mySet.insert(pair);
myMap[pair.second] = pair.first;
} else {
// Check to see if the current score is larger than the worst performer in the set
auto worstPairPtr = mySet.begin();
if (pair.first > (*worstPairPtr).first) {
// The contender performed better than the worst in the set
// Remove the worst item from the set, and add the contender
// Remove the corresponding item from the map, and add the new contender
mySet.erase(worstPairPtr);
myMap.erase((*worstPairPtr).second);
mySet.insert(pair);
myMap[pair.second] = pair.first;
}
}
} else {
// The ID already exists
// Compare the contender score to the score of the existing ID.
// If the contender score is better, replace the existing item score with the new score
// Remove the old item from the set
if (pair.first > myMap[pair.second]) {
mySet.erase({myMap[pair.second], pair.second});
mySet.insert(pair);
myMap[pair.second] = pair.first;
}
}
}
for (auto it = mySet.rbegin(); it != mySet.rend(); ++it) {
std::cout << (*it).second << std::endl;
}
}
輸出是
Bob
Cyrus
Vanessa
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.