Anda di halaman 1dari 16

ALGORITMA FLOYD WARSHALL PENCARIAN RUTE TERDEKAT DENGAN PHP

Mekanisme algoritma Floyd Warshall


Langkah awal yang harus dilakukan untuk menentukan shortest path dengan
menggunakan algoritma Floyd Warshal adalah :

merepresentasikan suatu graph sebagai suatu matriks bobot. Dimana bobot untuk masing-masing
edge adalah:
wij = 0 jika i = j,
= w(i,j) jika i ≠ j dan (i,j) Є E
= ∞ jika i ≠ j dan (i,j) not(E)

Format output berupa matrix n x n berjarak D = [dij] dimana dij adalah jarak dari vertex i ke j.

Langkah Kedua yaitu:

melakukan dekomposisi Floyd Warshall. Urutannya adalah sebagai berikut:

dij(k) merupakan panjang dari shortest path dari i ke j sehingga semua vertex intermediate yang
terdapat pada path (jika ada) terkumpul pada (1, 2, …, k}.

dij(0) dikumpulkan pada wij, dimana berarti kondisi tidak ada vertex intermediate

D(k) menjadi matrix n x n [dij(k)]

Tentukan dij(n) sebagai jarak dari i ke j. Jadi, yang dilakukan selanjutnya adalah menghitung D(n) ->
D(n) beranggotakan elemen-elemen dij(n)

Hitung D(k) untuk k = 0, 1, …, n.

Langkah Ketiga Yaitu

menentukan struktur shortest path. Dalam hal ini, harus dilakukan dua pengamatan terlebih dahulu
sebelum melangkah lebih jauh, yaitu:

Sebuah shortest path tidak memuat vertex yang sama sebanyak 2 kali. Sebuah path yang memuat
vertex 2 kali merupakan cycle.

Untuk sebuah shortest path dari i ke j dengan beberapa vertex intermediate pada path dipilih dari
kumpulan {1, 2, …, k), dengan 2 kemungkinan:

k bukan vertex pada path, path terpendek mempunyai panjang dij(k – 1)

k adalah vertex pada path, path terpendek mempunyai panjang dik(k – 1) + dkj(k – 1)

Setelah melakukan pengamatan di atas, kemudian dilakukan penentuan shortest path dari i ke j
yang memuat vertex k.

Shortest path tersebut memuat sebuah subpath dari i ke k dan sebuah subpath dari k ke j.

Setiap subpath hanya dapat memuat vertex intermediate pada {1, …, k-1} dan sedapat mungkin
haruslah paling pendek, beri nama panjangnya dik(k – 1) dan dkj(k – 1). Sehingga path mempunyai
panjang dik(k – 1) + dkj(k – 1)

Dengan menggabungkan dua persamaan tersebut, maka didapat :


- dij(k) = min { dij(k – 1), dik(k – 1) + dkj(k – 1)}

Langkah Keepat yaitu:

melakukan iterasi. Dimulai dari iterasi ke-0 sampai dengan n


Perhitungan yang dilakukan adalah:

Menentukan D(0) ( iterasi ke-0 )= [wij], merupakan matrix bobot

Menentukan D(k) dengan menggunakan dij(k) = min { dij(k – 1), dik(k – 1) + dkj(k – 1)}, untuk k = 1, …, n.

k bukan vertex pada path, path terpendek mempunyai panjang dij(k – 1)

k adalah vertex pada path, path terpendek mempunyai panjang dik(k – 1) + dkj(k – 1) Dimana n adalah
jumlah verteks

Hasil akhir dari algoritma Floyd Warshall adalah matriks untuk iterasi ke-n. Dari matriks ke-n ini,
dapat dilihat shortest path untuk setiap vertek pada suatu graph.

CONTOH PROGRAM FLOYD WARSHALL MENGGUNAKAN PHP DAN GOOGLE MAPS API

Alasan kenapa saya membuat aplikasi ini menggunakan bahasa program PHP
ialah karena yang pertama basic saya di php dan yang kedua menurut saya aplikasi ini
sangat cocok dibuat dengan menggunakan php karena tutorial php sangat-sangat
mudah didapat dari tutorial bahasa-bahasa program lainya.

Oke kita langsung saja, jika teman-teman ingin belajar bahasa program php teman-
teman bisa membacanya lewat link-link yang sudah saya kaitkan dibawah:

Baca Juga Artikel

PENGERTIAN PHP

Contoh yang akan saya berikan disini ialah tentang pencarian lokasi tempat sosial
terdekat serta mencari jalur terpendek dari lokasi fasilitas yang didapat.

Jadi pada aplikasi yang akan dibuat disini memiliki dua proses yaitu:

Pertama kita akan mencari lokasi sosial mana yang paling dekat dari posisi kita sekarang

Kedua jika sudah dapat fasilitas sosial yang paling dekat kemudian kita akan mencari jalur-jalur
mana saja yang harus kita lewati agar kita mendapat jalur terpendek untuk menuju fasilitas sosial
tersebut.

Buat database dan beri nama floyd_warshall. Kemudian kita buat tabel-tabel seperti dibawah ini

1. Nama Tabel : tabel_kategori_fasilitas_umum

SQL SKRIP

1
CREATE TABLE `tabel_kategori_fasilitas_umum` (
2 `kode_kategori_fasilitas_umum` varchar(20) NOT NULL,

3 `nama_kategori_fasilitas_umum` varchar(40) DEFAULT NULL,

4 `gambar` varchar(200) DEFAULT NULL,

PRIMARY KEY (`kode_kategori_fasilitas_umum`)


5
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
6
Skript diatas adalah untuk membuat tabel tabel_kategori_fasilitas_umumyang nantinya
akan digunakan untuk menampung data kategori fasilitas umum
Misalnya : kita akan menambah fasilitas seperti : Rumah sakit, Masjid, Mushallah Dll

2. Nama Tabel : tabel_lokasi_fasilitas


SQL SKRIP

1
CREATE TABLE `tabel_lokasi_fasilitas` (
2
`id` int(11) NOT NULL AUTO_INCREMENT,
3
`nama` varchar(255) NOT NULL,
4 `lat` varchar(12) NOT NULL,

5 `lon` varchar(12) NOT NULL,

6 `kode_kategori_fasilitas_umum` varchar(20) NOT NULL,

`alamat` varchar(50) NOT NULL DEFAULT 'alamat',


7
`deskripsi` varchar(100) NOT NULL DEFAULT 'deskripsi',
8
PRIMARY KEY (`id`)
9
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=latin1;
10

Skript diatas adalah untuk membuat tabel tabel_lokasi_fasilitas yang nantinya akan
digunakan untuk menampung data fasilitas umum.
tabel ini berelasi dengan tabel kategori fasilitas umum karena ditabel inilah nantinya
sebuah fasilitas umum dipecah akan masuk kekategori fasilitas apa seperti yang sudah
saya sebutkan diatas.

3. Nama Tabel : tabel_node_lokasi

SQL SKRIP

1
CREATE TABLE `tabel_node_lokasi` (
2
`id` int(20) NOT NULL AUTO_INCREMENT,
3 `id_lokasi` varchar(10) DEFAULT NULL,

4 `nama_jalan` varchar(200) DEFAULT NULL,

5 `latitude` varchar(100) DEFAULT NULL,

`longtitude` varchar(100) DEFAULT NULL,


6
PRIMARY KEY (`id`)
7
) ENGINE=MyISAM AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
8
Skript diatas adalah untuk membuat tabel tabel_node_lokasi yang nantinya akan
digunakan untuk menampung data node-node yang terdapat pada setiap fasilitas
umum.
Jadi node-node ini ialah jalur-jalur mana saja yang dapat dilalui untuk menuju suatu
fasilitas umum, jalur-jalur inilah yang harus dikumpulkan semua.

Selanjutnya jika sudah selesai membuat tabel-tabel yang diperlukan kemudian


sekarang kita masuk ketahap skrip php. Disini saya menggunakan sebuah class
FloydWarshall yang dibuat oleh anne Mikkonen, class ini dibuat pada tahun 2011, class
FloydWarshall ini telah banyak digunakan pengembang untuk mencari rute terdekat,
dan hasilnyapun sangat akurat tanpa ada bug segikitpun.

Copy dan pasti skript dibawah kemudian simpan dan beri nama fw.class.php

PHP SCRIPT

1 <?php

2 /**

* @package FloydWarshall
3
* @author Janne Mikkonen
4
* @date $Date: 2011/06/13 05:10:48 $
5
* @version $Revision: 1.1 $
6
* @license GNU General Public License, version 2 <a class="vglnk"
7 href="http://www.opensource.org/licenses/GPL-2.0" rel="nofollow"><span>http</span>

8 <span>://</span><span>www</span><span>.</span><span>opensource</span>

9 <span>.</span><span>org</span><span>/</span><span>licenses</span>

10 <span>/</span><span>GPL</span><span>-</span><span>2</span><span>.</span>
<span>0</span></a>
11
**/
12

13
error_reporting(E_STRICT);
14
define('INFINITE', pow(2, (20 * 8 - 2)-1));
15

16
class FloydWarshall {
17

18 /**

19 * Distances array
20 * @var array

*/
21
private $dist = array(array());
22
/**
23
* Predecessor array
24
* @var array
25
*/
26 private $pred = array(array());

27 /**

28 * Weights array

29 * @var array

*/
30
private $weights;
31
/**
32
* Number of nodes
33
* @var integer
34 */

35 private $nodes;

36 /**

37 * Node names array

* @var array
38
*/
39
private $nodenames;
40
/**
41
* Temporary table for various stuff.
42 * @var array

43 */

44 private $tmp = array();

45

46 /**

* Constructor
47
* @param array $graph Graph matrice.
48
* @param array $nodenames Node names as an array.
49
*/
50
public function __construct($graph, $nodenames='') {
51

52 $this->weights = $graph;
53 $this->nodes = count($this->weights);

if ( ! empty($nodenames) && $this->nodes == count($nodenames) ) {


54
$this->nodenames = $nodenames;
55
}
56
$this->__floydwarshall();
57

58
}
59

60
/**
61 * The actual PHP implementation of Floyd-Warshall algorithm.

62 * @return void

63 */

64 private function __floydwarshall () {

65
// Initialization
66
for ( $i = 0; $i < $this->nodes; $i++ ) {
67
for ( $j = 0; $j < $this->nodes; $j++ ) {
68
if ( $i == $j ) {
69
$this->dist[$i][$j] = 0;
70 } else if ( $this->weights[$i][$j] > 0 ) {

71 $this->dist[$i][$j] = $this->weights[$i][$j];

72 } else {

73 $this->dist[$i][$j] = INFINITE;

}
74
$this->pred[$i][$j] = $i;
75
}
76
}
77

78
// Algorithm
79

80 for ( $k = 0; $k < $this->nodes; $k++ ) {

81 for ( $i = 0; $i < $this->nodes; $i++ ) {

82 for ( $j = 0; $j < $this->nodes; $j++ ) {

83 if ($this->dist[$i][$j] > ($this->dist[$i][$k] + $this->dist[$k][$j]

$this->dist[$i][$j] = $this->dist[$i][$k] + $this->dist[$k][$j];


84
$this->pred[$i][$j] = $this->pred[$k][$j];
85
86 //echo "<br>".$this->pred[$k][$j];

}
87
}
88
}
89
}
90

91
}
92

93
/**
94 * Private method to get the path.

95 *

96 * Get graph path from predecessor matrice.

97 * @param integer $i

* @param integer $j
98
* @return void
99
*/
100
private function __get_path($i, $j) {
101

102
if ( $i != $j ) {
103 $this->__get_path($i, $this->pred[$i][$j]);

104 }

105 array_push($this->tmp, $j);

106 }

107
/**
108
* Public function to access get path information.
109
*
110
* @param ingeger $i Starting node.
111
* @param integer $j End node.
112 * @return array Return array of nodes.

113 */

114 public function get_path($i, $j) {

115 $this->__get_path($i, $j);

return $this->tmp;
116
}
117

118
119 /**

* Print nodes from a and b.


120
* @param ingeger $i Starting node.
121
* @param integer $j End node.
122
* @return void
123
*/
124
public function print_path($i, $j) {
125

126 if ( $i != $j ) {

127 $this->print_path($i, $this->pred[$i][$j]);

128 }

129

130 if (! empty($this->nodenames) ) {

print($this->nodenames[$j]) . ' ';


131
} else {
132
print($j) . ' ';
133
}
134

135
}
136

137 /**

138 * Get total cost (distance) between point a to b.

139 *

140 * @param integer $i

* @param ingeger $j
141
* @return array Returns an array of costs.
142
*/
143
public function get_distance($i, $j) {
144
return $this->dist[$i][$j];
145 }

146

147 /************************************************************

148 *** DEBUG FUNCTIONS ***

149 *** - print_graph ***

*** - print_dist ***


150
*** - print_pred ***
151
152 *************************************************************/

153
/**
154
* Print out the original Graph matrice.
155
* @return void
156
*/
157
public function print_graph () {
158

159

160
//if ( empty($_SERVER['argv']) ) {
161 echo '<strong>Graph</strong><br>';

162 echo '';

163 if (! empty($this->nodenames) ) {

164 echo '';

echo '';
165
for ($n = 0; $n < $this->nodes; $n++) {
166
echo '';
167
}
168
}
169 echo '';

170 for ($i = 0; $i < $this->nodes; $i++) {

171 echo '';

172 if (! empty($this->nodenames) ) {

echo '';
173
}
174
for ($j = 0; $j < $this->nodes; $j++) {
175
echo '';
176
}
177 echo '';

178 }

179 echo '<table border="1" cellpadding="4" width="100%"><tbody><tr><td> </td><t

180 $this->nodenames[$n] .

'</strong></td></tr><tr><td width="15" align="center"><strong>'


181
$this->nodenames[$i] .
182
'</strong></td><td width="15" align="center">' .
183
$this->weights[$i][$j] . '</td></tr></tbody></table><br>';
184
185 // } else {

186
//}
187
}
188

189
/**
190
* Print out distances matrice.
191
* @return void
192
*/
193 public function print_dist () {

194

195 //if ( empty($_SERVER['argv']) ) {

196 echo '<strong>Distances</strong><br>';

197 echo '';

if (! empty($this->nodenames) ) {
198
echo '';
199
echo '';
200
for ($n = 0; $n < $this->nodes; $n++) {
201
echo '';
202 }

203 }

204 echo '';

205 for ($i = 0; $i < $this->nodes; $i++) {

echo '';
206
if (! empty($this->nodenames) ) {
207
echo '';
208
}
209
for ($j = 0; $j < $this->nodes; $j++) {
210 echo '';

211 }

212 echo '';

213 }

echo '<table border="1" cellpadding="4" width="100%"><tbody><tr><td> </td><t


214
$this->nodenames[$n] .
215
'</strong></td></tr><tr><td width="15" align="center"><strong>'
216
$this->nodenames[$i] .
217
'</strong></td><td width="15" align="center">' .
218 $this->dist[$i][$j] . '</td></tr></tbody></table><br>';

//} else {
219
// echo "cmd line not yet completed!\n";
220
//}
221

222
}
223

224
/**
225
* Print out predecessors matrice.
226 * @return void

227 */

228 public function print_pred () {

229

230 //if ( empty($_SERVER['argv']) ) {

echo '<strong>Predecessors</strong><br>';
231
echo '';
232
if (! empty($this->nodenames) ) {
233
echo '';
234
echo '';
235 for ($n = 0; $n < $this->nodes; $n++) {

236 echo '';

237 }

238 }

echo '';
239
for ($i = 0; $i < $this->nodes; $i++) {
240
echo '';
241
if (! empty($this->nodenames) ) {
242
echo '';
243 }

244 for ($j = 0; $j < $this->nodes; $j++) {

245 echo '';

246 }

echo '';
247
}
248
echo '<table border="1" cellpadding="4" width="100%"><tbody><tr><td> </td><t
249
$this->nodenames[$n] .
250
'</strong></td></tr><tr><td width="15" align="center"><strong>'
251 $this->nodenames[$i] .

'</strong></td><td width="15" align="center">' .


252
$this->pred[$i][$j] . '</td></tr></tbody></table><br>';
253
// } else {
254
// echo "cmd line not yet completed!\n";
255
//}
256

257
}
258

259} // End of class

260?>

Kemudian copy dan paste skript dibawah dan simpan dengan nama index.php

PHP SKRIP

1 <?php

echo "<table border="1" width="100%"><tbody><tr><td>";


2
$nama_jalan[] = "Start";
3
$lat[] = $_GET['x'];
4
$long[] = $_GET['y'];
5
echo "</td><td>Start";
6 $data = mysql_query("SELECT * from tabel_node_lokasi where id_lokasi='".$idlokasi."'

7 while ($d = mysql_fetch_array($data)) {

8 echo "</td><td>$d[nama_jalan]";

9 $nama_jalan[] = $d['nama_jalan'];

$lat[] = $d['latitude'];
10
$long[] = $d['longtitude'];
11
}
12
$lokasi =mysql_fetch_array(mysql_query("SELECT * from tabel_lokasi_fasilitas where i
13
echo "</td><td>$lokasi[nama]";
14 $lat[] = $lokasi['lat'];

15 $long[] = $lokasi['lon'];
16 $nama_jalan[] = $lokasi['nama'];

17
$jlhsas = count($nama_jalan)-1;
18
$n = 0;
19
foreach ($nama_jalan as $key1 => $value1) {
20
echo "</td></tr><tr><td>$value1";
21
foreach ($nama_jalan as $key => $value) {
22
//include "distans.php";
23 $nama[$key1][$key] = $value1.'-'.$value;

24

25

26 if ($value == $value1) {

27 $dataf = 0;

28 }

29
if ($key1>$key) {
30
if ($key == 0 and $key1 == $jlhsas) {
31
$dataf = "∞";
32
}
33
else{
34
$asala = $lat[$key].",".$long[$key];
35 $tujuana = $lat[$key1].",".$long[$key1];

36

37 include "distans.php";

38 }

39

40 echo "</td><td align="right">".$dataf;//.' >'.$key.','.$key1;//.'='.$nama[$k

}
41
elseif ($key1 == $key) {
42
$dataf=0;
43
echo "</td><td align="right">".$dataf;
44
}
45 else{

46 if ($key1 == 0 and $key == $jlhsas) {

47 $dataf = "∞";

48 }
49 else{

50 $asala = $lat[$key1].",".$long[$key1];

51 $tujuana = $lat[$key].",".$long[$key];

52
include "distans.php";
53
}
54

55
echo "</td><td align="right">".$dataf;//. ' > '.$key1.','.$key;//.'='.$nama[
56
}
57

58
$graph[$key1][] = str_replace(" km", "", str_replace(",", ".", $dataf));
59 }

60 $nodes[] = $value1;

61 $n++;

62 }

echo "</td></tr></tbody></table>";
63
$jlss = count($nama_jalan)-1;
64
echo "<br><br>";
65
include('fw_example.php');
66
?>

Sekript diatas dibuat untuk membentuk data menjadi array, data ini lah yang nantinya
akan diperoses dengan menggunakan fw.class.php yang sudah kita buat diatas.
Karena disini saya menggunakan google maps untuk mencari titik kordinat suatu lokasi,
maka disini saya tambah satu file untuk mencari jarak antara lokasi satu dengan lokasi
yang lainya.

Copy dan paste skript dibawah kemudian simpan dengan nama distans.php

PHP SKRIP

1 <?php

3 //!empty($_POST['tujuan']) ? urlencode($_POST['tujuan']) : null;

5 $urlApia = "<a class="vglnk" href="https://maps.googleapis.com/maps/api/distancematri


rel="nofollow"><span>https</span><span>://</span><span>maps</span><span>.</span><span>goo
6 span><span>?</span><span>origins</span><span>=".$</span><span>asala</span><span>."&</span

7
8 $resulta = file_get_contents($urlApia);

1 $data15 = json_decode($resulta, true);


0

1 $dataf=$data15['rows'][0]['elements'][0]['distance']['text'];
1
?>
1
2

Yang terakhir copy dan paste skript dibawah kemudian simpan dengan
nama fw_example.php

PHP SKRIP

1 <?php

3 include('fw.class.php');

4
//$graph = array(array(0,5,8,6),
5
// array(5,0,3,1),
6
// array(8,3,0,1),
7
// array(6,1,1,0));
8
// array(0,0,10,0,0,4),
9 // array(0,0,17,20,0,0));

10 //$nodes = array("a", "b", "c", "d");

11

12 $fw = new FloydWarshall($graph, $nodes);

13 //$fw->print_path(0,2);

$fw->print_graph();
14
$fw->print_dist();
15
//$fw->print_pred();
16

17
$sp = $fw->get_path(0,$jlss);
18

19
echo 'Ruter Terdekat Dari Star Ke '.$nodes[$jlss].' Adalah: <strong>';
20 $jl = count($sp);

21 $r=1;

22 foreach ($sp as $value) {


23 echo $nodes[$value];

if ($r == $jl) {
24

25
}
26
else{
27
echo ' => ';
28
}
29
$r++;
30

31 }

32 echo ' | Dengan Jarak Tempu ';

33 $menit = round(($fw->get_distance(0,$jlss)/40)*60,0);

34 print_r($fw->get_distance(0,$jlss));

echo " km yaitu $menit</strong>";


35
?>

Skript diatas adalah akhir dari proses, setelah data dibentuk kedalam graph pada file
kemudian data dimasukan kedalam class fw.class.phpdan selanjutnya diproses.

Anda mungkin juga menyukai