F#:二维数组 - 生成所有可能的二进制组合



您将使用哪种方法来生成仅包含零和代表所有可能不同组合的NXN矩阵集?

let matrix Array2D.init N N (fun x y -> something)

如果您不知道f#,那么伪代码将是贡献。

所以我想要的是所有不同矩阵组合的列表/数组

所以,我认为困难的部分是生成元素列表。我们可以递归地做。

基本情况很容易。对于1x1矩阵,您有1个元素,只能具有两个组合:[|[|0|]; [|1|]|]

对于2x2元素,我们有2^2 = 4个元素。其中每个都可以是1或0,因此可以使用2^4 = 16组合。为了使此2x2阵列的所有组合都可以看作是长度4的数组。

,但首先,让我们考虑一个长度2的数组。然后,我们必须找到[|[|0|]; [|1|]|][|[|0|]; [|1|]|]之间的所有组合。这是[|[|0; 0|]; [|0;1|]; [|1;0|]; [|1; 1|]|]。幸运的是,有一个称为Array.allPairs的函数,它将生成两个数组之间所有可能组合的数组,这已经为我们做到了!

因此,我们可以依次将Array.allPairs依次应用于长度4的每个元素,以使用Array.reduce获取整个矩阵的所有可能组合。我制作了一个称为pairsToArray的函数,以基本上使数据结构变平。

let pairsToArray x = Array.concat [|fst x; snd x|]
let rec binary N = 
    match N with
    | 0 -> [||]
    | 1 -> [|[|0|]; [|1|]|]
    | n -> let elements = n*n
           let combinations = Array.init elements (fun i -> binary 1)
           let result = Array.reduce (fun acc i -> Array.allPairs acc i |> Array.map pairsToArray) combinations
           result

现在,所有剩余的都将其转换为Array2D。像这样的事情应该做技巧

let c = binary 2
c |> Array.map (fun i -> Array2D.init 2 2 (fun j k -> i.[j+k*2]))

对于2x2案例

也许像这样的东西

let rec addOne (N1: int, N2: int) (M: int[,]) (i: int, j: int)=
  if M.[i,j] = 0
   then M.[i,j] <- 1
        true
   else M.[i,j] <- 0
        let newi, newj =
            if i < N1-1
             then (i+1,j)
             else (0,j+1)
        if newj = N2
         then false
         else addOne (N1, N2) M (newi,newj)

与此

结合
let N = 3
let M: int[,] = Array2D.zeroCreate N N
let mylist =
  [ yield M;
    while addOne (N,N) M (0,0)
       do yield Array2D.copy M ]

我不知道这是否有意义。这是找到"下一个"矩阵的方法,然后列出我们遇到的所有矩阵。

编辑:用int(0和1)替换布尔以更好地适合原始问题。

相关内容

最新更新