Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
 Аватар для damix
53 / 47 / 22
Регистрация: 04.11.2013
Сообщений: 410
Записей в блоге: 2

Случайное сочетание

05.02.2018, 22:50. Показов 3844. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужен алгоритм (желательно функция), который генерирует случайное сочетание из n по k. На входе целые числа n и k, на выходе список (или массив) содержащий k не повторяющихся целых чисел, каждое из которых в пределах от нуля до n. Например n = 10, k = 3, может вернуть {2; 5; 9} или {0; 3; 4} и т. п..
Как такое реализовать?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.02.2018, 22:50
Ответы с готовыми решениями:

Сочетание клавиш
Хочу заставить программу нажимать сочетание клавиш Clrl + Shift + L, не могу ни в какую Пробовал на C#, тоже не то Помогите пожалуйста

Найти сочетание из n по k
Всем привет! Мне нужно найти Сочетание из n по k где 1 <= n, k <= 10^6. Заранее спасибо!

Что такое сочетание ^=
Объясните пожалуйста что представляет собой следующая запись: b^=a^=b^=a%=b;

25
 Аватар для damix
53 / 47 / 22
Регистрация: 04.11.2013
Сообщений: 410
Записей в блоге: 2
06.02.2018, 14:24  [ТС]
Студворк — интернет-сервис помощи студентам
Да, это будет работать непредсказуемо долго, что еще хуже чем просто долго. Эту идею я отбросил в самом начале.
А что не так с этим алгоритмом?
Цитата Сообщение от damix Посмотреть сообщение
генерировать сначала числа от 0 до (n - k), сортировать их по возрастанию, а затем идти по массиву и если есть повторение, то все последующие числа увеличить на 1
Добавлено через 6 минут
...
Цитата Сообщение от palva Посмотреть сообщение
Без дополнительной памяти и совсем тупо. Выбираем случайный, если такой уже есть, то повторяем выбор.
Добавлено через 1 час 16 минут
Только у меня там ошибка на единицу, надо не до (n - k), а до (n - k + 1), ну и нужны два массива - из одного читать числа, а в другой записывать, потому что нужно помнить копию исходного массива. И я не знаю, равномерное ли будет распределение.

Добавлено через 1 минуту
TheCalligrapher, я так понимаю, тут самый эффективный - Алгоритм Боба Флойда, потому что он требует всего k итераций, а остальные - целых n итераций.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
06.02.2018, 14:39
Цитата Сообщение от damix Посмотреть сообщение
А что не так с этим алгоритмом?
Все будет в порядке, если ты докажешь, что генерируемые тобой итоговые последовательности равновероятны. Что с моей точки зрения очевидно не так. Но если тебе не требуется равновероятность, то никаких проблем нет.
0
║XLR8║
 Аватар для outoftime
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
06.02.2018, 15:14
damix, на 10М больше 6х сек на выполнение не требует.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <ctime>
 
const double SQRT_2 = ::std::sqrt(2);
 
::std::vector<size_t> random_sequence_shuffle(const size_t &k, const size_t &n)
{
    ::std::vector<size_t> ans(n);
    for (size_t i = 0; i < n; ++i)
        ans[i] = i;
    ::std::random_shuffle(ans.begin(), ans.end());
    ans.resize(k);
    return ans;
}
 
::std::vector<size_t> random_sequence_generate(const size_t &k, const size_t &n)
{
    ::std::unordered_set<size_t> r;
    for (size_t i = n - k; i < n; ++i)
    {
        size_t j = rand() % (i + 1);
        r.insert(r.find(j) == r.end() ? j : i);
    }
    return ::std::vector<size_t>(r.begin(), r.end());
}
 
::std::vector<size_t> random_sequence(const size_t &k, const size_t &n)
{
    return k > n * (SQRT_2 - 1) ? random_sequence_shuffle(k, n) : random_sequence_generate(k, n);
}
 
int main(int argc, char *argv[])
{
    int k = ::std::stoi(argv[1]),
        n = ::std::stoi(argv[2]);
    auto start = clock();
    ::random_sequence(k, n);
    auto end = clock();
    ::std::cout << double(end - start) / CLOCKS_PER_SEC << ::std::endl;
}
Bash
1
2
3
4
5
6
7
8
9
$ clang++ -std=gnu++11 -o run run.cpp
$ ./run 1 10000000
2.6e-05
$ ./run 1000000 10000000
1.22853
$ ./run 9000000 10000000
1.80145
$ ./run 4000000 10000000
5.05579
Добавлено через 4 минуты
Тут надо с этим множителем поиграться (SQRT_2 - 1)
0
 Аватар для damix
53 / 47 / 22
Регистрация: 04.11.2013
Сообщений: 410
Записей в блоге: 2
06.02.2018, 15:49  [ТС]
nonedark2008, вот я тоже подозреваю, что итоговые последовательности множества не будут равновероятными, а равновероятность здесь желательна.

Добавлено через 18 минут
outoftime, не разбираюсь я в матчасти, ваше доказательство не понял. Понял только это:
Цитата Сообщение от outoftime Посмотреть сообщение
В случае если K больше или равно N(sqrt(2) - 1) используем STL иначе один из методов TheCalligrapher
Подразумевается, что k во много раз меньше n, и следовательно меньше https://www.cyberforum.ru/cgi-bin/latex.cgi?n*(sqrt2 - 1).

Добавлено через 13 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Алгоритм Боба Флойда (упоминается в "Жемчужинах программирования")

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
  const unsigned K = 3, N = 100;
  std::unordered_set<int> r;
 
  for (unsigned i = N - K; i < N; ++i)
  {
    unsigned j = rand() % (i + 1);
    r.insert(r.find(j) == r.end() ? j : i);
  }
 
  std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << std::endl;
}
А в результате этого алгоритма сочетания равновероятны?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,308
06.02.2018, 18:26
Цитата Сообщение от damix Посмотреть сообщение
А в результате этого алгоритма сочетания равновероятны?
Именно сочетания (т.е. множества, наборы без порядка) - равновероятны. Если же вам нужны равновероятные размещения, то результат надо будет еще дополнительно перетасовать.

Добавлено через 10 минут
Цитата Сообщение от damix Посмотреть сообщение
TheCalligrapher, я так понимаю, тут самый эффективный - Алгоритм Боба Флойда, потому что он требует всего k итераций, а остальные - целых n итераций.
В теории - да. Но это еще зависит от сложности проверки на предмет того, был ли такой элемент. А на практике все будет зависеть от соотношения k и n и от накладных расходов.

Преимуществом первого алгоритма является то, что он не требует дополнительной памяти, т.е. не требует даже накопления результата.

Преимуществом второго алгоритма является то, что он накапливает результат в простом массиве, т.е. не требует поисковой структуры данных. А также то, что он является "on-line" алгоритмом: в принятии решения он не опирается на величину n, т.е. ему вообще не надо знать заранее, из скольких элементов он делает выбор.
0
 Аватар для damix
53 / 47 / 22
Регистрация: 04.11.2013
Сообщений: 410
Записей в блоге: 2
17.02.2018, 15:01  [ТС]
Алгоритм Боба Флойда. Моя реализация с использованием классов QList и QSet из библиотеки Qt.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
QList<int> RandComb(int n, int k)
{
    QList<int> randlist;
 
    int i, j;
 
    if (k >= n)
    {
        for (i = 0; i < n; i++)
            randlist << i;
    }
    else
    {
        QSet<int> randset;
 
        for (i = n - k; i < n; ++i)
        {
            j = qrand() % (i + 1);
            randset.insert(randset.contains(j) ? i : j);
        }
 
        randlist = randset.toList();
    }
 
    return randlist;
}
Перед вызовом надо сделать:
C++ (Qt)
1
2
uint t = QDateTime::currentDateTime().toTime_t();
qsrand(t);
Констуктивная критика приветствуется.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.02.2018, 15:01

Сочетание без повторений
Нужно вывести все возможные комбинации из 37 цифр без повторений. Тоисть необходимо что бы вывело все комбинации (по 6 цифр) из заданых 37...

Случайное число
Вот мне надо случайные числа в диапазоне 1-4 пишу for (int j=0;j&lt;10;j++){ srand(time(NULL)); int i = rand()%4+1; cout...

Случайное предсказание
Помогите пожалуйста. Нужно составить программу случайного предсказания 1 из 10 ближайшего будущего, с шансом на неудачу. Используя...

Заменить сочетание букв в строке
как заменить сочетание букв &quot;л*г&quot; на &quot;лаг&quot;, при выводе из текстового файла? (вместо звёздочки любая другая буква)

задача на сочетание цикла и разветвления
Даны натуральные числа п, р, целые числа A1 ..., An,. Получить произведение членов последовательности A1, ..., An, кратных р. решите на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Нейтральные знания ..., ... чистая наука. Пока что-то проходит модерацию на Хабре, стоит развить мысль ...
Hrethgir 20.07.2026
К таким радикальным взглядам я конечно в той публикации не приходил, но чтобы скоротать вечер, решил углубиться немного. 1. Почему показания термометра заряжены целью? Цель заложена в самом. . .
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ По ссылке 403. Не очень информативно такую ссылку постить. Запись от Usaga размещена Сегодня в 06:46 . . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru