Я пытаюсь написать быстрый алгоритм для сортировки вектора большого количества целых чисел, например:Используя рекурсивные базисных роды параллельно ведра сортировки
159 14 5 97 6 54
до сих пор, моя программа разбивает вектор в небольшие ведра по МСДУ, как:
bucket[1]:159 14
bucket[5]:5 54
bucket[6]:6
bucket[9]:97
и теперь я должен использовать рекурсивный базисного род для сортировки ведра в наиболее значимых порядка цифр:
bucket[1]:14 159
bucket[5]:5 54
bucket[6]:6
bucket[9]:97
Это рекурсивный радикс код, который я нашел в Интернете:
// Sort 'size' number of integers starting at 'input' according to the 'digit'th digit
// For the parameter 'digit', 0 denotes the least significant digit and increases as significance does
void radixSort(int* input, int size, int digit){
if (size == 0)
return;
int[10] buckets; // assuming decimal numbers
// Sort the array in place while keeping track of bucket starting indices.
// If bucket[i] is meant to be empty (no numbers with i at the specified digit),
// then let bucket[i+1] = bucket[i]
for (int i = 0; i < 10; ++i)
{
radixSort(input + buckets[i], buckets[i+1] - buckets[i], digit+1);
}
}
Я не знаю, как реализовать этот бит в мой код, я не уверен, о том, что ведро [] делать в коде выше , Может ли кто-нибудь объяснить, какие изменения я должен внести? Вот многопоточный код, который я использую, который плохо работает, так как я не использую рекурсивный.
void sort(unsigned int numCores, std::vector<unsigned int> numbersToSort){
// ******************Stage 1****************
// Use multithread to seperate numbers into buckets using the most significant digits
auto smallbuckets = std::vector<std::shared_ptr<std::vector<std::vector<unsigned int>>>>();
std::mutex mutex;
unsigned int workload = numbersToSort.size()/numCores;
std::function<void(unsigned int, unsigned int, unsigned int)> put_small_buckets;
put_small_buckets = [this, &smallbuckets, &mutex]
(unsigned int id, unsigned int start, unsigned int end) {
auto buckets = std::make_shared<std::vector<std::vector<unsigned int>>>(std::vector<std::vector<unsigned int>>());
for (int j = 0; j < 10; ++j) {
buckets->push_back(std::vector<unsigned int>());
}
for (unsigned int i = start; i < end; ++i) {
unsigned int a = numbersToSort[i];
std::string tmp = std::to_string(a);
char c = tmp.at(0);
int ia = c - '0';
(*buckets)[ia].push_back(numbersToSort[i]);
}
std::lock_guard<std::mutex> lock(mutex);
smallbuckets.push_back(buckets);
};
// create a container of threads
std::vector<std::shared_ptr<std::thread>> containerOfThreads;
// create threads and add them to the container.
for (unsigned int i = 0; i < numCores; ++i) {
// start the thread.
unsigned int start = workload * i;
unsigned int end = workload * (i + 1);
if(i == numCores - 1) end = this->numbersToSort.size() ;
containerOfThreads.push_back(std::make_shared<std::thread>(put_small_buckets, i, start, end));
}
// join all the threads back together.
for (auto t : containerOfThreads) t->join();
numbersToSort.clear();
// ******************Stage 2****************
// Put small multithreaded buckets back to the bucket of radix(10)
auto bigbuckets = std::vector<std::shared_ptr<std::vector<unsigned int>>>();
for (int j = 0; j < 10; ++j) {
bigbuckets.push_back(std::make_shared<std::vector<unsigned int>>(std::vector<unsigned int>()));
}
int current_index = 10;
std::function<void()> collect;
collect = [this, &smallbuckets, ¤t_index, &mutex, &collect, &bigbuckets]() {
mutex.lock();
int index = --current_index;
mutex.unlock();
if (index < 0) return;
auto mybucket = bigbuckets[index];
for (auto i = smallbuckets.begin(); i != smallbuckets.end(); ++i) {
mybucket->insert(mybucket->end(), (*(*i))[index].begin(), (*(*i))[index].end());
}
collect();
};
// create a container of threads
containerOfThreads.clear();
// create threads and add them to the container.
for (unsigned int i = 0; i < numCores; ++i) {
containerOfThreads.push_back(std::make_shared<std::thread>(collect));
}
// join all the threads back together.
for (auto t : containerOfThreads) t->join();
// ******************Stage 3****************
// Sort big buckets
for (int j = 0; j < 10; ++j) {
bigbuckets.push_back(std::make_shared<std::vector<unsigned int>>(std::vector<unsigned int>()));
}
std::function<void(unsigned int, unsigned int)> sort_big_buckets;
sort_big_buckets = [this, &bigbuckets, &mutex]
(unsigned int start, unsigned int end) {
unsigned int curr = start;
while(curr < end){
auto mybucket = bigbuckets[curr];
std::sort(mybucket->begin(),mybucket->end(), [](const unsigned int& x, const unsigned int& y){
std::string tmp1 = std::to_string(x);
std::string tmp2 = std::to_string(y);
return lexicographical_compare(tmp1.begin(), tmp1.end(), tmp2.begin(), tmp2.end());
//return aLessB(x,y,0);
});
++curr;
}
};
// create a container of threads
containerOfThreads.clear();
workload = 10/numCores;
// create threads and add them to the container.
for (unsigned int i = 0; i < numCores; ++i) {
// start the thread.
unsigned int start = workload * i;
unsigned int end = workload * (i + 1);
if(i == numCores - 1) end = 10 ;
containerOfThreads.push_back(std::make_shared<std::thread>(sort_big_buckets, start, end));
}
// join all the threads back together.
for (auto t : containerOfThreads) t->join();
// put all elements back to numbersToSort
for (auto i = bigbuckets.begin(); i != bigbuckets.end(); ++i) {
numbersToSort.insert(numbersToSort.end(), (*i)->begin(), (*i)->end());
}
}
неродственных на ваш вопрос, но почему есть вектор (Я предполагаю) общих указателей на 'std :: thread'? Вы проезжаете этот вектор вокруг? Будете ли вы делать больше с потоками, чем просто присоединиться к ним? Почему не просто простой вектор объектов 'std :: thread'? Затем вы можете использовать 'emplace_back' для создания потоков. –
Что касается вашей проблемы, что такое 'bigbuckets'? Что такое содержимое «bigbuckets»? Можете ли вы создать [Минимальный, полный и проверенный пример] (http://stackoverflow.com/help/mcve) и показать нам? –
@Someprogrammerdude Я не передаю вектор вокруг, и я использую его, потому что один из примеров моего учебника использует его. Я попробую метод, который вы упомянули, спасибо за совет! Также я отредактировал пример с тем, что я сделал, пытаясь подойти к сортировке. – SuperMurloc