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