Seleção aleatória com uma advertência / critério

2

Eu tenho uma grade de 6 x 6. Eu tenho 36 amostras divididas em três grupos iguais (A, B e C).

Eu quero uma fórmula para organizar as amostras nessa grade aleatoriamente. No entanto, cada linha e cada coluna deve conter dois de cada grupo. Fazer isso manualmente uma ou duas vezes é fácil, mas há um grande número de combinações.

Estou aberto em termos de opções de software, desde que seja freeware ou baseado no Microsoft Office.

Obrigado!

    
por Andrew Cooke 20.05.2015 / 15:02

2 respostas

1

Eu montei uma ferramenta para gerar permutações aleatórias de linha / coluna com algumas fórmulas e algum VBA. O layout da folha é assim:

Agradedereferênciaéumexemplotrivialdeumamatrizválida,conformepostadanarespostapreliminardoGary'sStudent(possivelmenteexcluída).Aspermutaçõesdelinhaecolunaincorporamtodasaspossíveiscombinaçõesexclusivasdepermutaçõesparaagrade6x6.(Issopodeserfacilmentemodificadoparaincluirpermutaçõesnãoexclusivas,sedesejado.)OsvaloresemE12:E26eL12:L26sãodistribuídosaleatoriamenteparazeroouum,parafornecerabaseparaexecutarounãoumadeterminadapermutação.AscolunasDeKapenasasconvertememvaloresbooleanosparamanipulaçãosimplificadanoVBA(vejaabaixo).AgradepermutadaégeradapelafunçãopersonalizadadoSwap,inseridacomoumafórmuladematriz.PressionarF9paraacionarorecálculodafolhafazcomqueasváriasfunçõesRANDgeremnovamenteseusvaloresaleatórios,alterandoasériedepermutaçõesaseremexecutadas.

OcódigodoVBAquehabilitaessecomportamentoé:

FunctiondoSwap(srcRgAsRange,rowSwapsAsRange,colSwapsAsRange)AsVariantDimworkVtAsVariantDimiterAsLongworkVt=srcRg.Value'DorowswapsForiter=1TorowSwaps.Rows.CountWithrowSwapsIf.Cells(iter,3).ValueThenworkVt=swapRow(workVt,.Cells(iter,1),.Cells(iter,2))EndIfEndWithNextiter'DocolswapsForiter=1TocolSwaps.Rows.CountWithcolSwapsIf.Cells(iter,3).ValueThenworkVt=swapCol(workVt,.Cells(iter,1),.Cells(iter,2))EndIfEndWithNextiter'StoreandreturndoSwap=workVtEndFunctionFunctionswapCol(ByValinArrAsVariant,idx1AsLong,idx2AsLong)AsVariantDimtempValAsVariant,workVtAsVariantDimiterAsLong'CheckifRangeorArrayinputIfIsObject(inArr)ThenIfTypeOfinArrIsRangeThenworkVt=inArr.ValueElseswapCol="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

O código acima não é bem robusto, mas serve ao propósito atual. A extensão / generalização deve ser bastante direta, se necessário. Em particular, ele deve lidar como é qualquer tamanho de grade de referência 2-D, mesmo que seja não-quadrado. O importante é garantir que as matrizes de instruções de permutação sejam configuradas corretamente.

EDITAR: Depois de brincar um pouco com isso, fica claro que essa solução não fornece acesso ao espaço total de possíveis permutações. Então, eu ajustei adicionando um " bit shift aleatório" para trocar os tipos de etiquetas entre si. Para simplificar, mudei de ABC labels para 123 labels, o que permite a implementação por meio de uma simples operação MOD e também uma rápida verificação de sanidade na forma de somas de linha e coluna:

    
por 21.05.2015 / 17:48
0

Existe uma maneira muito simples de conseguir isso. Primeiro, pré-atribua slots a cada um dos três tipos:

Em seguida, pegue a primeira amostra, por exemplo, SAMPLE_A_1, e coloque-a aleatoriamente em um dos slots A. Em seguida, continue a processar cada uma das 35 amostras restantes.


Se essa abordagem for aceitável, publicarei um programa curto para preencher a matriz. Se a abordagem não for aceitável, eliminarei este post.

    
por 20.05.2015 / 15:48