階層化

ryamada2222222012-12-25

  • ノードとエッジからできたものが全体グラフの中でサブグラフになる
  • このサブグラフもノードとして扱いたい
  • サブグラフはノードの集合とエッジの集合の組でできている(グラフはノード集合とエッジ集合の組)
  • このサブグラフをノードに帰属させるには、ノード集合とエッジ集合とにエッジを下したノードを作ることで可能だが、その前に、すべてのエッジはノード扱いできるようにする必要がある
  • 言い換えると、ノード集合とエッジ集合を作るときにエッジの集合もノード集合とする(ただしこのノードは本来のノード2つにエッジを伸ばした、次数2に限定したノード)こととし、このノード集合をエッジがノード化したノード集合を作り、その上でサブグラフに相当するノードからは、エッジがノード化したノード(と、もしあれば、サブグラフに帰属する次数0のノード(サブグラフ上で連結していないノード)にエッジを下ろすものとする
  • こうすれば、ノード・エッジに関してサブグラフによる取りまとめができ、さらにこのサブグラフに対応するノードを要素とするサブグラフを従えたサブグラフも作れそうだ
  • やってみよう
    • こんな「メタな知識」をファイル"メタ正単体.txt"で受け取る
    • ファイル名がメタな知識につけられた名前であり、そんなメタな知識同士(正単体.txtと双対.txt)同士を結んだり、メタな知識(正単体.txt)と単なる用語知識("完全グラフ")とを結んだりできる
正単体.txt	双対.txt
正単体.txt	完全グラフ


setwd("C:\\Users\\ryamada\\Desktop\\20121214入力ノート")
library(igraph)
#infiles <- c("正単体.txt","双対.txt","序数.txt","グラフ理論.txt","集合.txt","数.txt","複体.txt")
infiles <- c("正単体.txt","双対.txt","グラフ理論.txt","メタ正単体.txt")
infile.list <- list()
for(i in 1:length(infiles)){
	infile.list[[i]] <- read.table(infiles[i], sep = "\t", fill =TRUE)
}
g <- graph.empty(directed=FALSE)
g.plus <- graph.empty(directed=FALSE)
v.list <- list()
v.plus.list <- list()
e.list <- list()
e.plus.list <- list()
for(i in 1:length(infile.list)){
	infile <- infile.list[[i]]
	# 行列の方が好きなので行列にする
	infile.m <- as.matrix(infile)

	# エッジに関係するところだけを取り出す
	infile.m <- infile.m[,1:length(infile.m[1,])]
	# ノードをユニークにする
	unique.word <- unique(c(infile.m))
	unique.word <- unique.word[which(unique.word != "")]
	# ノードの名前に順序idをつける
	v.list[[i]] <- NULL
	v.list[[i]] <- unique.word
	e.list[[i]] <- matrix(0,0,2)
	v.plus.list[[i]] <- unique.word
	e.plus.list[[i]] <- matrix(0,0,2)
	#g <- g + vertices(v.name)

	# 行ごとに要素数を数えて
	for(j in 1:length(infile.m[,1])){
		num.kids <- length(which(infile.m[j,] != ""))-1
		if(num.kids>=1){
			for(k in 1:num.kids){
				#g <- g + edges(c(infile.m[i,1],infile.m[i,j+1]))
				e.list[[i]] <- rbind(e.list[[i]],c(infile.m[j,1],infile.m[j,k+1]))
			}
		}
		
	}
	sorted.e.list <- t(apply(e.list[[i]],1,sort))
	tmp.v <- paste(sorted.e.list[,1],sorted.e.list[,2],sep="")
	v.plus.list[[i]] <- c(unique.word,infiles[i],tmp.v)
	v.plus.list[[i]] <- unique(v.plus.list[[i]])
	#e.plus.list[[i]] <- e.list[[i]]
	for(j in 1:length(e.list[[i]][,1])){
		e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(e.list[[i]][j,1],tmp.v[j]))
		e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(e.list[[i]][j,2],tmp.v[j]))
		e.plus.list[[i]] <- rbind(e.plus.list[[i]],c(tmp.v[j],infiles[i]))
	}
	#plot(g,vertex.label=V(g)$name)

}
unique.v <- unique(unlist(v.list))
unique.plus.v <- unique(unlist(v.plus.list))
g <- graph.empty(directed=FALSE) + vertices(unique.v)
g.plus <- graph.empty(directed=FALSE) + vertices(unique.plus.v)
for(i in 1:length(infile.list)){
	for(j in 1:length(e.list[[i]][,1])){
		g <- g + edges(e.list[[i]][j,])
	}
	for(j in 1:length(e.plus.list[[i]][,1])){
		g.plus <- g.plus + edges(e.plus.list[[i]][j,])
	}
}
plot(g,vertex.label=V(g)$name,vertex.size=3,edge.arrow.mode=0)
dev.new()
plot(g.plus,vertex.label=V(g.plus)$name,vertex.size=3,edge.arrow.mode=0)
  • ごちゃごちゃしてきてどうなっているのかわかりにくいのでサブクラスをまとめるノード(入力ファイル名のノード)のあたりのみを表示させる(一部を表示させる機能で)

# 2点を指定して、その最短パスを求め、その周囲だけを表示する

two <- c("正単体.txt","完全グラフ")

sh.paths <- get.shortest.paths(g.plus,two[1],two[2])
sh.paths.mat <- shortest.paths(g.plus)

lay <- layout.kamada.kawai(g)
Ls <- 0:1
par(ask=TRUE)
for(i in seq(Ls)){
	L <- Ls[i]
	tmp <- (sh.paths.mat[unlist(sh.paths),] <= L)
	neighbors <- sign(apply(tmp,2,sum))
	tmp.g <- induced.subgraph(g.plus,which(neighbors==1))
	plot(tmp.g,vertex.label=V(tmp.g)$name,vertex.size=3,edge.arrow.mode=0,layout=lay[which(neighbors==1),])

}