/// <summary>
        ///     Метод поска с возвратом
        ///     При поиске не добавляются в стек плохие направления
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void branchesAndBoundsAndReturn_Click(object sender, EventArgs e)
        {
            var capacity = (double)numericUpDownCapacity.Value;
            var weights  = new double[dataGridView1.Rows.Count];
            var prices   = new double[dataGridView1.Rows.Count];

            for (var index = 0; index < dataGridView1.Rows.Count; index++)
            {
                weights[index] = Convert.ToDouble(dataGridView1[0, index].EditedFormattedValue);
                prices[index]  = Convert.ToDouble(dataGridView1[1, index].EditedFormattedValue);
            }

            var stack = new Stack <BranchesAndBoundsPlan>();
            var zero  = new BranchesAndBoundsPlan();

            zero.MinWeight = 0;
            zero.MinPrice  = 0;
            zero.MaxWeight = weights.Sum();
            zero.MaxPrice  = prices.Sum();
            stack.Push(zero);
            textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, stack.Sum(i => 1 + i.bools.Count));
            var foundPrice = 0.0;
            var foundPlan  = zero;

            while (stack.Any())
            {
                var item = stack.Pop();
                do
                {
                    if (item.bools.Count == dataGridView1.Rows.Count)
                    {
                        if (item.MinPrice >= foundPrice && item.MaxWeight <= capacity)
                        {
                            foundPrice = item.MinPrice;
                            foundPlan  = item;
                        }
                        item = null;
                    }
                    else
                    {
                        var b = new BranchesAndBoundsPlan();
                        foreach (var pair in item.bools)
                        {
                            b.bools.Add(pair.Key, pair.Value);
                        }
                        var index = b.bools.Count;
                        b.bools.Add(index, true);
                        b.MaxWeight = item.MaxWeight;
                        b.MaxPrice  = item.MaxPrice;
                        b.MinWeight = item.MinWeight + weights[index];
                        b.MinPrice  = item.MinPrice + prices[index];
                        if (b.MaxPrice >= foundPrice && b.MinWeight <= capacity)
                        {
                            stack.Push(b); // отсечение границей
                            textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, stack.Sum(i => 1 + i.bools.Count));
                        }

                        index = item.bools.Count;
                        item.bools.Add(index, false);
                        item.MaxWeight = item.MaxWeight - weights[index];
                        item.MaxPrice -= prices[index];
                    }
                } while (item != null);
            }
            for (var index = 0; index < dataGridView1.Rows.Count; index++)
            {
                dataGridView1[2, index].Value = foundPlan.bools[index];
            }
            UpdateTotal();
            SystemSounds.Beep.Play();
        }
        /// <summary>
        ///     Метод ветвей и границ
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void branchesAndBounds_Click(object sender, EventArgs e)
        {
            var capacity   = (double)numericUpDownCapacity.Value;
            var weights    = new double[dataGridView1.Rows.Count];
            var prices     = new double[dataGridView1.Rows.Count];
            var foundPrice = 0.0;

            for (var index = 0; index < dataGridView1.Rows.Count; index++)
            {
                weights[index] = Convert.ToDouble(dataGridView1[0, index].EditedFormattedValue);
                prices[index]  = Convert.ToDouble(dataGridView1[1, index].EditedFormattedValue);
            }

            var list = new List <BranchesAndBoundsPlan>();
            var zero = new BranchesAndBoundsPlan();

            zero.MinWeight = 0;
            zero.MinPrice  = 0;
            zero.MaxWeight = weights.Sum();
            zero.MaxPrice  = prices.Sum();
            list.Add(zero);
            for (var index = 0; index < dataGridView1.Rows.Count; index++)
            {
                foundPrice = list.Select(i => i.MinPrice).Max();
                var list1 = new List <BranchesAndBoundsPlan>();
                foreach (var item in list)
                {
                    var a = new BranchesAndBoundsPlan();
                    var b = new BranchesAndBoundsPlan();
                    foreach (var pair in item.bools)
                    {
                        a.bools.Add(pair.Key, pair.Value);
                        b.bools.Add(pair.Key, pair.Value);
                    }
                    a.bools.Add(index, false);
                    b.bools.Add(index, true);

                    a.MaxWeight = item.MaxWeight - weights[index];
                    a.MaxPrice  = item.MaxPrice - prices[index];
                    a.MinWeight = item.MinWeight;
                    a.MinPrice  = item.MinPrice;

                    b.MaxWeight = item.MaxWeight;
                    b.MaxPrice  = item.MaxPrice;
                    b.MinWeight = item.MinWeight + weights[index];
                    b.MinPrice  = item.MinPrice + prices[index];

                    if (a.MaxPrice >= foundPrice)
                    {
                        list1.Add(a);
                    }
                    if (b.MinWeight <= capacity)
                    {
                        list1.Add(b);
                    }
                    textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, list.Sum(i => 1 + i.bools.Count) + list1.Sum(i => 1 + i.bools.Count));
                }
                foundPrice     = list1.Select(i => i.MinPrice).Max();
                list           = list1.Where(i => i.MaxPrice >= foundPrice).ToList();
                textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, list.Sum(i => 1 + i.bools.Count));
            }
            if (!list.Any())
            {
                return;
            }
            foundPrice = list.Select(i => i.MinPrice).Max();
            var z = list.First(i => i.MinPrice == foundPrice);

            for (var index = 0; index < dataGridView1.Rows.Count; index++)
            {
                dataGridView1[2, index].Value = z.bools[index];
            }
            UpdateTotal();
            SystemSounds.Beep.Play();
        }