private void Load_Button_Click(object sender, RoutedEventArgs e) { start_Button.IsEnabled = true; save_Button.IsEnabled = true; string exePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); using (StreamReader inputFile = new StreamReader(System.IO.Path.Combine(exePath, "plik1.txt"))) { var lineA = inputFile.ReadLine(); var valuesA = lineA.Split(';'); if (!Int32.TryParse(valuesA[0], out clientsCount)) { throw new Exception(); } clientCount_textBox.Text = clientsCount.ToString(); DrawX.SendData(mainGrid, clientsCount); if (!Int32.TryParse(valuesA[1], out minMass)) { throw new Exception(); } min_textBox.Text = minMass.ToString(); if (!Int32.TryParse(valuesA[2], out maxMass)) { throw new Exception(); } max_textBox.Text = maxMass.ToString(); clients = new Point[clientsCount]; clientsOrders = new int[clientsCount]; int i = 0; while (!inputFile.EndOfStream) { var line = inputFile.ReadLine(); var values = line.Split(';'); Double.TryParse(values[0], out double value0); Double.TryParse(values[1], out double value1); clients[i] = new Point(value0, value1); Int32.TryParse(values[2], out int value2); clientsOrders[i] = value2; i++; } } DrawX.RemoveClients(); DrawX.RemoveLines(); DrawX.DrawClients(clients); start_Button.IsEnabled = true; save_Button.IsEnabled = true; }
private void Randomize_Button_Click(object sender, RoutedEventArgs e) { start_Button.IsEnabled = true; save_Button.IsEnabled = true; UpdateParams(); // *** losowanie pozycji klientów i rysowanie ich na mapie *** clients = new Point[clientsCount]; clientsOrders = new int[clientsCount]; for (int i = 0; i < clientsCount; i++) { clients[i] = new Point(rnd.Next(0, 1000), rnd.Next(0, 1000), i); clientsOrders[i] = rnd.Next(minMass, maxMass + 1); } DrawX.RemoveClients(); DrawX.RemoveLines(); DrawX.DrawClients(clients); start_Button.IsEnabled = true; save_Button.IsEnabled = true; }
private void TracksButton_Click(object sender, RoutedEventArgs e) { DrawX.RemoveLines(); DrawX.DrawLines(tracks); }
private void HamiltonCycleButton_Click(object sender, RoutedEventArgs e) { DrawX.RemoveLines(); DrawX.DrawLines(bestTracks); }
private void Start() { UpdateParams(); int iteracjeBezPoprawy = aspirationPlusPlus; int iteracjaTotal = 1; bestOfBestCost = 1e100; finalCost = 1e100; iteration_textBlock.Dispatcher.Invoke(() => { iteration_textBlock.Text = "0"; }); cost_textBlock.Dispatcher.Invoke(() => { cost_textBlock.Text = "0"; }); bestCost_textBlock.Dispatcher.Invoke(() => { bestCost_textBlock.Text = "0"; }); finalCost_textBlock.Dispatcher.Invoke(() => { finalCost_textBlock.Text = "0"; }); while (iteracjeBezPoprawy > 0) { // *** losowanie cyklu Hamiltona *** bool bufBB = false; kNNStart_checkBox.Dispatcher.Invoke(() => { bufBB = (bool)(kNNStart_checkBox.IsChecked); }); if (bufBB == false) { tracks = new List <List <Point> >(); tracks.Add(new List <Point>()); List <Point> bufCliets = new List <Point>(); for (int i = 0; i < clientsCount; i++) { bufCliets.Add(clients[i]); } for (int i = 0; i < clientsCount; i++) { int bufr = rnd.Next(0, bufCliets.Count); tracks[0].Add(bufCliets[bufr]); bufCliets.RemoveAt(bufr); } tracks[0].Add(tracks[0][0]); } else { tracks = new List <List <Point> >(); tracks.Add(new List <Point>()); List <Point> bufCliets = new List <Point>(); for (int i = 0; i < clientsCount; i++) { bufCliets.Add(clients[i]); } int bufr = rnd.Next(0, clientsCount); tracks[0].Add(bufCliets[bufr]); bufCliets.RemoveAt(bufr); for (int i = 0; i < clientsCount - 1; i++) { double bufbestL = 2000 * clientsCount + 1; int bestInd = -1; for (int j = 0; j < bufCliets.Count; j++) { double bufD = LengthEuclid(tracks[0][i], bufCliets[j]); if (bufD < bufbestL) { bufbestL = bufD; bestInd = j; } } tracks[0].Add(bufCliets[bestInd]); bufCliets.RemoveAt(bestInd); } tracks[0].Add(tracks[0][0]); } // *** inicjalizacja zmiennych do algorytmu Tabu Search *** double bufbestCost = 2000 * clientsCount + 1, buf; int bufbestIndex1 = -1, bufbestIndex2 = -1; double bufworstCost = 0; int bufworstIndex1 = -1, bufworstIndex2 = -1; int iteracja = 1; iteration_textBlock.Dispatcher.Invoke(() => { iteration_textBlock.Text = iteracjaTotal.ToString(); }); double bestCost = CalcHamiltonTrackLengh(tracks[0]); cost_textBlock.Dispatcher.Invoke(() => { cost_textBlock.Text = bestCost.ToString("F3"); }); bool bufBreak = false, aspPlus = false; int iPlus = 0; bool paraTabu = false; // *** wyliczanie pierwszego kosztu *** cost1_textBlock.Dispatcher.Invoke(() => { cost1_textBlock.Text = bestCost.ToString("F3"); }); // *** rysowanie wylosowanego cyklu Hamiltona *** DrawX.RemoveLines(); DrawX.DrawLines(tracks); // *** zmiana koloru kwadratu na jasny niebieski po poprzednich obliczeniach ; opóźnienie po losowaniu i przed rozpoczęciem algorytmu result_Rectangle.Dispatcher.Invoke(() => { result_Rectangle.Fill = new SolidColorBrush(Color.FromArgb(0xFF, 0x71, 0x71, 0xFF)); }); //DEBUG DEBUG DEBUG DEBUG DEBUG if (debug) { Console.WriteLine("max ilosc Tabu listy = " + maxTabu); } if (debug) { Console.WriteLine("ilosc możliwych ruchów = " + avaMoves); } if (debug) { Console.WriteLine("max procent ruchow zakazanych = " + percMaxTabu); } if (debug) { Console.WriteLine("kadencja = " + cadence); } while (true) { if (debug) { Console.WriteLine("Iteracja: " + iteracja); } // *** reset zmiennych buforowych *** bufbestCost = 2000 * clientsCount + 1; bufbestIndex1 = -1; bufbestIndex2 = -1; bufworstCost = bestCost; bufworstIndex1 = -1; bufworstIndex2 = -1; bufBreak = false; aspPlus = false; iPlus = -1; // *** sprawdzanie wszystkich sąsiadów z ograniczeniem aspiracji plus *** for (int i = 1; i < clientsCount - 1; i++) { for (int j = i + 1; j < clientsCount - 1; j++) { if (iPlus == aspirationPlus) { bufBreak = true; break; } buf = CalcHamiltonTrackNeighLengh(tracks[0], i, j); paraTabu = false; for (int k = 0; k < tabuList.Count; k++) { if (tabuList[k][0] == i && tabuList[k][1] == j) { paraTabu = true; break; } } if (buf < bufbestCost && !paraTabu || buf < bufbestCost * aspiration) //znalezione lepsze rozwiązanie w danej interacji niz najlepsze w danej iteracji { bufbestCost = buf; bufbestIndex1 = i; bufbestIndex2 = j; if (buf < bestCost) // po znalezieniu lepszego rozwiązania od globalnego, startujemy aspirację plus { aspPlus = true; } } else if (buf > bufworstCost && tabuList.Count < maxTabu && !paraTabu) //znalezione gorsze rozwiązanie w danej interacji niz najgorsze w danej iteracji { bufworstCost = buf; bufworstIndex1 = i; bufworstIndex2 = j; } if (aspPlus) { iPlus++; } } if (bufBreak) { break; } } // *** warunek stopu danego podejscia *** if (bestCost <= bufbestCost) { break; } else // *** zamieniamy miejscami punkty najlepszej znalezionej pary, usuwamy zakazane ruchy, ktorych kadencja minęła oraz dodajemy do TabuList pare *** { bestCost = bufbestCost; Point bufPoint = tracks[0][bufbestIndex1]; tracks[0][bufbestIndex1] = tracks[0][bufbestIndex2]; tracks[0][bufbestIndex2] = bufPoint; for (int i = 0; i < tabuList.Count; i++) // pomniejszanie kadencji o 1 i usuwanie elementow z kadencją = 0 { tabuList[i][2] -= 1; if (tabuList[i][2] == 0) { tabuList.RemoveAt(i); } } if (tabuList.Count < maxTabu && bufworstCost > bufbestCost) //jesli lista Tabu nie jest pełna i znalezione najogrsze rozwiązanie w iteracji jest gorsze od najlepszego rozwiązania { int[] bufP = { bufworstIndex1, bufworstIndex2, cadence }; tabuList.Add(bufP); } } // *** rysowanie cyklu Hamiltona *** DrawX.RemoveLines(); DrawX.DrawLines(tracks); // *** wyswietlanie kosztu *** cost_textBlock.Dispatcher.Invoke(() => { cost_textBlock.Text = bestCost.ToString("F3"); }); // *** iteracja ++ *** iteracja++; iteracjaTotal++; iteration_textBlock.Dispatcher.Invoke(() => { iteration_textBlock.Text = iteracjaTotal.ToString(); }); // *** opóźnienie *** delay_checkBox.Dispatcher.Invoke(() => { if (delay_checkBox.IsChecked == true) { Thread.Sleep(500); } }); } if (bestCost < bestOfBestCost) { iteracjeBezPoprawy = aspirationPlusPlus; if (bestTracks.Count == 1) { if (debug) { Console.Write(CalcHamiltonTrackLengh(bestTracks[0]) + " != "); } } else if (bestTracks.Count != 0) { throw new Exception("Bardzo zle: " + bestTracks.Count); } bestOfBestCost = bestCost; bestCost_textBlock.Dispatcher.Invoke(() => { bestCost_textBlock.Text = bestOfBestCost.ToString("F3"); }); bestTracks = new List <List <Point> >(); bestTracks.Add(new List <Point>()); for (int i = 0; i < tracks[0].Count; i++) { bestTracks[0].Add(tracks[0][i]); } if (bestTracks.Count == 1) { if (debug) { Console.WriteLine(CalcHamiltonTrackLengh(bestTracks[0])); } } } else { iteracjeBezPoprawy--; } } // *** wyswietlenie najlepszego cyklu Hamiltona *** DrawX.RemoveLines(); DrawX.DrawLines(bestTracks); // *** kwadrat na zielono *** result_Rectangle.Dispatcher.Invoke(() => { result_Rectangle.Fill = Brushes.LightGreen; }); // *** pokrojenie cyklu Hamiltona *** double bufBestCost = 1e100; for (int i = 0; i < clientsCount; i++) //iteracja po klientach (sprawdzamy kazdy punkt startowy cięć) { List <List <Point> > bufTracks = new List <List <Point> >(); int ii = 0; //nr trasy int jj = 0; //nr punktu z najlepszego cyklu Hamiltona int bufLadunekCzesc = -1; while (true) { int bufCap = capacity; bufTracks.Add(new List <Point>()); bufTracks[ii].Add(main_station); while (true) { if (bufLadunekCzesc > -1) { bufTracks[ii].Add(bestTracks[0][jj]); bufCap -= bufLadunekCzesc; bufLadunekCzesc = -1; jj++; } else if (clientsOrders[bestTracks[0][jj].i] < bufCap) { bufTracks[ii].Add(bestTracks[0][jj]); bufCap -= clientsOrders[bestTracks[0][jj].i]; jj++; } else if (clientsOrders[bestTracks[0][jj].i] == bufCap) { bufTracks[ii].Add(bestTracks[0][jj]); bufCap = 0; jj++; break; } else { bufTracks[ii].Add(bestTracks[0][jj]); bufLadunekCzesc = bufCap; bufCap = 0; break; } if (jj == bestTracks[0].Count - 1) { break; } } bufTracks[ii].Add(main_station); if (jj == bestTracks[0].Count - 1) // minus 1 bo na końcu cyklu Hamiltona jest ten sam punkt co na początku a nie chcemy robić podwójnej dostawy do tego klienta ;) { break; } ii++; } // sprawdzenie kosztu bufTracks i jesli lepsze to przepisanie bufTracks do tracks double buf = CalcTracksLengh(bufTracks); if (bufBestCost > buf) { bufBestCost = buf; tracks = new List <List <Point> >(); for (int j = 0; j < bufTracks.Count; j++) { tracks.Add(new List <Point>()); for (int k = 0; k < bufTracks[j].Count; k++) { tracks[j].Add(bufTracks[j][k]); } } } } int buf001 = 0, buf002 = 0; for (int i = 0; i < clientsOrders.Length; i++) { buf001 += clientsOrders[i]; } for (int i = 0; i < tracks.Count; i++) { for (int j = 1; j < tracks[i].Count - 1; j++) { if (i > 0) { if (j == 1 && tracks[i - 1][tracks[i - 1].Count - 2].i != tracks[i][j].i) { buf002 += clientsOrders[tracks[i][j].i]; } else if (j > 1) { buf002 += clientsOrders[tracks[i][j].i]; } } else { buf002 += clientsOrders[tracks[i][j].i]; } } } if (buf001 != buf002) { if (debug) { Console.WriteLine(" UWAGA BŁĄD: " + buf001 + " != " + buf002); } } // *** wyswietlenie ostatecznego kosztu *** finalCost = CalcTracksLengh(tracks); finalCost_textBlock.Dispatcher.Invoke(() => { finalCost_textBlock.Text = finalCost.ToString("F3"); }); // *** rysowanie ostateczne *** DrawX.RemoveLines(); DrawX.DrawLines(tracks); // *** kwadrat na zielono *** result_Rectangle.Dispatcher.Invoke(() => { result_Rectangle.Fill = Brushes.Green; }); // *** Aktywacja wszystkich kontrolek *** mainGrid.Dispatcher.Invoke(() => { EnableAllControls(); start_Button.IsEnabled = true; }); }