Bagaimana cara membuat matriks dari semua barisan biner 2^n dengan panjang n menggunakan rekursi di R?

Saya tahu saya bisa menggunakan expand.grid untuk ini, tetapi saya mencoba mempelajari pemrograman yang sebenarnya. Tujuan saya adalah mengambil apa yang saya miliki di bawah ini dan menggunakan rekursi untuk mendapatkan semua urutan biner 2^n dengan panjang n.

Saya dapat melakukan ini untuk n = 1, tetapi saya tidak mengerti bagaimana saya akan menggunakan fungsi yang sama secara rekursif untuk mendapatkan jawaban untuk dimensi yang lebih tinggi.

Ini untuk n = 1:

binseq <- function(n){
  binmat <- matrix(nrow = 2^n, ncol = n)
  r <- 0 #row counter
  for (i in 0:1) {
        r <- r + 1
        binmat[r,] <- i
    }
  return(binmat)
  }

Saya tahu saya mungkin harus menggunakan cbind dalam pernyataan return. Intuisi saya mengatakan pernyataan return harus seperti cbind(binseq(n-1), binseq(n)). Tapi sejujurnya, aku benar-benar tersesat saat ini.

Output yang diinginkan pada dasarnya harus menghasilkan ini secara rekursif untuk n = 3:


binmat <- matrix(nrow = 8, ncol = 3)
r <- 0 # current row of binmat
for (i in 0:1) {   
for (j in 0:1) {
for (k in 0:1) {
r <- r + 1
binmat[r,] <- c(i, j, k)}   
} 
}
binmat

Seharusnya hanya berupa matriks karena binmat diisi secara rekursif.


person Michael    schedule 15.10.2019    source sumber
comment
Contoh fungsi Anda menghasilkan NA dalam matriks. Bisakah Anda memperbaikinya atau memberikan hasil yang Anda inginkan?   -  person yusuzech    schedule 15.10.2019
comment
seharusnya tidak untuk binseq(1). Masalah saya menggeneralisasi ke n › 1 menggunakan rekursi. Output yang diinginkan juga telah ditambahkan.   -  person Michael    schedule 15.10.2019


Jawaban (1)


Saya segera menulis fungsi ini untuk menghasilkan semua permutasi N^K dengan panjang K untuk karakter N tertentu. Semoga bermanfaat.

gen_perm <- function(str=c(""), lst=5, levels = c("0", "1", "2")){
  if (nchar(str) == lst){
    cat(str, "\n")
    return(invisible(NULL))
  }
  for (i in levels){
    gen_perm(str = paste0(str,i), lst=lst, levels=levels)
  }
}

# sample call
gen_perm(lst = 3, levels = c("x", "T", "a"))

Saya akan kembali ke masalah Anda ketika saya punya lebih banyak waktu.

PERBARUI Saya memodifikasi kode di atas agar dapat mengatasi masalah Anda. Perhatikan bahwa matriks yang diisi berada di lingkungan global. Fungsi ini juga menggunakan variabel tmp untuk meneruskan baris ke lingkungan global. Ini adalah cara termudah bagi saya untuk menyelesaikan masalah tersebut. Mungkin ada cara lain.

levels <- c(0,1)
nc <- 3

m <- matrix(numeric(0), ncol = nc)

gen_perm <- function(row=numeric(), lst=nc, levels = levels){
  if (length(row) == lst){
    assign("tmp", row, .GlobalEnv)
    with(.GlobalEnv, {m <- rbind(m, tmp); rownames(m) <- NULL})
    return(invisible(NULL))
  }
  for (i in levels){
    gen_perm(row=c(row,i), lst=lst, levels=levels)
  }
}

gen_perm(lst=nc, levels=levels)

UPDATE 2 Untuk mendapatkan hasil yang diharapkan yang Anda berikan, jalankan

m <- matrix(numeric(0), ncol = 3)
gen_perm(lst = 3, levels = c(0,1))
m

levels menentukan kisaran nilai yang akan dihasilkan (biner dalam kasus kita) untuk menghasilkan permutasi, m adalah matriks kosong yang harus diisi, gen_perm menghasilkan baris dan menambahkannya ke matriks m, lst adalah panjang permutasi (cocok dengan jumlah kolom dalam matriks).

person slava-kohut    schedule 15.10.2019
comment
Saya lebih memahami apa yang dilakukannya, meskipun saya mencari pendekatan yang lebih numerik, daripada menempelkan karakter. Saya akan melihat apakah ini membantu saya memahami kesalahan saya, meskipun bantuan lebih lanjut tentu akan sangat kami hargai. Terima kasih! - person Michael; 15.10.2019
comment
tidak tepat. itu jauh melampaui levelku. Saya pada dasarnya sedang mengerjakan buku teks dan saya mengubah jawaban yang saya harapkan untuk menunjukkan dengan tepat apa yang saya coba tiru tetapi secara rekursif untuk n besar. Solusi asli saya, atau langkah pertama sebenarnya, bahkan tidak menghasilkan semua kemungkinan hanya untuk n = 1 secara teknis. - person Michael; 15.10.2019
comment
@Michael Saya menyertakan contoh dan beberapa klarifikasi pada postingan saya di atas. - person slava-kohut; 15.10.2019