id:witchmakersと集合位相の勉強会をやっているわけですが、直積とかべき集合とか毎回書き出すのは面倒です。人間のやるべきことではありません。そういうわけで、自分用の集合を生成する関数をRで書いたりしました。
直積
こんな感じで直積を書き出せるようなのを書いてみました。> write.direct.product(1:3,4:6) [1] "{(1,4),(2,4),(3,4),(1,5),(2,5),(3,5),(1,6),(2,6),(3,6)}"
関数定義はこんなの。expand.gridのおかげで簡単。
write.direct.product <- function(x,y){ e <- expand.grid(x,y) m <- mapply(function(x,y){paste("(",x,",",y,")",sep="")},e[,1],e[,2]) return(paste("{",paste(m,collapse=","),"}",sep="")) }
直積を引数にするような関数とかはこんな感じで書けますね。
> apply(expand.grid(1:3,4:6),1,function(x){x[1]*x[2]}) [1] 4 8 12 5 10 15 6 12 18 > apply(expand.grid(letters[1:3],1:3),1,function(d){Reduce(function(x,init){paste(init,x,sep="")},rep(d[1],d[2]),init="")}) [1] "a" "b" "c" "aa" "bb" "cc" "aaa" "bbb" "ccc"
冪集合
冪集合を生成するようなコードは昔この辺に書いたりしました。が、もっと簡単にできるはず。ということで書きました。combn関数とかapplyとかがあるから楽すぎた。
powerset <- function(list){ c(NA,unlist(lapply(seq(length(list)),function(x){apply(combn(list,x),2,function(y){y})}),recursive=FALSE)) }
とりあえず、こんなことができる。
> powerset(list("a","b","c")) [[1]] [1] NA [[2]] [[2]][[1]] [1] "a" [[3]] [[3]][[1]] [1] "b" [[4]] [[4]][[1]] [1] "c" [[5]] [[5]][[1]] [1] "a" [[5]][[2]] [1] "b" [[6]] [[6]][[1]] [1] "a" [[6]][[2]] [1] "c" [[7]] [[7]][[1]] [1] "b" [[7]][[2]] [1] "c" [[8]] [[8]][[1]] [1] "a" [[8]][[2]] [1] "b" [[8]][[3]] [1] "c"
これだと見ずらいので、lapplyを使えば大丈夫。
> lapply(powerset(list("a","b","c")),unlist) [[1]] [1] NA [[2]] [1] "a" [[3]] [1] "b" [[4]] [1] "c" [[5]] [1] "a" "b" [[6]] [1] "a" "c" [[7]] [1] "b" "c" [[8]] [1] "a" "b" "c"
これを集合っぽく書きたいよね!!ということで書きました。というかskypeとかで簡単にはれるから(ry。
write.list <- function(list){ write.vector <- function(vector){ return(paste("{",paste(vector,collapse=","),"}",sep="")) } write.list.intern <- function(list){ ifelse(is.list(list),Reduce(function(init,x){paste(init,write.list.intern(x),sep="")},list,""),write.vector(list)) } gsub("NA","",paste("{",gsub("\\}\\{","\\},\\{",write.list.intern(list)),"}",sep="")) }
これでおk。
> write.list(list("a","b","c","d",list(1:10,list(1,2)))) [1] "{{a},{b},{c},{d},{1,2,3,4,5,6,7,8,9,10},{1},{2}}" > write.list(lapply(powerset(list("a","b","c","d")),unlist)) [1] "{{},{a},{b},{c},{d},{a,b},{a,c},{a,d},{b,c},{b,d},{c,d},{a,b,c},{a,b,d},{a,c,d},{b,c,d},{a,b,c,d}}"
その他もうちょち書いたんだけど、この辺に書きすてておく。