/// <summary> /// Метод поска с возвратом /// При поиске не добавляются в стек плохие направления /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void branchesAndBoundsAndReturn_Click(object sender, EventArgs e) { var sources = new string[dataGridView1.Rows.Count]; var destinations = new string[dataGridView1.Rows.Count]; var prices = new double[dataGridView1.Rows.Count]; for (var index = 0; index < dataGridView1.Rows.Count; index++) { sources[index] = Convert.ToString(dataGridView1[0, index].EditedFormattedValue); destinations[index] = Convert.ToString(dataGridView1[1, index].EditedFormattedValue); prices[index] = Convert.ToDouble(dataGridView1[2, index].EditedFormattedValue); } var stack = new Stack <BranchesAndBoundsPlan>(); var zero = new BranchesAndBoundsPlan(); zero.MinPrice = 0; 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 = double.MaxValue; var foundPlan = zero; while (stack.Any()) { var item = stack.Pop(); do { if (item.bools.Count == dataGridView1.Rows.Count) { var s = new List <string>(); var d = new List <string>(); for (var j = 0; j < dataGridView1.Rows.Count; j++) { if (item.bools.ContainsKey(j) && item.bools[j]) { continue; } s.Add(sources[j]); d.Add(destinations[j]); } if (item.MaxPrice < foundPrice && IsAcyclic(s, d)) { foundPrice = item.MaxPrice; 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.MaxPrice = item.MaxPrice; b.MinPrice += prices[index]; if (b.MinPrice <= foundPrice) { 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.MaxPrice -= prices[index]; } } while (item != null); } for (var index = 0; index < dataGridView1.Rows.Count; index++) { dataGridView1[3, 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 sources = new string[dataGridView1.Rows.Count]; var destinations = new string[dataGridView1.Rows.Count]; var prices = new double[dataGridView1.Rows.Count]; var foundPrice = double.MaxValue; for (var index = 0; index < dataGridView1.Rows.Count; index++) { sources[index] = Convert.ToString(dataGridView1[0, index].EditedFormattedValue); destinations[index] = Convert.ToString(dataGridView1[1, index].EditedFormattedValue); prices[index] = Convert.ToDouble(dataGridView1[2, index].EditedFormattedValue); } var list = new List <BranchesAndBoundsPlan>(); var list2 = new List <BranchesAndBoundsPlan>(); var zero = new BranchesAndBoundsPlan { MinPrice = 0, MaxPrice = prices.Sum() }; list.Add(zero); for (var index = 0; index <= dataGridView1.Rows.Count; index++) { var list1 = new List <BranchesAndBoundsPlan>(); foreach (var item in list) { var s = new List <string>(); var d = new List <string>(); for (var j = 0; j < dataGridView1.Rows.Count; j++) { if (item.bools.ContainsKey(j) && item.bools[j]) { continue; } s.Add(sources[j]); d.Add(destinations[j]); } if (IsAcyclic(s, d)) { var price = item.bools.Where(pair => pair.Value).Sum(pair => prices[pair.Key]); foundPrice = Math.Min(foundPrice, price); list2.Add(item); } else if (index < dataGridView1.Rows.Count) { 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); a.MaxPrice = item.MaxPrice - prices[index]; a.MinPrice = item.MinPrice; b.bools.Add(index, true); b.MaxPrice = item.MaxPrice; b.MinPrice = item.MinPrice + prices[index]; list1.Add(a); 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) + list2.Sum(i => 1 + i.bools.Count)); } } list = list1.Where(i => i.MinPrice <= foundPrice + 0.0001).ToList(); textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, list.Sum(i => 1 + i.bools.Count) + list2.Sum(i => 1 + i.bools.Count)); } if (!list2.Any()) { return; } textBox1.Text += string.Format("Memory: {0} items" + Environment.NewLine, list2.Sum(i => 1 + i.bools.Count)); var z = list2.First(i => Math.Abs(i.MinPrice - foundPrice) < 0.0001); for (var index = 0; index < dataGridView1.Rows.Count; index++) { dataGridView1[3, index].Value = z.bools.ContainsKey(index) && z.bools[index]; } UpdateTotal(); SystemSounds.Beep.Play(); }