Esempio n. 1
0
 private void HamiltonCycleButton_Click(object sender, RoutedEventArgs e)
 {
     DrawX.RemoveLines();
     DrawX.DrawLines(bestTracks);
 }
Esempio n. 2
0
 private void TracksButton_Click(object sender, RoutedEventArgs e)
 {
     DrawX.RemoveLines();
     DrawX.DrawLines(tracks);
 }
Esempio n. 3
0
        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;
            });
        }