Exemplo n.º 1
0
		private static ZDDNode CheckTerminal(ZDDNode n_hat, int i, int x, State state) {
			Edge edge = state.graph.GetEdgeList()[i - 1];
			if(x == 1) {
				// 辺でつないだときに,それぞれの連結成分の要素数が4超え(フォーセルズ的に破綻)したら
				if(n_hat.compCount[n_hat.comp[edge.src]] + n_hat.compCount[n_hat.comp[edge.dest]] > 4) {
					// 同じ連結成分ならセーフ
					if(n_hat.comp[edge.src] != n_hat.comp[edge.dest]) {
						return ZDDNode.ZeroTerminal;
					}
				}
				if(n_hat.mate[edge.src] != 0 || n_hat.mate[edge.dest] != 0) {
					int src = n_hat.mate[edge.src];
					int dest = n_hat.mate[edge.dest];
					if(src == 0) {
						src = edge.src;
					}
					if(dest == 0) {
						dest = edge.dest;
					}
					foreach(Edge ed in state.graph.GetEdgeList()) {
						if(ed.compare(src, dest)) {
							return ZDDNode.ZeroTerminal;
						}
					}
				}
			}
			else {
				// 四角のブロックはループさせる
				if(n_hat.comp[edge.src] == n_hat.comp[edge.dest]) {
					return ZDDNode.ZeroTerminal;
				}
			}
			ZDDNode n_prime = n_hat.MakeCopy();
			UpdateInfo(n_prime, i, x, state);
			int[] src_dest = new int[] { edge.src, edge.dest };
			bool check = false;
			// フロンティアに関して
			foreach(int u in src_dest) {
				// フロンティアを抜ける
				if(!state.F[i].Contains(u)) {
					if(n_prime.compCount[n_prime.comp[u]] < 4) {
						check = false;
						foreach(int f in state.F[i]) {
							if(n_prime.comp[f] == n_prime.comp[u]) {
								check = true;
							}
						}
						if(!check) {
							return ZDDNode.ZeroTerminal;
						}
					}
				}
			}
			// 最後の辺まで処理を終えたなら
			if(i == state.graph.GetEdgeList().Count) {
				return ZDDNode.OneTerminal;
			}
			// 0終端か1終端かまだ判定がつかない中継ノード
			return null;
		}