Masalah Penjual Perjalanan di Jawa

1. Pengenalan

Dalam tutorial ini, kita akan belajar mengenai algoritma Simulasi Annealing dan kita akan menunjukkan contoh pelaksanaan berdasarkan Traveling Salesman Problem (TSP).

2. Penyepuhan Simulasi

Algoritma Simulasi Annealing adalah heuristik untuk menyelesaikan masalah dengan ruang carian yang besar.

Inspirasi dan nama berasal dari penyepuhlindapan dalam metalurgi; ia adalah teknik yang melibatkan pemanasan dan penyejukan terkawal bahan

Secara amnya, Simulated Annealing menurunkan kebarangkalian untuk menerima penyelesaian yang lebih buruk ketika menjelajahi ruang penyelesaian dan menurunkan suhu sistem. Animasi berikut menunjukkan mekanisme mencari penyelesaian terbaik dengan algoritma Simulasi Annealing:

Seperti yang kita amati, algoritma menggunakan rangkaian penyelesaian yang lebih luas dengan suhu tinggi sistem, mencari optimum global. Sambil menurunkan suhu, julat pencarian menjadi lebih kecil, hingga mencapai optimum global.

Algoritma mempunyai beberapa parameter untuk digunakan:

  • bilangan lelaran - keadaan berhenti untuk simulasi
  • suhu awal - tenaga permulaan sistem
  • parameter kadar penyejukan - peratusan di mana kita mengurangkan suhu sistem
  • suhu minimum - keadaan berhenti pilihan
  • masa simulasi - keadaan berhenti pilihan

Nilai parameter tersebut mesti dipilih dengan teliti - kerana ia mungkin mempunyai pengaruh yang signifikan terhadap prestasi proses.

3. Masalah Penjual Perjalanan

The Traveling Salesman Problem (TSP) adalah masalah pengoptimuman sains komputer yang paling terkenal di dunia moden.

Dengan kata mudah, ini adalah masalah mencari jalan optimum antara nod dalam grafik. Jumlah jarak perjalanan boleh menjadi salah satu kriteria pengoptimuman. Untuk maklumat lebih lanjut mengenai TSP sila lihat di sini.

4. Model Java

Untuk menyelesaikan masalah TSP, kami memerlukan dua kelas model, iaitu City dan Travel . Pada yang pertama, kami akan menyimpan koordinat nod dalam grafik:

@Data public class City { private int x; private int y; public City() { this.x = (int) (Math.random() * 500); this.y = (int) (Math.random() * 500); } public double distanceToCity(City city) { int x = Math.abs(getX() - city.getX()); int y = Math.abs(getY() - city.getY()); return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); } }

Pembina kelas Bandar membolehkan kita membuat lokasi bandar secara rawak. The distanceToCity (..) logik bertanggungjawab untuk pengiraan mengenai jarak antara bandar-bandar.

Kod berikut bertanggungjawab untuk memodelkan lawatan jurujual yang bergerak. Mari mulakan dengan menghasilkan susunan awal bandar dalam perjalanan:

public void generateInitialTravel() { if (travel.isEmpty()) new Travel(10); Collections.shuffle(travel); }

Selain menghasilkan pesanan awal, kami memerlukan kaedah untuk menukar dua bandar secara rawak dalam urutan perjalanan. Kami akan menggunakannya untuk mencari penyelesaian yang lebih baik di dalam algoritma Simulasi Annealing:

public void swapCities() { int a = generateRandomIndex(); int b = generateRandomIndex(); previousTravel = travel; City x = travel.get(a); City y = travel.get(b); travel.set(a, y); travel.set(b, x); }

Selain itu, kami memerlukan kaedah untuk mengembalikan penjanaan pertukaran pada langkah sebelumnya, jika penyelesaian baru tidak akan diterima oleh algoritma kami:

public void revertSwap() { travel = previousTravel; }

Kaedah terakhir yang ingin kita lindungi adalah pengiraan jumlah jarak perjalanan, yang akan digunakan sebagai kriteria pengoptimuman:

public int getDistance() { int distance = 0; for (int index = 0; index < travel.size(); index++) { City starting = getCity(index); City destination; if (index + 1 < travel.size()) { destination = getCity(index + 1); } else { destination = getCity(0); } distance += starting.distanceToCity(destination); } return distance; }

Sekarang, mari kita fokus pada bahagian utama, pelaksanaan algoritma Simulasi Annealing.

5. Pelaksanaan Penyepuhan Simulasi

Dalam implementasi Simulasi Annealing berikut, kami akan menyelesaikan masalah TSP. Sekadar peringatan ringkas, objektifnya adalah untuk mencari jarak terpendek untuk melancong ke semua bandar.

Dalam usaha untuk memulakan proses, kita perlu menyediakan tiga parameter utama iaitu startingTemperature , numberOfIterations dan coolingRate :

public double simulateAnnealing(double startingTemperature, int numberOfIterations, double coolingRate) { double t = startingTemperature; travel.generateInitialTravel(); double bestDistance = travel.getDistance(); Travel currentSolution = travel; // ... }

Sebelum permulaan simulasi, kami menghasilkan susunan awal (rawak) bandar dan mengira jumlah jarak perjalanan. Oleh kerana ini adalah jarak yang dikira pertama, kami menyimpannya di dalam pemboleh ubah Jarak terbaik , bersama dengan Penyelesaian semasa.

Pada langkah seterusnya kita memulakan gelung simulasi utama:

for (int i = 0; i  0.1) { //... } else { continue; } }

Gelung akan bertahan sebilangan lelaran yang kami tentukan. Lebih-lebih lagi, kami menambahkan syarat untuk menghentikan simulasi jika suhu akan lebih rendah atau sama dengan 0.1. Ini akan membolehkan kita menjimatkan masa simulasi, kerana dengan suhu rendah perbezaan pengoptimuman hampir tidak dapat dilihat.

Mari lihat logik utama algoritma Simulasi Annealing:

currentSolution.swapCities(); double currentDistance = currentSolution.getDistance(); if (currentDistance < bestDistance) { bestDistance = currentDistance; } else if (Math.exp((bestDistance - currentDistance) / t) < Math.random()) { currentSolution.revertSwap(); }

Dalam setiap langkah simulasi, kami menukar dua bandar secara rawak mengikut urutan perjalanan.

Selanjutnya, kami mengira Jarak semasa . Sekiranya Jarak semasa yang baru dikira lebih rendah daripada Jarak terbaik , kami menyimpannya sebagai yang terbaik.

Jika tidak, kita periksa sama ada fungsi Boltzmann taburan kebarangkalian lebih rendah daripada nilai yang dipilih secara rawak dalam julat 0-1. Sekiranya ya, kami akan menukar pertukaran bandar. Sekiranya tidak, kami menjaga susunan bandar-bandar yang baru, kerana dapat membantu kami menghindari minima setempat.

Akhirnya, dalam setiap langkah simulasi, kami mengurangkan suhu dengan penyejukan yang disediakan .

t *= coolingRate;

Selepas simulasi, kami mengembalikan penyelesaian terbaik yang kami dapati menggunakan Simulated Annealing.

Please note the few tips on how to choose the best simulation parameters:

  • for small solution spaces it's better to lower the starting temperature and increase the cooling rate, as it will reduce the simulation time, without lose of quality
  • for bigger solution spaces please choose the higher starting temperature and small cooling rate, as there will be more local minima
  • always provide enough time to simulate from the high to low temperature of the system

Don't forget to spend some time on the algorithm tuning with the smaller problem instance, before you start the main simulations, as it will improve final results. The tuning of the Simulated Annealing algorithm was shown for example in this article.

6. Conclusion

Dalam tutorial ini cepat kita dapat belajar tentang simulasi Annealing algoritma dan kita menyelesaikan Salesman Perjalanan Masalah . Ini diharapkan dapat menunjukkan betapa bergunanya algoritma mudah ini, apabila diterapkan pada jenis masalah pengoptimuman tertentu.

Pelaksanaan penuh artikel ini boleh didapati di GitHub.