Пример #1
0
        /// <remarks>
        /// 同じ種類の関数ごとに足していった方が最適な構造が得られるため、
        /// 関数のリストを一度ソートしてから足しなおす。
        /// あと、定数 0 が混ざってたら消す。
        /// </remarks>
        public override Function Optimize()
        {
            Hashtable table = new Hashtable();

            // 種類わけ
            foreach (Function f in this.functions)
            {
                Function g = f.Optimize();

                Type t = g.GetType();
                if (table[t] == null)
                {
                    table[t] = g;
                }
                else
                {
                    table[t] = (Function)table[t] + g;
                }
            }

            // 繋ぎなおす
            ArrayList func = new ArrayList();

            foreach (Function f in table.Values)
            {
                if (f is Sum)
                {
                    Sum s = f as Sum;
                    func.AddRange(s.functions);
                }
                else
                {
                    if (!f.Equals((Constant)0))
                    {
                        func.Add(f);
                    }
                }
            }

            // 特殊な場合
            if (func.Count == 0)
            {
                return((Constant)0);
            }

            if (func.Count == 1)
            {
                return(func[0] as Function);
            }

            // 足しなおす。
            Function h = func[0] as Function;

            for (int i = 1; i < func.Count; ++i)
            {
                h += func[i] as Function;
            }

            return(h);
        }
Пример #2
0
        /// <remarks>
        /// 同じ種類の関数ごとに掛けていった方が最適な構造が得られるため、
        /// 関数のリストを一度ソートしてから掛けなおす。
        /// あと、Constant とか Variable とか Function の辺りの乗算を最適化。
        /// </remarks>
        public override Function Optimize()
        {
            Hashtable table = new Hashtable();

            // 種類わけ
            foreach (Function f in this.functions)
            {
                Function g = f.Optimize();

                Type t = g.GetType();
                if (table[t] == null)
                {
                    table[t] = g;
                }
                else
                {
                    table[t] = (Function)table[t] * g;
                }
            }

            // 繋ぎなおす
            Constant c = table[typeof(Constant)] as Constant;

            if (c != null && c.Equals((Constant)0))
            {
                return((Constant)0);
            }

            Function v = table[typeof(Variable)] as Function;
            Multiple m = table[typeof(Multiple)] as Multiple;

            Function h = (Constant)1;

            if (v != null)
            {
                h = Sort(v);
                table.Remove(typeof(Variable));
            }
            if (c != null)
            {
                table.Remove(typeof(Constant));
            }
            if (m != null)
            {
                if (c == null)
                {
                    c = (Constant)m.Factor;
                }
                else
                {
                    c = (Constant)(c.Value * m.Factor);
                }
                h *= m.Inner;
                table.Remove(typeof(Multiple));
            }

            ArrayList func = new ArrayList();

            if (!h.Equals((Constant)1))
            {
                func.Add(h);
            }

            foreach (Function f in table.Values)
            {
                if (f is Product)
                {
                    Product p = f as Product;
                    func.AddRange(p.functions);
                }
                else
                {
                    if (!f.Equals((Constant)1))
                    {
                        func.Add(f);
                    }
                }
            }

            // 特殊な場合
            if (c == null)
            {
                if (func.Count == 0)
                {
                    return((Constant)1);
                }

                if (func.Count == 1)
                {
                    return(func[0] as Function);
                }
            }

            // 掛けなおす。
            h = func[0] as Function;
            for (int i = 1; i < func.Count; ++i)
            {
                h *= func[i] as Function;
            }

            if (c == null || c.Equals((Constant)1))
            {
                return(h);
            }
            return(new Multiple(c.Value, h));
        }