Случайный выбор с оговоркой / критериями

519
Andrew Cooke

У меня есть сетка 6 х 6. У меня есть 36 образцов, разделенных на три равные группы (A, B и C).

Я хочу, чтобы формула располагала образцы в этой сетке случайным образом. Однако каждая строка и каждый столбец должны содержать две группы. Делать это вручную один или два раза легко, но существует огромное количество комбинаций.

Я открыт в плане выбора программного обеспечения, если оно бесплатное или на базе Microsoft Office.

Спасибо!

2
Добро пожаловать в SuperUser! Интересный вопрос. Чтобы уточнить, имеет ли значение, что члены данной группы всегда находятся в одном и том же месте в сетке? То есть, является ли это приемлемым решением, если первая строка всегда `AABBCC`, даже если все двенадцать выборок` A` можно поменять местами в этих первых двух точках? hBy2Py 8 лет назад 0
Брайан К сожалению нет. Представьте, что каждая координата сетки считается «слотом», и для каждой выборки имеется двенадцать слотов, а в каждой строке и столбце - две. Это расположение этих слотов, которое я хочу рандомизировать (в пределах моего предупреждения 2 в каждой строке и столбце). Думайте об этом как 6 x 6 судоку. Есть миллионы комбинаций, которые работают, я, по сути, хочу метод, который использует случайность для создания одной из этих миллионов комбинаций. Одна мысль была сделать сетку вручную, которая работает. Затем случайным образом меняйте месторасположение всех столбцов, затем делайте то же самое со строками - что за работа? Andrew Cooke 8 лет назад 0
, боялся, что это то, что вы были после. Случайный обмен может работать - я не знаю достаточно об алгоритмах и математике такого рода вещей, чтобы знать, обеспечит ли он доступ ко всему пространству возможных конфигураций. Если вам не нужно обеспечивать такую ​​исчерпывающую производительность, она может работать достаточно хорошо. Вам, вероятно, понадобится кодировать его в VBA, так как написание формул рабочего листа для обработки перестановок строк / столбцов будет непростым делом. Я буду пережевывать это все же. hBy2Py 8 лет назад 0

2 ответа на вопрос

1
hBy2Py

Я собрал инструмент для генерации случайных перестановок строк / столбцов с помощью нескольких формул и некоторого VBA. Макет листа выглядит следующим образом:

Excel snip

Сетка ссылок - это тривиальный пример действительной матрицы, опубликованной в предварительном ответе ученика Гэри (возможно, с тех пор, как он был удален). Перестановки строк и столбцов включают в себя все возможные уникальные комбинации перестановок для сетки 6x6. (Это можно легко изменить, чтобы включить неуникальные перестановки, если это необходимо.) Значения E12:E26и L12:L26случайным образом добавляются в ноль или единицу, чтобы обеспечить основу для того, выполнять или нет заданную перестановку. Столбцы Dи Kпросто преобразуйте их в логические значения для упрощенной обработки в VBA (см. Ниже). Переставленная сетка генерируется пользовательской функцией doSwap, вводимой в виде формулы массива. НажатиеF9 для запуска пересчета листа вызывает различныеRAND функции для генерации их случайных значений, изменения серии перестановок, которые будут выполнены.

Код VBA, который включает это поведение:

Function doSwap(srcRg As Range, rowSwaps As Range, colSwaps As Range) As Variant Dim workVt As Variant Dim iter As Long  workVt = srcRg.Value  ' Do row swaps For iter = 1 To rowSwaps.Rows.Count With rowSwaps If .Cells(iter, 3).Value Then workVt = swapRow(workVt, .Cells(iter, 1), .Cells(iter, 2)) End If End With Next iter  ' Do col swaps For iter = 1 To colSwaps.Rows.Count With colSwaps If .Cells(iter, 3).Value Then workVt = swapCol(workVt, .Cells(iter, 1), .Cells(iter, 2)) End If End With Next iter  ' Store and return doSwap = workVt  End Function  Function swapCol(ByVal inArr As Variant, idx1 As Long, idx2 As Long) As Variant Dim tempVal As Variant, workVt As Variant Dim iter As Long  ' Check if Range or Array input If IsObject(inArr) Then If TypeOf inArr Is Range Then workVt = inArr.Value Else swapCol = "ERROR" Exit Function End If Else workVt = inArr End If  ' Just crash if not correct size ' Do swap For iter = LBound(workVt, 1) To UBound(workVt, 1) tempVal = workVt(iter, idx1) workVt(iter, idx1) = workVt(iter, idx2) workVt(iter, idx2) = tempVal Next iter  ' Return swapCol = workVt  End Function  Function swapRow(ByVal inArr As Variant, idx1 As Long, idx2 As Long) As Variant Dim tempVal As Variant, workVt As Variant Dim iter As Long  ' Check if Range or Array input If IsObject(inArr) Then If TypeOf inArr Is Range Then workVt = inArr.Value Else swapRow = "ERROR" Exit Function End If Else workVt = inArr End If  ' Just crash if not correct size ' Do swap For iter = LBound(workVt, 2) To UBound(workVt, 2) tempVal = workVt(idx1, iter) workVt(idx1, iter) = workVt(idx2, iter) workVt(idx2, iter) = tempVal Next iter  ' Return swapRow = workVt  End Function 

Вышеприведенный код не очень хорошо оправдан, но служит настоящей цели. Расширение / обобщение должно быть довольно простым, если это необходимо. В частности, он должен обрабатывать как-бы любой размер двумерной эталонной сетки, даже не квадратный. Ключевым моментом является обеспечение правильной настройки массивов команд перестановки.

РЕДАКТИРОВАТЬ: немного поиграв, становится ясно, что это решение не предоставляет доступ ко всему пространству возможных перестановок. Итак, я изменил его, добавив случайный « сдвиг битов », чтобы поменять метки типов между собой. Для упрощения я переключился с ABCметок на 123метки, что позволяет реализовать простую MODоперацию, а также быструю проверку работоспособности в виде сумм строк и столбцов:

Excel snip

Молодец, Брайан! Похоже, работает очень хорошо! Gary's Student 8 лет назад 0
Вот это да. С моего первоначального взгляда на это выглядит абсолютно идеально. Сейчас я возьму какой-нибудь город, чтобы глубже попробовать это. Не могу отблагодарить вас за усилия! Andrew Cooke 8 лет назад 0
Конечно! Рад был помочь. Если это работает хорошо для вас, единственное, что вам нужно, это принятый ответ. :-) hBy2Py 8 лет назад 0
0
Gary's Student

Существует очень простой способ сделать это. Сначала предварительно назначьте слоты каждому из трех типов:

Затем возьмите первый образец, например, SAMPLE_A_1, и поместите его случайным образом в один из A-слотов. Затем продолжите обработку каждого из оставшихся 35 образцов.


Если такой подход приемлем, я опубликую короткую программу для заполнения матрицы. Если подход не является приемлемым, я удалю этот пост.

Привет - Извинения, в моем первоначальном вопросе была некоторая двусмысленность. Все образцы A идентичны, как образцы B и C. Таким образом, проблема заключается в том, чтобы сделать «слоты» (как вы их использовали). Формирование «слотов» должно быть случайным, но в пределах оговорки (по 2 на каждый образец в каждой строке и столбце). Один способ, на который я посмотрел и хотел бы получить обратную связь, был: я создал сетку, как вы показали выше. Затем я случайным образом расположил эти столбцы, а затем строки. Я просто не уверен, является ли это случайным или этот метод не учитывает каждую возможность. Спасибо, что вернулся ко мне! Andrew Cooke 8 лет назад 0
@AndrewCooke .... Возможно, мы можем начать с известного шаблона и "перемешать карты" ....... если мы начнем с моего шаблона и просто поменяемся столбцами ** A ** и ** B **, мы в конечном итоге с действительным шаблоном ..... на самом деле, мы можем поменять ЛЮБОЙ два случайно выбранных столбца и иметь действительный шаблон ............ то же самое верно для строк ... это может быть способом генерации дел. Gary's Student 8 лет назад 0

Похожие вопросы