/// <summary>
        /// Builds a new scenario tree by merging two scenarios.
        /// </summary>
        /// <param name="St1"></param>
        /// <param name="St2"></param>
        /// <returns></returns>
        public static ScenarioTree Merge(ScenarioTree St1, ScenarioTree St2)
        {
            ScenarioTree St = new ScenarioTree();

            St.deltaT = St1.deltaT;

            //get the maximum period index...
            int T = St1.T;

            for (int t = 0; t <= T; t++)
            {
                if (t == 0)
                {
                    TreeNode root1 = St1.Root;
                    TreeNode root2 = St2.Root;
                    TreeNode root  = new TreeNode(t, null, 1.0);
                    MergeValues(root1, root2, ref root);
                    root.ComesFrom(root1, root2);

                    St.Add(root);
                }
                else
                {
                    List <TreeNode> L1 = St1.NodesAt(t);
                    List <TreeNode> L2 = St2.NodesAt(t);

                    List <TreeNode> Previous = St.NodesAt(t - 1);
                    foreach (TreeNode n1 in L1)
                    {
                        foreach (TreeNode n2 in L2)
                        {
                            TreeNode n = new TreeNode();
                            n.Period      = t;
                            n.Probability = n1.Probability * n2.Probability;
                            MergeValues(n1, n2, ref n);

                            n.Predecessor = ScenarioTree.ComeFromListSearch(Previous, n1.Predecessor, n2.Predecessor);

                            St.Add(n);
                            n.ComesFrom(n1, n2);
                        }
                    }
                }
            }

            return(St);
        }
        public static ScenarioTree AMPL_Import(string file_name)
        {
            ScenarioTree St      = new ScenarioTree();
            StreamReader freader = File.OpenText(file_name);

            string first_line = freader.ReadLine();

            do
            {
                string   line  = freader.ReadLine();
                string[] parts = line.Split('\t');

                if (parts[parts.Length - 1] == string.Empty)
                {
                    parts = Reshape(parts, 0, parts.Length - 1);
                }

                if (parts.Length > 6)
                {
                    TreeNode Tn = new TreeNode();

                    Tn.Id          = int.Parse(parts[0]);
                    Tn.Probability = double.Parse(parts[1]);
                    Tn.Period      = int.Parse(parts[2]);

                    if (parts[3] != string.Empty)
                    {
                        Tn.PredecessorId = int.Parse(parts[3]);
                    }
                    else
                    {
                        Tn.PredecessorId = -1;
                    }

                    Tn.Value = new float[parts.Length - 4];
                    for (int c = 0; c < parts.Length - 4; c++)
                    {
                        Tn.Value[c] = float.Parse(parts[4 + c]);
                    }

                    St.Add(Tn);
                }
            }while (!freader.EndOfStream);

            St.ConvertPredecessorIdsToReferences();

            // Create a deltaT vector.
            St.deltaT = new double[St.T];
            for (int i = 0; i < St.deltaT.Length; i++)
            {
                St.deltaT[i] = 1;
            }

            freader.Close();
            return(St);
        }
        public ScenarioTree Clone()
        {
            ScenarioTree cloned = new ScenarioTree();

            for (int z = 0; z < Count; z++)
            {
                cloned.Add(this[z]);
                if (this[z].Predecessor != null)
                {
                    cloned[z].Predecessor = cloned[this.FindPredecessorIndex(z)];
                }
            }

            cloned.deltaT = (double[])deltaT.Clone();
            return(cloned);
        }
        /// <summary>
        /// Read a text file with the following structure
        ///
        /// Node:
        /// Id:= x1
        /// p := x1
        /// t := x1
        /// v := x1 x2 xn
        /// ParentId := c1
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static ScenarioTree FromFile(string file)
        {
            StreamReader sr = File.OpenText(file);
            string       line;

            ScenarioTree tree = new ScenarioTree();
            TreeNode     tn   = null;

            do
            {
                line = sr.ReadLine();

                if (line.Contains("Node:"))
                {
                    // Add the previous.
                    if (tn != null)
                    {
                        tree.Add(tn);
                    }

                    tn = new TreeNode();
                }
                else if (line.Contains("ParentId"))
                {
                    line = CutIdentifier(line);
                    int predessor_id = int.Parse(line);
                    if (predessor_id > 0)
                    {
                        tn.Predecessor = tree[predessor_id - 1];
                    }
                }
                else if (line.Contains("Id"))
                {
                    line  = CutIdentifier(line);
                    tn.Id = int.Parse(line);
                }
                else if (line.Contains("p"))
                {
                    line           = CutIdentifier(line);
                    tn.Probability = double.Parse(line);
                }
                else if (line.Contains("t"))
                {
                    line      = CutIdentifier(line);
                    tn.Period = int.Parse(line);
                }
                else if (line.Contains("v"))
                {
                    line = CutIdentifier(line);
                    string[] values = line.Split('\t');
                    tn.Value = new float[values.Length - 1];
                    for (int i = 0; i < values.Length - 1; i++)
                    {
                        tn.Value[i] = float.Parse(values[i]);
                    }
                }
            }while (!sr.EndOfStream);

            // Aadd the last one.
            if (tn != null)
            {
                tree.Add(tn);
            }

            int min_period = 1;

            // Check for the format of periods.
            for (int z = 0; z < tree.Count; z++)
            {
                if (tree[z].Period < min_period)
                {
                    min_period = tree[z].Period;
                }
            }

            if (min_period == 1)
            {
                tree.OneBasedPeriods = 1;

                for (int z = 0; z < tree.Count; z++)
                {
                    tree[z].Period--;
                }
            }
            else
            {
                tree.OneBasedPeriods = 0;
            }

            int Periods = tree.T + 1;

            tree.deltaT = new double[Periods];
            for (int t = 0; t < Periods; t++)
            {
                tree.deltaT[t] = 1;
            }

            return(tree);
        }