จะสร้างเมทริกซ์ของลำดับไบนารี่ 2 ^ n ทั้งหมดความยาว n โดยใช้การเรียกซ้ำใน R ได้อย่างไร

ฉันรู้ว่าฉันสามารถใช้expand.gridได้ แต่ฉันกำลังพยายามเรียนรู้การเขียนโปรแกรมจริง เป้าหมายของฉันคือนำสิ่งที่ฉันมีด้านล่างและใช้การเรียกซ้ำเพื่อให้ได้ลำดับไบนารี่ที่มีความยาว n ทั้งหมด 2^n

ฉันสามารถทำเช่นนี้ได้สำหรับ n = 1 แต่ฉันไม่เข้าใจว่าฉันจะใช้ฟังก์ชันเดียวกันในลักษณะวนซ้ำเพื่อให้ได้คำตอบสำหรับมิติที่สูงกว่าได้อย่างไร

นี่คือสำหรับ 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)
  }

ฉันรู้ว่าฉันต้องใช้ cbind ในคำสั่ง return สัญชาตญาณของฉันบอกว่าคำสั่ง return ควรเป็นเช่น cbind(binseq(n-1), binseq(n)) แต่จริงๆ แล้ว ณ จุดนี้ ฉันหลงทางไปหมดแล้ว

โดยทั่วไปเอาต์พุตที่ต้องการควรสร้างสิ่งนี้ซ้ำ ๆ สำหรับ 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

มันควรจะเป็นเมทริกซ์เนื่องจาก binmat กำลังถูกเติมแบบวนซ้ำ


person Michael    schedule 15.10.2019    source แหล่งที่มา
comment
ฟังก์ชันตัวอย่างของคุณสร้าง NA ในเมทริกซ์ คุณสามารถแก้ไขหรือให้ผลลัพธ์ที่คุณต้องการได้หรือไม่?   -  person yusuzech    schedule 15.10.2019
comment
ไม่ควรสำหรับ binseq(1) ปัญหาของฉันคือการสรุปถึง n › 1 โดยใช้การเรียกซ้ำ เพิ่มเอาต์พุตที่ต้องการแล้ว   -  person Michael    schedule 15.10.2019


คำตอบ (1)


ฉันเขียนฟังก์ชันนี้อย่างรวดเร็วเพื่อสร้างการเรียงสับเปลี่ยน N^K ความยาว K ทั้งหมดสำหรับอักขระ N ที่กำหนด หวังว่ามันจะมีประโยชน์

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"))

ฉันจะกลับไปหาปัญหาของคุณเมื่อฉันมีเวลามากขึ้น

อัปเดต ฉันแก้ไขโค้ดด้านบนเพื่อแก้ไขปัญหาของคุณแล้ว โปรดทราบว่าเมทริกซ์ที่มีประชากรอาศัยอยู่ในสภาพแวดล้อมโลก ฟังก์ชันยังใช้ตัวแปร tmp เพื่อส่งแถวไปยังสภาพแวดล้อมส่วนกลาง นี่เป็นวิธีที่ง่ายที่สุดสำหรับฉันในการแก้ปัญหา บางทีอาจมีวิธีอื่น

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)

อัปเดต 2 หากต้องการรับเอาต์พุตที่คาดหวังที่คุณระบุ ให้เรียกใช้

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

levels ระบุช่วงของค่าที่จะสร้าง (ไบนารีในกรณีของเรา) เพื่อสร้างการเรียงสับเปลี่ยน m เป็นเมทริกซ์ว่างที่จะเติม gen_perm สร้างแถวและเพิ่มลงในเมทริกซ์ m, lst คือความยาวของการเรียงสับเปลี่ยน (ตรงกับจำนวน คอลัมน์ในเมทริกซ์)

person slava-kohut    schedule 15.10.2019
comment
ส่วนใหญ่ฉันเข้าใจว่าสิ่งนี้กำลังทำอะไรอยู่ แม้ว่าฉันจะมองหาแนวทางที่เป็นตัวเลขมากกว่าการวางอักขระก็ตาม ฉันจะดูว่าสิ่งนี้ช่วยให้ฉันเข้าใจว่าฉันผิดพลาดตรงไหนหรือไม่ แต่เราจะขอบคุณความช่วยเหลือมากกว่านี้อย่างแน่นอน ขอบคุณ! - person Michael; 15.10.2019
comment
ไม่แน่นอน มันเกินระดับของฉันมาก โดยพื้นฐานแล้วฉันกำลังอ่านหนังสือเรียนอยู่ และฉันเปลี่ยนคำตอบที่คาดไว้เพื่อแสดงให้เห็นว่ามันคืออะไร ฉันกำลังพยายามทำซ้ำ แต่วนซ้ำสำหรับ n ขนาดใหญ่ ผลเฉลยเดิมของผม หรือขั้นตอนแรกจริงๆ ไม่ได้สร้างความเป็นไปได้ทั้งหมดด้วยซ้ำแค่ n = 1 ในทางเทคนิค - person Michael; 15.10.2019
comment
@Michael ฉันได้รวมตัวอย่างและคำชี้แจงไว้ในโพสต์ของฉันด้านบน - person slava-kohut; 15.10.2019