Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.02.2015, 19:21   #1
Debauchee
Пользователь
 
Регистрация: 28.12.2011
Сообщений: 41
По умолчанию Вопрос про случайное перемешивание массива

Всем, доброго времени суток!

Дико извиняюсь за тупой вопрос.
Есть одномерный массив из N элементов. Надо производить перестановку местами случайных пар элементов чтобы массив считался полностью перемешен.
Вопрос в том, сколько раз надо переставлять местами элементы в этих самых случайных парах, исходя из длины массива?
Будьте так добры, напомните как это решается, хоть как называется решение. В голову лезут какие-то мутные обрывки про сочетание, нормальное распределение, мат.ожидание и еще что-то, что ни разу не пригодилось за последние 30 с лишним лет.

Заранее благодарю!
Debauchee вне форума Ответить с цитированием
Старый 18.02.2015, 19:47   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Обычно N достаточно
https://ru.wikipedia.org/wiki/%D0%A2...82%D1%81%D0%B0
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 18.02.2015, 22:23   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

точно так.
тут на форуме это обсуждалось.

позволю себе процитировать себя же:
Цитата:
по поводу "тасования" карт:
но мне для решения таких задач ГОРАЗДО больше нравится вариант с перемешиванием. ( можно тут посмотреть) - он очень быст, прост и не требует наличия и манипулирования динамическими массивами!
Единственное, если подходить к вопросу серьёзно, необходимо учитывать, что распределение получается неравномерным. смотри пост №11 (с) kogemrka или, статью, на которую он ссылается:
http://mazanu.com/2008/11/blog-post_20.html
Цитата:
Как не надо тасовать карты
если кратно, то алгоритм перемешивания (с нормальным распределением) должен быть такой:
Цитата:
Для (i от 1 до n-1)
Переставить i-ю карту со случайной картой от i-й до n-й
ну посмотрите реализацию - ТУТ
Serge_Bliznykov вне форума Ответить с цитированием
Старый 18.02.2015, 23:50   #4
Debauchee
Пользователь
 
Регистрация: 28.12.2011
Сообщений: 41
По умолчанию

Спасибо за ответы!

Аватар, статью прочитал. Оказывается, все не так, как себе нафантазировал

На работе начальство захотело тест профпригодности менеджеров, да еще, чтобы он был в Экселе. Придумали около 300 вопросов с пятью вариантами ответов и критерии их интерпретации, осталось только все это "засунуть" в Эксель на VBA.
Собственно тасовать надо вопросы (индексы массива с вопросами) внутри каждого теста.
Вобщем-то, перестановку я уже написал, но возникли сомнения, что некоторые элементы массива останутся на исходном месте. Поэтому "для верности" и сделал 1E6 перестановок для массива вопросов в 289 элементов. Потом задумался, а не перебор ли это...
Код:
Public Function permutationArrat(ByRef arr As Variant) As Integer
    Dim r1 As Integer, r2 As Integer, ub As Integer
    Dim i As Long
    Dim temp As Variant

    ub = UBound(arr) + 1

    Randomize
    For i = 1 To 1000000# Step 1
        r1 = 0
        r2 = 0
        Do
            r1 = Int((ub * Rnd) + 1) - 1
            r2 = Int((ub * Rnd) + 1) - 1
        Loop While (r1 = r2)

        temp = arr(r2)
        arr(r2) = arr(r1)
        arr(r1) = temp
    Next i
    permutationArrat = ub
End Function
Код:
Private Sub test()	' проверка работы функции
    Dim arr As Variant
    Dim n As Integer

    arr = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)	' тестовый массив из 10 элементов
    Debug.Print Join(arr, " ")
    n = permutationArrat(arr)

    Debug.Print Join(arr, " ")
End Sub

Последний раз редактировалось Debauchee; 18.02.2015 в 23:58.
Debauchee вне форума Ответить с цитированием
Старый 19.02.2015, 08:16   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Потом задумался, а не перебор ли это...
перебор.
достаточно всего ОДИН раз пройтись по массив, правильно переставляя случайные элементы.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 19.02.2015, 08:43   #6
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,543
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Обычно N достаточно
https://ru.wikipedia.org/wiki/%D0%A2...82%D1%81%D0%B0
Это в идеале. На самом деле N + 1. Для нечётных массивов, при N, центральный элемент, в худшем случае остаётся на месте. В лучшем, смещается на одну позицию вправо или влево.
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 20.02.2015, 10:49   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Smitt&Wesson, извините, но Вы не правы.

я не знаю, читали ли Вы статью и правильно ли поняли ли её смысл,
но суть случайного перемешивания:
Цитата:
Современный алгоритм[править | править вики-текст]
Современный вариант алгоритма тасования Фишера–Йетса, предназначенный для использования в компьютерах, был представлен Ричардом Дурштенфельдом (Richard Durstenfeld) в 1964-м году в журнале Communications of the ACM том 7, выпуск 7, под названием "Algorithm 235: Random permutation",[2] и был популяризован Дональдом Кнутом во втором томе его книги Искусство программирования как "Алгоритм P".[3] Ни Дуршенфельд, ни Кнут в первом издании книги не упомянули об алгоритме Фишера и Йетса, и, похоже, не были осведомлены о нём. Во втором издании книги Искусство программирования, однако, это упущение было исправлено.[4]

Алгоритм, описанный Дуршенфельдом, отличается от алгоритма Фишера и Йетса в небольших, но существенных деталях. Чтобы компьютерная реализация алгоритма не тратила бесполезно время на перебор оставшихся чисел на шаге 3, у Дуршенфельда на каждой итерации выбираемые числа переносились в конец списка путем перестановки с последним невыбранным числом. Эта модификация сокращала временную сложность алгоритма до O(n), по сравнению с O(n2) для исходного алгоритма.[5] Это изменение приводит к следующему алгоритму.

Для тасования массива a из n элементов (индексы 0..n-1):
для всех i от n − 1 до 1 выполнить
j ← случайное число 0 ≤ j ≤ i
обменять местами a[j] и a[i]
Грубо говоря - берём I-й элемент массива. Получаем СЛУЧАЙНОЕ число, НОВУЮ позицию этого элемента. Меняем эти два элемента местами.
Берём следующий элемент массива и повторяем действия.
Позицию, куда поставить элемент - мы получаем случайным образом, причём ПРАВИЛЬНО.
С чего это вдруг центральный элемент останется на своём месте?!!

я в сообщении #3 выложил код на Паскале. Вы его запустите - проверьте (если нет Паскаля на компьютере, можно воспользоваться онлайн).

p.s. думаю, что автор темы уже утратил к ней интерес, судя по его активности...
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перемешивание двухмерного массива stenl1 Общие вопросы C/C++ 10 22.11.2016 06:26
Случайное перемешивание Opex911 Помощь студентам 21 26.09.2011 01:15
Перемешивание массива revaldo666 Общие вопросы C/C++ 6 19.01.2011 15:04
Вопрос. Про передачу массива DartDayring Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 29.03.2010 02:27
Вопрос про циклический сдвиг массива С++ Юлия12 Общие вопросы C/C++ 4 08.02.2010 08:52