帶有警告/標準的隨機選擇

帶有警告/標準的隨機選擇

我有一個 6 x 6 網格。我有 36 個樣本,分成三個相等的組別(A、B 和 C)。

我想要一個公式來隨機排列該網格中的樣本。但是,每行和每列必須包含每組中的兩個。手動執行一次或兩次很容易,但有大量的組合。

我對軟體選擇持開放態度,只要它是免費軟體或基於 Microsoft Office 的。

謝謝你!

答案1

我用幾個公式和一些 VBA 組合了一個用於產生隨機行/列排列的工具。工作表佈局如下所示:

Excel 截圖

參考網格是有效矩陣的一個簡單範例,如加里學生的初步答案中所發布的(可能已被刪除)。行和列排列包含 6x6 網格的所有可能的獨特排列組合。 (如果需要,可以輕鬆修改以包括非唯一排列。)E12:E26和中的值L12:L26隨機播種為零或一,以提供是否執行給定排列的基礎。列DK只需將它們轉換為布林值,以簡化 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 截圖

答案2

有一個非常簡單的方法可以實現這一點。首先預先分配插槽對於這三種類型中的每一種:

在此輸入影像描述

然後取出第一個樣本,例如 SAMPLE_A_1,並將其放置在隨機地在 A 槽之一。然後繼續處理剩下的 35 個樣本。


如果這種方法可以接受,我將發布一個簡短的程式來填入矩陣。如果該方法不可接受,我將刪除此帖子。

相關內容