C ++ - возможно ли генерировать каждую перестановку массива один раз и только один раз, используя random_shuffle?

0

Мне было поручено проверить алгоритм сортировки путем "кормления" его каждой перестановки массива длины "n" один раз. Я должен делать это с random_shuffle.

Я знаю, что random_shuffle следует за равномерным распределением, т.е. Каждая перестановка имеет равные шансы быть сгенерированной, но это не означает, что каждая перестановка будет генерироваться один раз перед получением повторного результата, правильно? Скажем, если первый результат равен 12345, это займет 5! используется random_shuffle для получения повторного результата 12345. Но это не то, что происходит. Я часто повторяю результаты. Это код, который я использую:

#include <cmath>
#include <algorithm>

using namespace std;

int main()
{
int v[5]={1,2,3,4,5}, w[5], cuenta=1;
memcpy(w,v,sizeof v);
srand(time(0));

do {
    random_shuffle(v,v+5);
    for (int j=0;j<5;j++)
        cout << v[j];
    cout << endl;
    cuenta++;
    cout << cuenta << endl;
    } while (memcmp(w,v,sizeof v));
}

Я делаю что-то неправильно? Или это так, как работает random_shuffle?

редактировать:

Я знаю, что следующая: перестановка будет иметь больше смысла. Я знаю, что это слишком сложно. Но мой учитель настаивает на том, что я делаю это так, что я не должен получать повторяющиеся результаты, поскольку random_shuffle следует за равномерным распределением; что противоречит всему, что я прочитал, включая документацию. Я должен использовать random_shuffle. Я просто ищу подтверждение/конкретное поведение этой функции. И даже тогда next_permutation не является случайным.

  • 3
    случайный не имеет такой гарантии. Если вы подбрасываете монету х раз, есть небольшая вероятность того, что она всегда окажется на одном лице. Получение всех перестановок НЕ случайно
  • 0
    Составьте список всех перестановок в списке. (Читайте: список списков.) Случайно перетасуйте список списков. Достаточно для ваших нужд?
Показать ещё 8 комментариев
Теги:
arrays
permutation
random
shuffle

2 ответа

4
Лучший ответ

Вам нужно использовать random_shuffle? Это похоже на неправильный алгоритм для этой функции, поскольку нет никакой гарантии, сколько попыток вам нужно получить все ваши n! различные перестановки. Более подходящим алгоритмом будет std::next_permutation. Как в:

 do {
     // test your sort
 } while (std::next_permutation(v, v+5)); 

С random_shuffle вам нужно будет проверить, действительно ли это перестановка, которую вы делали раньше, и выполняете всю эту дополнительную работу, чтобы убедиться, что вы ее не пропустили. Я имею в виду, если вам нужно использовать его для задания, вы должны его использовать, но я бы постарался не делать этого :)

[ОБНОВЛЕНИЕ] Я просто подумал. Может быть, ваш учитель просто хочет, чтобы вы попробовали множество разных перестановок, не обязательно все из них? Подобно:

for (int i = 0; i < 1000; ++i) {
    std::random_shuffle(v, v+5);
    // test your sort
}

Это может проверить все перестановки. Возможно, это не так. Но я чувствую, что было бы маловероятно, чтобы ваш сорт был сломан, и это пройдет.

  • 0
    Я добавил редактирование, адресовав это. Я знаю, что имеет смысл использовать next_permutation, но я должен использовать random_shuffle. Большое спасибо за вклад
  • 0
    @Kovalainen Позвольте мне знать, если обновление звучит разумно на всех. Это действительно единственный разумный способ использовать random_shuffle .
2

Очень маловероятно, что каждая перестановка будет генерироваться один раз перед получением повторного результата. Каждый вызов random_shuffle() не зависит от других вызовов. Вероятность некоторого результата всегда одинакова для каждого вызова.

next_permutation() может быть тем, что вы хотите. См. Http://www.cplusplus.com/reference/algorithm/next_permutation/

  • 0
    следующая_перестановка не случайна. Он основан на лексикографическом порядке. Рандомизация представляется обязательным требованием.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню