Oleh :
10110241 Carsadi
10110261 Dodi Permana
Kelas IF6/VI
adalah
bagaimana
salesman
tersebut
dapat
mengatur
rute
perjalanannya sehingga jarak yang ditempuhnya merupakan rute yang optimum yaitu
jarak minimum terbaik.
Banyak metode yang dapat dipakai untuk menyelesaikan TSP sepertiHillClimbing
Method, Ant Colony System dan Dynamic Programming. TSP ini dapat diselesaikan
dengan cepat walaupun dengan menggunakan algoritma brute force sekalipun, tetapi
hanya jika kota-kota yang akandikunjunginya sedikit. Namun, jika kota-kota yang akan
dikunjungi banyak, maka algoritma seperti Brute Force tidaklah menjadi pilihan lagi.
Sebab, Algoritma Brute Force sendiri memiliki kompleksitas O(n!).
Metode lain yang dapat dipakai untuk menyelesaikan TSP adalah algoritma
genetika. Algoritma genetika merupakan sebuah algoritma yang meniru cara kerja
proses genetika pada makhluk hidup, dimana terdapat proses seleksi, rekombinasi dan
mutasi untuk mendapatkan kromosom terbaik pada suatu generasi.
Algoritma Genetika sebagai cabang dari Algoritma Evolusi didasarkan pada proses
genetik yang ada dalam makhluk hidup; yaitu perkembangan generasi dalam sebuah
populasi yang alami, secara lambat laun mengikuti prinsip seleksi alam atau "siapa yang
kuat, dia yang bertahan (survive)". Peletak prinsip dasar sekaligus pencipta algoritma
genetika adalah John Holland.
Algoritma genetika menggunakan analogi secara langsung dari kebiasaan yang
alami yaitu seleksi alam. Algoritma ini bekerja dengan sebuah populasi yang terdiri dari
individu-individu, yang masing-masing individu mempresentasikan sebuah solusi yang
mungkin bagi persoalan yang ada. Dalam kaitan ini, individu dilambangkan dengan
sebuah nilai fitness yang akan digunakan untuk mencari solusi terbaik dari persoalan
yang ada.
dengan
menggunakan
pembangkitan
random-walk.
d. Menentukan proses seleksi yang akan digunakan.
acak
seperti
Populasi Awal
Evaluasi fitness
Seleksi Individu
Populasi Baru
ReproduksiCross-OverDan Mutasi
satu
diangkat.
solusi
yang
mungkin
dari
permasalahan
yang
2. PENGENALAN SISTEM
1
Proses
A. Teknik Pengkodean
Teknik pengkodean adalah bagaimana mengkodekan gen dari kromosom,
dimana gen merupakan bagian dari kromosom.
3. ANALISIS
3.1. Pengkodean
dilakukan
pengkodeantersebut
dalam
antara
algoritma
lain
adalah
teknikpengkodean
genetika. Beberapateknik-teknik
pengkodean biner,
pengkodean
Salesman
yang
mewakili
posisi
dalam sebuahurutan.
Pada
berartisalesmen
3.3.
Seleksi
Seleksi akan menentukan individu-individu mana saja yang akan dipilih untuk
i
yi 1 )2
(
2
( ix i1) +
h=
Sehingga
nilai
kromosom-kromosom
pada
contoh
populasi
awal
yang
Kromosom[2]
FAB | E C G D
D E A| C G F B
FAB | C G B F
D E A| E C G D
Pada TSP, setiap kota hanya bisa dikunjungi satu kali dalam sebuah tour, sedangkan
pada hasil cross over di atas, child 1 mengunjungi F dab B sebanyak dua kali. Untuk
mengatasi hal tersebut proses cross over dapat diimplementasikan dengan skema order
crossover. Pada skema ini, satu bagian kromosom dipertukarkan dengan tetap menjaga
urutan kota yang bukan bagian dari kromosom tersebut.Hal tersebut dilakukan dengan
membangkitkan bilanganacak antara 1 sampai dengan panjang kromosom-1. Pada
contoh di atas bilangan acaknya adalah antara 1 sampai 6. Misal diperoleh bilangan
acak 1, maka gen yang ke-1 pada kromosom parent pertama diambil kemudian ditukar
dengan gen pada kromosom parentkedua yang belum ada pada parent pertama dengan
tetap memperhatikan urutannya.
Contoh
3.5. Mutasi
Proses mutasi sangatlah sederhana. Untuk semua gen yang ada, jika bilangan
random yang dibangkitkan kurang dari probabilitas permutasi yang ditentukan maka
ubah gen tersebut menjadi nilai kebalikannya. Program simulasi ini menggunakan
swapping mutation sehingga proses mutasinya dilakukan dengan cara melakukan
pertukaran tempat node secara acak.
4. IMPLEMENTASI
if (Halt)
{
break; // GUI has requested we exit.
}
foundNewBestTour = makeChildren(groupSize, mutation);
if (foundNewBestTour)
{
displayTour(population.BestTour, generation, false);
}
}
displayTour(population.BestTour, generation, true);
}
Skema pengkodean
<?xmlversion="1.0"encoding="utf-8" ?>
<CityList>
<CityX="160"Y="370"/>
<CityX="121"Y="132"/>
<CityX="58"Y="234"/>
<CityX="41"Y="213"/>
<CityX="143"Y="86"/>
<CityX="312"Y="176"/>
<CityX="121"Y="264"/>
<CityX="231"Y="366"/>
<CityX="380"Y="62"/>
<CityX="202"Y="260"/>
<CityX="241"Y="12"/>
<CityX="23"Y="356"/>
<CityX="43"Y="317"/>
<CityX="175"Y="134"/>
<CityX="260"Y="125"/>
<CityX="277"Y="386"/>
<CityX="312"Y="153"/>
<CityX="23"Y="256"/>
<CityX="313"Y="297"/>
<CityX="131"Y="96"/>
<CityX="87"Y="67"/>
<CityX="249"Y="283"/>
<CityX="307"Y="234"/>
<CityX="159"Y="167"/>
<CityX="285"Y="123"/>
<CityX="12"Y="34"/>
<CityX="85"Y="356"/>
<CityX="387"Y="125"/>
<CityX="135"Y="268"/>
<CityX="185"Y="345"/>
<CityX="75"Y="314"/>
<CityX="275"Y="45"/>
<CityX="313"Y="78"/>
<CityX="110"Y="67"/>
<CityX="256"Y="215"/>
<CityX="314"Y="164"/>
<CityX="342"Y="186"/>
<CityX="331"Y="214"/>
<CityX="141"Y="275"/>
<CityX="67"Y="389"/>
</CityList>
///<summary>
/// Create the initial set of random tours.
///</summary>
///<param name="populationSize">Number of tours to create.</param>
///<param name="cityList">The list of cities in this tour.</param>
///<param name="rand">Random number generator. We pass around the same random
number generator, so that results between runs are consistent.</param>
///<param name="chanceToUseCloseCity">The odds (out of 100) that a city that is known
to be close will be used in any given link.</param>
publicvoid CreateRandomPopulation(int populationSize, Cities cityList, Random rand, int
chanceToUseCloseCity)
{
int firstCity, lastCity, nextCity;
for (int tourCount = 0; tourCount < populationSize; tourCount++)
{
Tour tour = newTour(cityList.Count);
// Create a starting point for this tour
firstCity = rand.Next(cityList.Count);
lastCity = firstCity;
for (int city = 0; city < cityList.Count - 1; city++)
{
do
{
// Keep picking random cities for the next city, until we find one we haven't been to.
if ((rand.Next(100) < chanceToUseCloseCity) && ( cityList[city].CloseCities.Count > 0 ))
{
// 75% chance will will pick a city that is close to this one
nextCity =
cityList[city].CloseCities[rand.Next(cityList[city].CloseCities.Count)];
}
else
{
// Otherwise, pick a completely random city.
nextCity = rand.Next(cityList.Count);
}
// Make sure we haven't been here, and make sure it isn't where we are at now.
} while ((tour[nextCity].Connection2 != -1) || (nextCity == lastCity));
// When going from city A to B, [1] on A = B and [1] on city B = A
tour[lastCity].Connection2 = nextCity;
tour[nextCity].Connection1 = lastCity;
lastCity = nextCity;
}
// Connect the last 2 cities.
tour[lastCity].Connection2 = firstCity;
tour[firstCity].Connection1 = lastCity;
tour.DetermineFitness(cityList);
Add(tour);
if ((bestTour == null) || (tour.Fitness < bestTour.Fitness))
{
BestTour = tour;
}
}
population[childPosition] = Tour.Crossover(population[tourGroup[0]],
population[tourGroup[1]], cityList, rand);
if (rand.Next(100) < mutation)
{
population[childPosition].Mutate(rand);
}
population[childPosition].DetermineFitness(cityList);
// now see if the first new tour has the best fitness
if (population[childPosition].Fitness < population.BestTour.Fitness)
{
population.BestTour = population[childPosition];
foundNewBestTour = true;
}
// take the best 2 tours (opposite order), do crossover, and replace the 2nd worst tour with it
childPosition = tourGroup[groupSize - 2];
population[childPosition] = Tour.Crossover(population[tourGroup[1]],
population[tourGroup[0]], cityList, rand);
if (rand.Next(100) < mutation)
{
population[childPosition].Mutate(rand);
}
population[childPosition].DetermineFitness(cityList);
// now see if the second new tour has the best fitness
if (population[childPosition].Fitness < population.BestTour.Fitness)
{
population.BestTour = population[childPosition];
foundNewBestTour = true;
}
return foundNewBestTour;
}
Cross over
publicstaticTour Crossover(Tour parent1, Tour parent2, Cities cityList, Random rand)
{
Tour child = newTour(cityList.Count);
// the new tour we are making
int[] cityUsage = newint[cityList.Count]; // how many links 0-2 that connect to this city
int city;
// for loop variable
int nextCity;
// the other city in this link
for (city = 0; city < cityList.Count; city++)
{
cityUsage[city] = 0;
}
// Take all links that both parents agree on and put them in the child
for (city = 0; city < cityList.Count; city++)
{
if (cityUsage[city] < 2)
{
if (parent1[city].Connection1 == parent2[city].Connection1)
{
nextCity = parent1[city].Connection1;
if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
{
}
}
if (parent1[city].Connection2 == parent2[city].Connection2)
{
nextCity = parent1[city].Connection2;
if (testConnectionValid(child, cityList, cityUsage, city, nextCity))
{
joinCities(child, cityUsage, city, nextCity);
if
if
if
if
}
}
(parent1[city].Connection1 == parent2[city].Connection2)
{
nextCity = parent1[city].Connection1;
(testConnectionValid(child, cityList, cityUsage, city, nextCity))
{
joinCities(child, cityUsage, city, nextCity);
}
}
(parent1[city].Connection2 == parent2[city].Connection1)
{
nextCity = parent1[city].Connection2;
(testConnectionValid(child, cityList, cityUsage, city, nextCity))
{
joinCities(child, cityUsage, city, nextCity);
}
}
}
}
// The parents don't agree on whats left, so we will alternate between using
// links from parent 1 and then parent 2.
for (city = 0; city < cityList.Count; city++)
{
if (cityUsage[city] < 2)
{
if (city % 2 == 1) // we prefer to use parent 1 on odd cities
{
nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
if (nextCity == -1) // but if thats not possible we still go with parent 2
{
nextCity = findNextCity(parent2, child, cityList, cityUsage, city); ;
}
}
else// use parent 2 instead
{
nextCity = findNextCity(parent2, child, cityList, cityUsage, city);
if (nextCity == -1)
{
nextCity = findNextCity(parent1, child, cityList, cityUsage, city);
}
}
if (nextCity != -1)
{
joinCities(child, cityUsage, city, nextCity);
}
// Remaining links must be completely random.
// Parent's links would cause multiple disconnected loops.
for (city = 0; city < cityList.Count; city++)
{
while (cityUsage[city] < 2)
{
do
{
nextCity = rand.Next(cityList.Count); // pick a random city, until we find one
we can link to
} while (!testConnectionValid(child, cityList, cityUsage, city, nextCity));
}
}
return child;
}
Mutasi
///<summary>
/// Randomly change one of the links in this tour.
///</summary>
///<param name="rand">Random number generator. We pass around the same random
number generator, so that results between runs are consistent.</param>
publicvoid Mutate(Random rand)
{
int cityNumber = rand.Next(this.Count);
Link link = this[cityNumber];
int tmpCityNumber;
// Find which 2 cities connect to cityNumber, and then connect them directly
if (this[link.Connection1].Connection1 == cityNumber) // Conn 1 on Conn 1 link points
back to us.
{
if (this[link.Connection2].Connection1 == cityNumber)// Conn 1 on Conn 2 link points back
to us.
{
tmpCityNumber = link.Connection2;
this[link.Connection2].Connection1 =link.Connection1;
this[link.Connection1].Connection1 = tmpCityNumber;
}
else// Conn 2 on Conn 2 link points back to us.
{
tmpCityNumber = link.Connection2;
this[link.Connection2].Connection2 = link.Connection1;
this[link.Connection1].Connection1 = tmpCityNumber;
}
}
else// Conn 2 on Conn 1 link points back to us.
{
if (this[link.Connection2].Connection1 == cityNumber)// Conn 1 on Conn 2 link points back
to us.
{
tmpCityNumber = link.Connection2;
this[link.Connection2].Connection1 = link.Connection1;
this[link.Connection1].Connection2 = tmpCityNumber;
}
else// Conn 2 on Conn 2 link points back to us.
{
tmpCityNumber = link.Connection2;
this[link.Connection2].Connection2 = link.Connection1;
this[link.Connection1].Connection2 = tmpCityNumber;
}
}
int replaceCityNumber = -1;
do
{
replaceCityNumber = rand.Next(this.Count);
}
while (replaceCityNumber == cityNumber);
Link replaceLink = this[replaceCityNumber];
// Now we have to reinsert that city back into the tour at a random location
tmpCityNumber = replaceLink.Connection2;
link.Connection2 = replaceLink.Connection2;
link.Connection1 = replaceCityNumber;
replaceLink.Connection2 = cityNumber;
if (this[tmpCityNumber].Connection1 == replaceCityNumber)
{
this[tmpCityNumber].Connection1 = cityNumber;
}
else
{
this[tmpCityNumber].Connection2 = cityNumber;
}
}
6. Referensi
[1] Fitrah, A., Zaky, A., & Fitrasani. (2006). PENERAPAN ALGORITMA
GENETIKA PADA PERSOALAN .
[2] Lalena, M. (n.d.). Retrieved 11 18, 2013, from http://www.lalena.com/
[3] Lukas, S., Anwar, T., & Yuliani, W. (2005). PENERAPAN ALGORITMA
GENETIKA UNTUK TRAVELING SALESMAN. 1-5.
[4] Informatika.Rerieved
11
18,2013,
www.informatika.web.id/algoritma-genetik.htm
7. Lampiran
from