주의사항/기준이 있는 무작위 선택

주의사항/기준이 있는 무작위 선택

6 x 6 그리드가 있습니다. 36개의 샘플을 3개의 동일한 그룹(A, B, C)으로 나눴습니다.

해당 그리드의 샘플을 무작위로 배열하는 수식을 원합니다. 그러나 각 행과 열에는 각 그룹이 두 개 포함되어야 합니다. 이 작업을 수동으로 한두 번 수행하는 것은 쉽지만 엄청난 수의 조합이 있습니다.

프리웨어나 Microsoft Office 기반 소프트웨어라면 자유롭게 선택할 수 있습니다.

감사합니다!

답변1

몇 가지 수식과 일부 VBA를 사용하여 임의의 행/열 순열을 생성하는 도구를 구성했습니다. 시트 레이아웃은 다음과 같습니다.

엑셀 캡처

참조 그리드는 Gary's Student의 예비 답변(삭제된 이후)에 게시된 유효한 행렬의 간단한 예입니다. 행 및 열 순열은 6x6 그리드에 대해 가능한 모든 고유한 순열 조합을 통합합니다. (원하는 경우 고유하지 않은 순열을 포함하도록 쉽게 수정할 수 있습니다.) E12:E26및 의 값은 L12:L26주어진 순열을 수행할지 여부에 대한 기준을 제공하기 위해 0 또는 1로 무작위로 시드됩니다. VBA 내에서 처리를 단순화하기 위해 열을 부울 값으로 변환하기만 하면 됩니다(아래 참조 ) D. K순열 그리드는 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

위의 코드는 견고하지는 않지만 현재 목적에 부합합니다. 필요한 경우 확장/일반화는 매우 간단해야 합니다. 특히, 정사각형이 아닌 경우에도 모든 크기의 2D 참조 그리드를 있는 그대로 처리해야 합니다. 중요한 것은 순열 명령어 배열이 올바르게 설정되었는지 확인하는 것입니다.

편집하다:조금 사용해 본 후에는 이 솔루션이 가능한 순열의 전체 공간에 대한 액세스를 제공하지 않는다는 것이 분명해졌습니다. 그래서 무작위로 "를 추가하여 조정했습니다.비트 시프트"를 사용하여 유형 레이블을 서로 교체했습니다. 단순화하기 위해 ABC레이블 에서 123레이블로 전환했습니다. 이를 통해 간단한 MOD작업으로 구현이 가능하고 행과 열 합계 형식으로 한 눈에 알아볼 수 있는 온전성 검사도 가능합니다.

엑셀 캡처

답변2

이를 수행하는 매우 간단한 방법이 있습니다. 첫 번째 사전 할당슬롯세 가지 유형 각각에 대해:

여기에 이미지 설명을 입력하세요

그런 다음 첫 번째 샘플(예: SAMPLE_A_1)을 가져와 배치합니다.무작위로A 슬롯 중 하나에 있습니다. 그런 다음 나머지 35개 샘플 각각을 계속 처리합니다.


이 접근 방식이 허용된다면 매트릭스를 채우는 짧은 프로그램을 게시하겠습니다. 접근 방식이 받아들여지지 않으면 이 게시물을 삭제하겠습니다.

관련 정보