예제 #1
0
        static void Main(string[] args)
        {
            Graph graph = new Graph();

            // グラフ(隣接リスト)を標準入力から読み込む
            string adj_text = "";
            string line = Console.ReadLine();
            while (line != null)
            {
                adj_text += line + "\r\n";
                line = Console.ReadLine();
            }
            graph.ParseAdjListText(adj_text);

            State state = new State(graph, 1, graph.GetNumberOfVertices());

            // 入力グラフの頂点の数と辺の数を出力
            Console.Error.WriteLine("# of vertices = " + graph.GetNumberOfVertices()
                + ", # of edges = " + graph.GetEdgeList().Count);

            ZDD zdd = FrontierAlgorithm.Construct(state); // フロンティア法によるZDD構築

            // 作成されたZDDのノード数と解の数を出力
            Console.Error.WriteLine("# of nodes of ZDD = " + zdd.GetNumberOfNodes());
            Console.Error.WriteLine("# of solutions = " + zdd.GetNumberOfSolutions());

            // ZDDを標準出力に出力
            Console.Write(zdd.GetZDDString());
        }
예제 #2
0
 private static void UpdateInfo(ZDDNode n_hat, int i, int x, State state)
 {
     Edge edge = state.graph.GetEdgeList()[i - 1];
     int[] src_dest = new int[] { edge.src, edge.dest };
     foreach (int u in src_dest)
     {
         if (!state.F[i - 1].Contains(u))
         {
             n_hat.deg[u] = 0;
             n_hat.comp[u] = u;
         }
     }
     if (x == 1)
     {
         ++n_hat.deg[edge.src];
         ++n_hat.deg[edge.dest];
         int c_min = Math.Min(n_hat.comp[edge.src], n_hat.comp[edge.dest]);
         int c_max = Math.Max(n_hat.comp[edge.src], n_hat.comp[edge.dest]);
         foreach (int u in state.F[i])
         {
             if (n_hat.comp[u] == c_max)
             {
                 n_hat.comp[u] = c_min;
             }
         }
     }
 }
예제 #3
0
 private static bool IsEquivalent(ZDDNode node1, ZDDNode node2, int i, State state)
 {
     foreach (int v in state.F[i]) // フロンティア上の頂点についてのみ比較
     {
         if (node1.deg[v] != node2.deg[v])
         {
             return false;
         }
         if (node1.comp[v] != node2.comp[v])
         {
             return false;
         }
     }
     return true;
 }
예제 #4
0
 private static ZDDNode Find(ZDDNode n_prime, List<ZDDNode> N_i, int i, State state)
 {
     foreach (ZDDNode n_primeprime in N_i)
     {
         if (IsEquivalent(n_prime, n_primeprime, i, state))
         {
             return n_primeprime;
         }
     }
     return null;
 }
예제 #5
0
 private static ZDDNode CheckTerminal(ZDDNode n_hat, int i, int x, State state)
 {
     Edge edge = state.graph.GetEdgeList()[i - 1];
     if (x == 1)
     {
         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 };
     foreach (int u in src_dest)
     {
         if ((u == state.s || u == state.t) && n_prime.deg[u] > 1)
         {
             return ZDDNode.ZeroTerminal;
         }
         else if ((u != state.s && u != state.t) && n_prime.deg[u] > 2)
         {
             return ZDDNode.ZeroTerminal;
         }
     }
     foreach (int u in src_dest)
     {
         if (!state.F[i].Contains(u))
         {
             if ((u == state.s || u == state.t) && n_prime.deg[u] != 1)
             {
                 return ZDDNode.ZeroTerminal;
             }
             else if ((u != state.s && u != state.t) && n_prime.deg[u] != 0 && n_prime.deg[u] != 2)
             {
                 return ZDDNode.ZeroTerminal;
             }
         }
     }
     if (i == state.graph.GetEdgeList().Count)
     {
         return ZDDNode.OneTerminal;
     }
     return null;
 }
예제 #6
0
        public static ZDD Construct(State state)
        {
            List<Edge> edge_list = state.graph.GetEdgeList();
            int[] ZeroOne = new int[] { 0, 1 };
            List<ZDDNode>[] N = new List<ZDDNode>[edge_list.Count + 2];
            N[1] = new List<ZDDNode>();
            N[1].Add(ZDDNode.CreateRootNode(state.graph.GetNumberOfVertices()));

            for (int i = 1; i <= edge_list.Count; ++i)
            {
                N[i + 1] = new List<ZDDNode>();

                foreach (ZDDNode n_hat in N[i])
                {
                    foreach (int x in ZeroOne)
                    {
                        ZDDNode n_prime = CheckTerminal(n_hat, i, x, state);

                        if (n_prime == null)
                        {
                            n_prime = n_hat.MakeCopy();
                            UpdateInfo(n_prime, i, x, state);
                            ZDDNode n_primeprime = Find(n_prime, N[i + 1], i, state);
                            if (n_primeprime != null)
                            {
                                n_prime = n_primeprime;
                            }
                            else
                            {
                                n_prime.SetNextId();
                                N[i + 1].Add(n_prime);
                            }
                        }
                        n_hat.SetChild(n_prime, x);
                    }
                }
            }
            return new ZDD(N);
        }