No Citra (.jpg) No
LAMPIRAN A DATA SAMPEL
1. Data Latih
1
Palmprint_April (20)
Palmprint_April (16)
17
18
19
20 Palmprint_April (17)
Palmprint_April (18)
Palmprint_April (19)
21
16 Palmprint_April (13) Palmprint_April (14)
22
23
24 Palmprint_Bobby
(1) Palmprint_Bobby
(2) Palmprint_Bobby
(3) Palmprint_Bobby
(4)
Palmprint_April (15)
15
2
Palmprint_April (8)
3
4 Palmprint_April (1) Palmprint_April (2) Palmprint_April (3) Palmprint_April (4)
5
6
7
8 Palmprint_April (5) Palmprint_April (6)
Palmprint_April (7)
9
No Citra (.jpg) No Citra (.jpg) No Citra (.jpg) No Citra (.jpg)
10
11
12 Palmprint_April
(9) Palmprint_April
(10) Palmprint_April
(11) Palmprint_April
(12)
13
14
25
47
(20)
41
42
43
44 Palmprint_Cici
(1) Palmprint_Cici
(2) Palmprint_Cici
(3) Palmprint_Cici
(4)
45
46
48 Palmprint_Cici
(18) Palmprint_Bobby
(5) Palmprint_Cici
(6) Palmprint_Cici
(7) Palmprint_Cici
(8)
49
50
51
52 Palmprint_Cici
(9) Palmprint_Cici
(10) Palmprint_Cici
(11) Palmprint_Cici
(19) Palmprint_Bobby
(17) Palmprint_Bobby
26
(10) Palmprint_Bobby
27
28 Palmprint_Bobby
(5) Palmprint_Bobby
(6) Palmprint_Bobby
(7) Palmprint_Bobby
(8)
29
30
31
32 Palmprint_Bobby
(9) Palmprint_Bobby
(11) Palmprint_Bobby
40 Palmprint_Bobby
(12)
33
34
35
36 Palmprint_Bobby
(13) Palmprint_Bobby
(14) Palmprint_Bobby
(15) Palmprint_Bobby
(16)
37
38
39
(12)
53
75
(8)
69
70
71
72 Palmprint_Irene
(9) Palmprint_Irene
(10) Palmprint_Irene
(11) Palmprint_Irene
(12)
73
74
76 Palmprint_Irene
(6) Palmprint_Irene
(13) Palmprint_Irene
(14) Palmprint_Irene
(15) Palmprint_Irene
(16)
77
78
79
80 Palmprint_Irene
(17) Palmprint_Irene
(18) Palmprint_Irene
(19) Palmprint_Irene
(7) Palmprint_Irene
(5) Palmprint_Irene
54
(18) Palmprint_Cici
55
56 Palmprint_Cici
(13) Palmprint_Cici
(14) Palmprint_Cici
(15) Palmprint_Cici
(16)
57
58
59
60 Palmprint_Cici
(17) Palmprint_Cici
(19) Palmprint_Cici
68 Palmprint_Irene
(20)
61
62
63
64 Palmprint_Irene
(1) Palmprint_Irene
(2) Palmprint_Irene
(3) Palmprint_Irene
(4)
65
66
67
(20)
81
Palmprint_Irwan (19)
96 Palmprint_Irwan
(13) Palmprint_Irwan
(14) Palmprint_Irwan
(15) Palmprint_Irwan
(16)
97
98 99 100
Palmprint_Irwan (17)
Palmprint_Irwan (18)
Palmprint_Irwan (20)
94
101 102 103 104
Palmprint_Rian (1)
Palmprint_Rian (2)
Palmprint_Rian (3)
Palmprint_Rian (4)
105 106 107 108
Palmprint_Rian (5)
Palmprint_Rian (6)
Palmprint_Rian (7)
95
93
82
88 Palmprint_Irwan
83
84 Palmprint_Irwan
(1) Palmprint_Irwan
(2) Palmprint_Irwan
(3) Palmprint_Irwan
(4)
85
86
87
(5) Palmprint_Irwan
(12)
(6) Palmprint_Irwan
(7) Palmprint_Irwan
(8)
89
90
91
92 Palmprint_Irwan
(9) Palmprint_Irwan
(10) Palmprint_Irwan
(11) Palmprint_Irwan
Palmprint_Rian (8)
109 110 111 112
Palmprint_Vero (9)
125 126 127 128
Palmprint_Vero (5)
Palmprint_Vero (6)
Palmprint_Vero (7)
Palmprint_Vero (8)
129 130 131 132
Palmprint_Vero (10)
Palmprint_Vero (3)
Palmprint_Vero (11)
Palmprint_Vero (12)
133 134 135 136
Palmprint_Vero (13)
Palmprint_Vero (14)
Palmprint_Vero (15)
Palmprint_Vero (4)
Palmprint_Vero (2)
Palmprint_Rian (9)
Palmprint_Rian (15)
Palmprint_Rian (10)
Palmprint_Rian (11)
Palmprint_Rian (12)
113 114 115 116
Palmprint_Rian (13)
Palmprint_Rian (14)
Palmprint_Rian (16)
Palmprint_Vero (1)
117 118 119 120
Palmprint_Rian (17)
Palmprint_Rian (18)
Palmprint_Rian (19)
Palmprint_Rian (20)
121 122 123 124
Palmprint_Vero (16)
137 138 139 140
Palmprint_Yayuk (9)
Palmprint_Yayuk (19)
Palmprint_Yayuk (18)
Palmprint_Yayuk (17)
157 158 159 160
Palmprint_Yayuk (16)
Palmprint_Yayuk (15)
Palmprint_Yayuk (14)
Palmprint_Yayuk (13)
153 154 155 156
Palmprint_Yayuk (12)
Palmprint_Yayuk (11)
Palmprint_Yayuk (10)
149 150 151 152
Palmprint_Vero (17)
Palmprint_Yayuk (8)
Palmprint_Yayuk (7)
Palmprint_Yayuk (6)
Palmprint_Yayuk (5)
145 146 147 148
Palmprint_Yayuk (4)
Palmprint_Yayuk (3)
Palmprint_Yayuk (2)
Palmprint_Yayuk (1)
141 142 143 144
Palmprint_Vero (20)
Palmprint_Vero (19)
Palmprint_Vero (18)
Palmprint_Yayuk (20)
2. Data uji tanpa noise
28 IW (1)
22
23
24 I (3) I (4) I (5) I (6)
25
26
27
IW (2)
20 C (5) C (6) I (1) I (2)
IW (3)
IW (4)
29
30
31
32 IW (5)
IW (6) R (1) R (2)
21
No Citra (.jpg) No Citra (.jpg) No Citra (.jpg) No Citra (.jpg)
1
9
2
3
4 A (1) A (2) A (3) A (4)
5
6
7
8 A (5) A (6) B (1) B (2)
10
18
11
12 B (3) B (4) B (5) B (6)
13
14
15
16 C (1) C (2) C (3) C (4)
17
19
No Citra (.jpg) No Citra (.jpg) No Citra (.jpg) No Citra (.jpg)
48 Y (3) Y (4) Y (5) Y (6)
60 C (7) C (8) C (9) C (10)
59
58
57
56 B (7) B (8) B (9) B (10)
55
54
53
52 A (7) A (8) A (9) A (10)
51
50
49
No Citra (.jpg) No Citra (.jpg) No Citra (.jpg) No Citra (.jpg)
47
33
46
45
44 V (5) V (6) Y (1) Y (2)
43
42
41
40 V (1) V (2) V (3) V (4)
39
38
37
36 R (3) R (4) R (5) R (6)
35
34
3. Data uji memiliki noise
No Citra (.jpg) No Citra (.jpg) No Citra (.jpg) No Citra (.jpg)
70
79
78
77
76 V (7) V (8) V (9) V (10)
75
74
73
72 R (7) R (8) R (9) R (10)
71
69
61
IW (10)
IW (9)
IW (8)
68 IW (7)
67
66
65
64 I (7) I (8) I (9) I (10)
63
62
80 Y (7) Y (8) Y (9) Y (10)
LAMPIRAN B LISTING PROGRAM 1.
Modul Filter Gambar import java.io.File; import javax.swing.filechooser.FileFilter; //class yang digunakan untuk menyaring format citra hanya .jpg saja public class filterGambar extends FileFilter { public filterGambar() {} public boolean accept (File f) { if(f.isDirectory()) { return true; } //pengubahan String dari nama citra menjadi huruf kapital String file = f.getName().toUpperCase(); if(file.endsWith(".JPG")) //kondisi jika file citra/image memiliki ekstensi .jpg
{ return true; } return false;
} public String getDescription(){ return "Image File"; } }
2. Modul pelatihan (grayscale, deteksi tepi, dan binerisasi)
public class formUtama3 extends javax.swing.JFrame { filterGambar filter = new filterGambar(); BufferedImage originalImage; BufferedImage grayscaleImage, normalisasiIntensitasImage, edgeImage; JFileChooser fc = new JFileChooser(); /*1. Method RGB2GS : mengubah citra RGB menjadi grayscale*/ public void RGB2GS(BufferedImage grayscaleImage){ int alpha, r, g, b; /*variable width : mengambil nilai lebar dari citra
- variable height : mengambil nilai tinggi dari citra*/ int width = originalImage.getWidth(); int height = originalImage.getHeight(); //Membuat Buffered image untuk image grayscale BufferedImage im = new BufferedImage
(width,height,BufferedImage.TYPE_BYTE_GRAY); for(int i=0; i < width; i++){ for(int j=0; j < height; j++){
//mendapatkan nilai RGB dari originalImage alpha = originalImage.getRGB(i,j); r = (alpha & 0x00ff0000) >> 16; //mendapatkan nilai red (merah) g = (alpha & 0x0000ff00) >> 8; //mendapatkan nilai green (hijau) b = alpha & 0x000000ff; //mendapatkan nilai blue (biru)
//menghitung nilai gray image float gray = (float) (0.3 * r + 0.59 * g + 0.11 * b); } } // membuat dan menyimpan citra grayscale ke dalam folder ImageIO.write(im,"JPG",new File
("3. Citra Hasil Latih/1. Grayscale/newGrayLatih.jpg")); } /*2. method setCannyEdgeDetector untuk mengubah citra grayscale menjadi citra deteksi tepi*/ public void setCannyEdgeDetector(BufferedImage edges){ //file image grayscale untuk dibentuk citra deteksi tepi File file = new File("3. Citra Hasil Latih/1. Grayscale/newGrayLatih.jpg"); BufferedImage frame = ImageIO.read(file); //membuat sebuah objek bernama detector dari Class CannyEdge Detector CannyEdgeDetector detector = new CannyEdgeDetector(); //tetapkan low dan high threshold detector.setLowThreshold(0.5f); detector.setHighThreshold(1.0f); //proses pendeteksian tepi detector.setSourceImage(frame); //pengambilan sumber image detector.process(); //method proses deteksi tepi edges = detector.getEdgesImage(); // membuat dan menyimpan citra deteksi tepi ke dalam folder ImageIO.write(edges,"PNG",new File
("3. Citra Hasil Latih/2. Deteksi Tepi/newEdgeLatih.png")); } /*3. Method setBinerisasi untuk mengubah citra deteksi tepi menjadi citra biner*/ public void setBinerisasi(){ File file = new File("3. Citra Hasil Latih/2. Deteksi Tepi/newEdgeLatih.png"); BufferedImage imageBiner = ImageIO.read(file); int lebar = imageBiner.getWidth(); int tinggi = imageBiner.getHeight(); int threshold = 150; //nilai threshold yang ditetapkan
BufferedImage im = new BufferedImage (lebar,tinggi,BufferedImage.TYPE_BYTE_GRAY); for(int i = 0; i < lebar; i++){ for (int j=0; j < tinggi; j++){ //kondisi jika nilai image lebih besar dari nilai threshold if(image.getRGB(j,i) >= threshold) { image.getRGB(j,i) = 255; }
//kondisi jika nilai image lebih kecil dari nilai threshold else if (image.getRGB(j,i) < threshold)
{ image.getRGB(j,i)= 0; }
} } // membuat dan menyimpan citra biner ke dalam folder ImageIO.write(im,"PNG",new File
("3. Citra Hasil Latih/3. Biner/newBinerLatih.png")); } //method setEkstraksi untuk mendapatkan nilai fitur dari citra yang diproses public void setEkstraksi(){ File file = new File("3. Citra Hasil Latih/3. Biner/newBinerLatih.png"); //mengambil file yang dihitung fiturnya BufferedImage image = ImageIO.read(file); int lebar = image.getWidth(); int tinggi = image.getHeight(); int[][] gambar = new int[tinggi][lebar]; //membuat array 2 dimensi dengan nama
//variable gambar for (int row = 0; row < tinggi; row++) { //perulangan untuk membaca piksel baris //dan kolom dari citra for (int col = 0; col < lebar; col++) { gambar[row][col] = image.getRGB(col, row); //kondisi saat image memiliki nilai biner -16777216 (hitam) set menjadi nilai biner if(gambar[row][col] == -16777216) gambar[row][col] = 1; //kondisi saat image memiliki nilai biner -1(putih) set menjadi nilai biner 0 else if(gambar[row][col] == -1) gambar[row][col] = 0; } }
//inisialisasi variable untuk perhitungan pixel dan blok int index_i , index_j, nilai_pixel, jlh_pixel, kolom, hasil_index, temp_hasil = 0; int total_block = 10; //jumlah blok 10x10 blok int max_pixel_block = 20; //jumlah piksel dalam 1 blok yaitu 20x20 piksel double[] hasil = new double[100]; //array dengan variable hasil yang memiliki //panjang array 100 for(int h=0; h < total_block; h++) //perulangan pada kolom blok
{ for(int i= 0; i < total_block; i++) //perulangan pada baris blok { nilai_pixel = 0; jlh_pixel = 0; index_i = h * max_pixel_block; temp_hasil = 0; for(int j = index_i; j<index_i + max_pixel_block; j++) { index_j = i * max_pixel_block; for(int k = index_j; k < index_j + max_pixel_block; k++) { temp_hasil += gambar[k][j]; }
} // array hasil utk menyimpan nilai fitur rata-rata hasil[hasil_index] = (double) temp_hasil / 400;
//menampilkan hasil index di textArea variable txtRataRata txtRataRata.setText(txtRataRata.getText()+""+hasil[hasil_index]+"\n"); hasil_index++; //melanjutkan nilai hasil dengan index berikutnya kolom++; //perhitungan blok di kolom berikutnya
} } } } Class: CannyEdgeDetector.java public class CannyEdgeDetector { private final static float GAUSSIAN_CUT_OFF = 0.005f; private final static float MAGNITUDE_SCALE = 100F; private final static float MAGNITUDE_LIMIT = 1000F; private final static int MAGNITUDE_MAX = (int) (MAGNITUDE_SCALE * MAGNITUDE_LIMIT); private int height; private int width; private int picsize; private int[] data; private int[] magnitude; private BufferedImage sourceImage; private BufferedImage edgesImage; private float gaussianKernelRadius; private float lowThreshold; private float highThreshold; private int gaussianKernelWidth; private boolean contrastNormalized; private float[] xConv; private float[] yConv; private float[] xGradient; private float[] yGradient; public CannyEdgeDetector() { lowThreshold = 2.5f; highThreshold = 7.5f; gaussianKernelRadius = 2f; gaussianKernelWidth = 16; contrastNormalized = false;
} /*method process berisi proses yang dilakukan untuk mencari deteksi tepi*/ public void process() { width = sourceImage.getWidth(); height = sourceImage.getHeight(); picsize = width * height; initArrays(); //komponen yang terdapat didalamnya //proses-proses untuk mendapatkan citra deteksi tepi computeGradients(gaussianKernelRadius, gaussianKernelWidth); int low = Math.round(lowThreshold * MAGNITUDE_SCALE); int high = Math.round(highThreshold * MAGNITUDE_SCALE); performHysteresis(low, high); //proses hysteresis menghilangkan tepi yang rusak thresholdEdges(); writeEdges(data); } private void initArrays() { if (data == null || picsize != data.length) { data = new int[picsize]; magnitude = new int[picsize]; xConv = new float[picsize]; yConv = new float[picsize]; xGradient = new float[picsize]; yGradient = new float[picsize]; } } // memproses penerapan filter gaussian private void computeGradients(float kernelRadius, int kernelWidth) { //perhitungan dengan matriks konvolusi Gaussian float kernel[] = new float[kernelWidth]; float diffKernel[] = new float[kernelWidth]; int kwidth; for (kwidth = 0; kwidth < kernelWidth; kwidth++) { float g1 = gaussian(kwidth, kernelRadius); if (g1 <= GAUSSIAN_CUT_OFF && kwidth >= 2) break; float g2 = gaussian(kwidth - 0.5f, kernelRadius); float g3 = gaussian(kwidth + 0.5f, kernelRadius); kernel[kwidth] = (g1 + g2 + g3) / 3f / (2f * (float) Math.PI * kernelRadius * kernelRadius); diffKernel[kwidth] = g3 - g2; } int initX = kwidth - 1; int maxX = width - (kwidth - 1); int initY = width * (kwidth - 1); int maxY = width * (height - (kwidth - 1)); //mencari nilai dan arah tepi dengan matriks konvolusi x dan y
for (int x = initX; x < maxX; x++) { for (int y = initY; y < maxY; y += width) { int index = x + y; float sumX = data[index] * kernel[0]; float sumY = sumX; int xOffset = 1; int yOffset = width; for(; xOffset < kwidth ;) { sumY += kernel[xOffset] * (data[index - yOffset] + data[index + yOffset]); sumX += kernel[xOffset] * (data[index - xOffset] + data[index + xOffset]); yOffset += width; xOffset++;} yConv[index] = sumY; xConv[index] = sumX;
} } for (int x = initX; x < maxX; x++) { for (int y = initY; y < maxY; y += width) { float sum = 0f; int index = x + y; for (int i = 1; i < kwidth; i++) sum += diffKernel[i] * (yConv[index - i] - yConv[index + i]); xGradient[index] = sum;
} } for (int x = kwidth; x < width - kwidth; x++) { for (int y = initY; y < maxY; y += width) { float sum = 0.0f; int index = x + y; int yOffset = width; for (int i = 1; i < kwidth; i++) { sum += diffKernel[i] * (xConv[index - yOffset] - xConv[index + yOffset]); yOffset += width;
} yGradient[index] = sum;
} } initX = kwidth; maxX = width - kwidth; initY = width * kwidth; maxY = width * (height - kwidth); /*perulangan untuk menghubungkan arah tepi (North, South, West, East, dst)*/ for (int x = initX; x < maxX; x++) { for (int y = initY; y < maxY; y += width) { int index = x + y; int indexN = index - width; int indexS = index + width; int indexW = index - 1; int indexE = index + 1; int indexNW = indexN - 1; int indexNE = indexN + 1; int indexSW = indexS - 1; int indexSE = indexS + 1; float xGrad = xGradient[index]; float yGrad = yGradient[index]; float gradMag = hypot(xGrad, yGrad); // non-maximal suppression : penelusuran tepi yang ada di dalam arah tepi float nMag = hypot(xGradient[indexN], yGradient[indexN]); float sMag = hypot(xGradient[indexS], yGradient[indexS]); float wMag = hypot(xGradient[indexW], yGradient[indexW]); float eMag = hypot(xGradient[indexE], yGradient[indexE]); float neMag = hypot(xGradient[indexNE], yGradient[indexNE]); float seMag = hypot(xGradient[indexSE], yGradient[indexSE]); float swMag = hypot(xGradient[indexSW], yGradient[indexSW]); float nwMag = hypot(xGradient[indexNW], yGradient[indexNW]); float tmp; if (xGrad * yGrad <= (float) 0 /*(1)*/
? Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/ ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * neMag - (xGrad + yGrad) * eMag) /*(3)*/
&& tmp > Math.abs(yGrad * swMag - (xGrad + yGrad) * wMag) /*(4)*/
: (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * neMag - (yGrad + xGrad) * nMag) /*(3)*/ && tmp > Math.abs(xGrad * swMag - (yGrad + xGrad) * sMag) /*(4)*/ : Math.abs(xGrad) >= Math.abs(yGrad) /*(2)*/ ? (tmp = Math.abs(xGrad * gradMag)) >= Math.abs(yGrad * seMag + (xGrad - yGrad) * eMag) /*(3)*/ && tmp > Math.abs(yGrad * nwMag + (xGrad - yGrad) * wMag) /*(4)*/ : (tmp = Math.abs(yGrad * gradMag)) >= Math.abs(xGrad * seMag + (yGrad - xGrad) * sMag) /*(3)*/ && tmp > Math.abs(xGrad * nwMag + (yGrad - xGrad) * nMag) /*(4)*/ )
{ magnitude[index] = gradMag >= MAGNITUDE_LIMIT ? MAGNITUDE_MAX : (int) (MAGNITUDE_SCALE * gradMag); } else { magnitude[index] = 0; }
} } private float hypot(float x, float y) { return (float) Math.hypot(x, y);
} private float gaussian(float x, float sigma) { //rumus untuk filter Gaussian return (float) Math.exp(-(x * x) / (2f * sigma * sigma));
} /*proses hysteresis private void performHysteresis(int low, int high) { Arrays.fill(data, 0); int offset = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (data[offset] == 0 && magnitude[offset] >= high) { follow(x, y, offset, low); } offset++; }
} } private void follow(int x1, int y1, int i1, int threshold) { int x0 = x1 == 0 ? x1 : x1 - 1; int x2 = x1 == width - 1 ? x1 : x1 + 1; int y0 = y1 == 0 ? y1 : y1 - 1; int y2 = y1 == height -1 ? y1 : y1 + 1; data[i1] = magnitude[i1]; for (int x = x0; x <= x2; x++) { for (int y = y0; y <= y2; y++) { int i2 = x + y * width; if ((y != y1 || x != x1)
&& data[i2] == 0 && magnitude[i2] >= threshold) { follow(x, y, i2, threshold); return;
} }
} }
//penentuan nilai threshold dalam menetapkan tepi atau tidak private void thresholdEdges() { for (int i = 0; i < picsize; i++) { data[i] = data[i] > 0 ? -1 : 0xff000000;
} }
//membuat edge /tepi citra private void writeEdges(int pixels[]) { if (edgesImage == null) { edgesImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB); } edgesImage.getWritableTile(0, 0).setDataElements(0, 0, width, height, pixels); }
3. Modul Pengujian
Modul untuk proses pengolahan citra sama dengan modul pelatihan hanya berbeda pada folder target penyimpanan. Semua citra hasil pengujian akan disimpan di dalam folder hasil citra uji.
//method untuk mencari jarak Euclidean ternormalisasi public void cariJarak(){ String nilaiUji = ambilFiturUji(); String[] potongUji = nilaiUji.split("; "); Double[] u = new Double[potongUji.length]; Double uNorm = 0.0; double min; double d = 0.0; /* array untuk menyimpan nilai jarak yang akan diuji*/ Double[] arrayD = new Double[160]; int h; for( h=0; h < potongUji.length; h++) //perulangan saat pengambilan fitur citra uji { u[h] = Double.parseDouble(potongUji[h]);
2
uNorm += (double) u[h] * u[h]; //sigma u (hitung sigma uNorm)
h
}
2 1/2
uNorm = (double) Math.sqrt(uNorm); //(sigma (u ))
h
/* perulangan untuk mengambil fitur yang telah dilatih dalam database (sebanyak 160 fitur) */ for(int i=0; i < arrayD.length; i++) { String nilaiLatih = ambilFiturLatih(i+1); //nilai fitur latih yang diambil
//mulai dari nomor indeks-1 String[] potongLatih = nilaiLatih.split("; "); /*membuat array v dengan panjang sebesar fitur latih yaitu 100*/ Double[] v = new Double[potongLatih.length]; Double vNorm = 0.0; for(int j=0; j < v.length; j++) //perulangan untuk menghitung sigma vNorm { v[j] = Double.parseDouble(potongLatih[j]);
2
vNorm += (double) v[j] * v[j]; // sigma v (hitung sigma vNorm)
j
}
2 1/2
vNorm = (double) Math.sqrt(vNorm); //(sigma (v ))
j
/*perulangan menghitung nilai jarak Euclidean ternormalisasi*/ for(int j=0; j < u.length; j++) {
//hitung jarak (d) d += (double) (u[j]/uNorm-v[j]/vNorm)*(u[j]/uNorm-v[j]/vNorm); d = (double) Math.sqrt(d); } arrayD[i] = (double) d; //menyimpan nilai setiap indeks arrayD dengan nilai
//hasil jarak (d) System.out.println(arrayD[i]); //cetak nilai semua indeks dalam arrayD } /*kondisi pencarian nilai jarak (d) minimum*/ min = arrayD[0]; //inisialisasi nilai min = nilai indeks ke-0 arrayD for (int k=1; k <arrayD.length; k++){ // pengecekan disetiap indeks arrayD if(arrayD[k] < min){ //kondisi saat nilai arrayD lebih kecil dari nilai min min = arrayD[k]; } } System.out.println("hasil jarak terkecil: "+min);