BAB IV
HASIL DAN ANALISIS 4.1 Hasil Karya
4.1.1 Tampilan Form a. Home
Gambar 4.1 Tampilan awal aplikasi
Pada saat membuka aplikasi, pengguna akan disuguhkan tampilan awal yang sederhana. Skema adalah nama untuk aplikasi ini, diambil dari bahasa Denmark yang berarti skedul, rencana, atau jadwal. Tampilan awal dari Skema terinspirasi dari desain yang sederhana dan elegan.
Di bagian pojok kanan tulisan Skema terdapat logo yang berbentuk seperti DNA (Deoxyribonucleic Acid) dan juga berbentuk seperti jam pasir. Dari logo Skema tersebut dapat diambil makna bahwa DNA mewakili untuk genetika, sedangkan jam pasir melambangkan proses atau waktu.
Jadi, dalam logo Skema menceritakan tentang sesuatu yang dapat memproses genetika, dalam hal ini adalah aplikasi yang melakukan proses penghitungan probabilitas menggunakan algoritma genetika.
Gambar 4.2 Logo Skema
Di bagian bawah tulisan Skema terdapat beberapa tombol yang digunakan untuk memanggil form yang diinginkan. Berbeda dengan tombol pada umumnya, tombol di aplikasi ini didesain berbentuk tautan untuk membuat aplikasi ini terlihat sederhana tapi memiliki fitur yang mumpuni.
b. Pelajaran
Form Pelajaran berisi tentang segala sesuatu tentang apa yang menyangkut tentang pelajaran untuk terselenggaranya KBM (Kegiatan Belajar Mengajar) meliputi data mata pelajaran, data guru pengampu, data kelas yang ada, dan plot mengajar. Plot mengajar digunakan untuk membuat plot tentang guru pengampu mengajar pelajaran apa dan kelas yang dimana saja guru tersebut mengajar.
Gambar 4.3 Tab Mata Pelajaran dalam form Pelajaran
Pada tab Mata Pelajaran terdapat pilihan untuk mengisi data mata pelajaran baru, mengedit atau menghapus data mata pelajaran yang sudah ada.
Gambar 4.4 Tab guru dalam form Pelajaran
Tab Guru berisi tentang data guru, sama seperti tab Mata Pelajaran data di tab Guru juga dapat ditambah, diedit, maupun dihapus.
Gambar 4.5 Menu Ruang
d. Jadwal
Gambar 4.6 Menu Jadwal
Pada gambar di atas dapat dilihat bahwa pada bagian kiri terdapat 4 opsional untuk memproses jadwal. Sedangkan dibagian kanan adalah hasil dari jadwal yang telah diproses oleh aplikasi.
4.1.2 Pengkodean
Dari sisi pengkodean terdapat 3 garis besar untuk aplikasi ini, yaitu pengkodean pada form untuk interaksi dengan pengguna, pemodelan bisnis untuk transaksi data dari dan ke database, kemudian yang paling rumit dan menyita banyak waktu untuk
riset dan uji coba adalah pengkodean untuk algoritma. Berikut adalah penjelasan dari rincian di atas:
4.1.2.1 Form
Dalam pembuatan aplikasi Skema menggunakan menggunakan OOP (Object Oriented Programming) atau pemrograman berbasis objek, jadi setiap kelas memiliki struktur kode yang hampir sama untuk aliran data dari database ke form atau CRUD (Create, Read, Update, and Delete).
Gambar 4.7 Windows form pada aplikasi Skema
Kode Program 4.3 Mengambil data pelajaran di database dalam form
Pelajaran
Imports BusinessLib
Public Class Pelajaran
Private busObj As PelajaranIni = Nothing
#Region " Read "
Private Sub Pelajaran_Load(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Load busObj = New PelajaranIni
Try
Home.Cursor = Cursors.WaitCursor
dgvPmapel.DataSource = busObj.ReadMapel dgvPkelas.DataSource = busObj.ReadKelas dgvPguru.DataSource = busObj.ReadGuru dgvPlot.DataSource = busObj.ReadPlot cbPlotRefresh()
Home.Cursor = Cursors.Arrow Catch ex As Exception
MessageBox.Show(ex.Message) Home.Cursor = Cursors.Arrow End Try
End Sub #End Region
Dari kode di atas dapat dilihat bahwa semua data diambil melalui sebuah Class Library bernama BusinessLib. Kemudian dibuatlah variabel busObj untuk memanggil sebuah class yang bernama PelajaranIni yang berada di dalam BusinessLib, busObj inilah yang berfungsi untuk memanggil data dari database melalui perantara class PelajaranIni. Data kemudian ditampung dalam Data Grid View. Jadi setiap menu Pelajaran diklik maka semua data dari database akan langsung dibaca dan ditampung di Data Grid View masing-masing sub-menu.
Kode Program 4.3 Menambah data pelajaran di database dalam form
Pelajaran
Imports BusinessLib
Public Class Pelajaran
Private busObj As PelajaranIni = Nothing
Private Sub btnSaveMP_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles btnSaveMP.Click If rbTambah.Checked Then 'untuk membedakan tambah baru dan edit data
Try
busObj = PelajaranIni.InsertData()
'memanggil fungsi insert data, dan mengisi value _newdata menjadi true With busObj .Pilihan = "mapel".ToLower .KodeMapel = tbKodeMapel.Text .NamaMapel = tbNamaMapel.Text End With
busObj.save() 'menyimpan data baru
MessageBox.Show("Data berhasil ditambahkan", "Sukses", MessageBoxButtons.OK, MessageBoxIcon.Information) Catch ex As Exception MsgBox(ex.Message) End Try dgvPmapel.DataSource = busObj.ReadMapel 'reload dgv
Di dalam kode program di atas mengunakan fungsi if dan else, jadi apabila Radio Button diklik untuk tambah data maka fungsi if akan berjalan dan langsung melakukan proses penambahan data melalui class PelajaranIni yang berada dalam class library BusinessLib. Begitu pula dengan mengedit data, apabila Radio Button diklik edit data maka fungsi else yang gantian berjalan dan melakukan proses edit data melalui alur yang sama (melewati BusinessLib).
Kode Program 4.3 Mengedit data pelajaran di database dalam form Pelajaran
Apabila kita perhatikan baris kode di atas dapat dilihat bahwa untuk proses edit, data diambil dahulu kemudian baru menyimpan perubahan ke dalam database.
Else
Try
Dim pilihan As DataRowView =
dgvPmapel.SelectedRows(0).DataBoundItem 'mengambil data dari dgv
Dim id As String = pilihan.Row(0).ToString
'inisialisasi id sebagai patokan
busObj = PelajaranIni.UpdateData(id)
'berisi id yg terpilih dari dgv
With busObj
.Pilihan = "mapel".ToLower .KodeMapel = tbKodeMapel.Text .NamaMapel = tbNamaMapel.Text End With
busObj.save() 'edit data
MessageBox.Show("Data berhasil diubah", "Sukses", MessageBoxButtons.OK,
MessageBoxIcon.Information) Catch ex As Exception MsgBox(ex.Message) End Try dgvPmapel.DataSource = busObj.ReadMapel 'reload dgv cbPlotRefresh() End If End Sub
Agar data yang baru ditambah atau diedit langsung terbaca maka akan dilakukan refresh di DataGridView setiap kali data berhasil diproses.
Kemudian yang terakhir mengenani transaksi data dari form adalah hapus data. Kode untuk menghapus data cukup sederhana dan tidak terlalu rumit untuk dibuat.
Kode Program 4.4 Menghapus data pelajaran di database dalam form
Pelajaran
MessageBox pertama berfungsi untuk memberikan peringatan kepada user agar tidak salah saat menghapus data yang telah dipilih. Setelah selesai proses menghapus maka akan ada
Private Sub HapusToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles
HapusToolStripMenuItem.Click Select Case
tcPelajaran.SelectedTab.Name.ToString 'seleksi nama tab
Case "tpMapel"
Dim pilihan As DataRowView = dgvPmapel.SelectedRows(0).DataBoundItem 'mengambil data dari dgv
Dim namaMapel As String = pilihan.Row(2).ToString 'inisialisasi id sebagai patokan
MessageBox.Show("Anda yakin ingin mengapus mata pelajaran " + namaMapel, "Hapus data?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) If vbYes Then Try busObj.Pilihan = "Mapel".ToLower busObj.MapelID = pilihan.Item("MapelID").ToString busObj.Delete() dgvPmapel.DataSource = busObj.ReadMapel MessageBox.Show("Mata pelajaran " + namaMapel + " berhasil dihapus :D", "Sukses", MessageBoxButtons.OK,
MessageBoxIcon.Information) Catch ex As Exception MsgBox(ex.Message) End Try End If dgvPlotRefresh()
PublicClassUtilities
PublicSharedFunction koneksi()
Return ("data source=TOSHIBATKJ-01\sqlEXPRESS ; database = skemadb; integrated security=SSPI")
EndFunction EndClass
informasi bahwa data tersebut telah dihapus dan
DataGridView akan refresh lagi untuk memperbarui data. 4.1.2.2 Basis Data
Dalam pengkodean basis data digunakan Class Library yang berfungsi agar class ini nantinya dapat di-reference ke class lainnya yang membutuhkan transaksi data dari database. BusinessLib memiliki beberapa class yang berfungsi untuk melayani transaksi data dari setiap form yang berbeda, misal class PelajaranIni berfungsi untuk melayani transaksi data dari form Pelajaran.
Gambar 4.8 Class pada BusinessLib
Dalam class di atas terdapat kelas bernama Utilities yang berfungsi untuk menginisialisasikan koneksi ke Database Engine yaitu SQL SERVER 2008 agar tidak dipanggil berulang kali saat ingin membuka koneksi.
Kode Program 4.5 Class Utilities
Setelah terhubung ke database dengan memanggil fungsi koneksi, maka selanjutnya adalah mencoba mengambil
Public Function ReadMapel() As DataTable Dim dt As New DataTable
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open() Try
Using cm As New SqlCommand("select * from Mapel", cn) dt.Load(cm.ExecuteReader) End Using Catch ex As Exception Throw ex End Try Catch ex As Exception Throw ex Finally cn.Close() End Try End Using Return dt End Function
data dari database. Untuk mengambilnya, kode yang digunakan cukup sederhana dan menggunakan query dasar yang biasa dipakai untuk mengambil data.
Kode Program 4.6 Mengambil data dari database
Data yang telah diambil dari database ditampung di Data Table. Hal ini dilakukan agar memudahkan saat ditampilkan di DataGridView pada form.
Untuk menambahkan data ke database diperlukan fungsi yang dapat diakses oleh semua class dikarenakan aplikasi tidak boleh langsung menyuntikkan data dari form langsung ke database karena hal tersebut kurang aman dan tidak efektif. Jadi dibutuhkan 2 method yaitu shared method untuk menjembatani antara form dengan BusinessLib dan yang kedua instance method untuk melakukan seleksi data akan masuk proses tambah atau edit sebelum diteruskan ke data portal untuk ditulis ke database.
'shared method
Public Shared Function InsertData() As PelajaranIni Dim obj As New PelajaranIni
obj._newData = True
obj._pilihan = "" Return obj End Function 'instance method Public Sub save() Select Case _pilihan Case "mapel".ToLower If _newData Then Call CreateMapel() Else Call UpdateMapel() End If ... 'data portal
Private Sub CreateMapel()
Dim qry As String = "INSERT INTO
Mapel(KodeMapel,NamaMapel) VALUES (@kdmp,@nmmp)" Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@kdmp", _kodeMapel) cm.Parameters.AddWithValue("@nmmp", _namaMapel) cm.ExecuteNonQuery() End Using Catch ex As Exception Throw ex Finally cn.Close() End Try End Using End Sub
Kode Program 4.7 Menambah data ke database
Menambahkan data ke database dibutuhkan variabel yang berfungsi untuk menampung data dari form yang telah dimasukkan oleh user. Kemudian variabel tersebut dijadikan untuk mengisi value agar dapat terbaca di query sebagai parameter yang sebelumnya didefinisikan sebagai alias, misal @kdmp, @nmmp, @idmp, dan lainnya.
'shared method
Public Shared Function UpdateData(id As Integer) As PelajaranIni
Dim obj As New PelajaranIni 'jadi si id ini langsung menginput ke semua variabel
obj.MapelID = id 'nanti si pilihan yang ngecek
obj.GuruID = id 'si id itu masuk ke pilihan mana
obj.KelasID = id obj.PlotID = id obj._pilihan = "" Return obj End Function 'instance method Public Sub save() Select Case _pilihan Case "mapel".ToLower If _newData Then Call CreateMapel() Else Call UpdateMapel() End If ... 'data portal
Private Sub UpdateMapel()
Dim qry As String = "UPDATE Mapel SET
KodeMapel=@kdmp,NamaMapel=@nmmp WHERE MapelID=@mpid" Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@mpid", _mapelID) cm.Parameters.AddWithValue("@kdmp", _kodeMapel) cm.Parameters.AddWithValue("@nmmp", _namaMapel) cm.ExecuteNonQuery() End Using Catch ex As Exception Throw ex Finally cn.Close() End Try End Using End Sub 'shared method
Public Shared Function DeleteData(id As Integer) As PelajaranIni
Dim obj As New PelajaranIni obj.MapelID = id obj.GuruID = id obj.KelasID = id obj.PlotID = id obj._pilihan = "" Return obj End Function 'instance method Public Sub Delete() Select Case _pilihan Case "mapel".ToLower Call DeleteMapel() Case "Guru".ToLower Call DeleteGuru() Case "Kelas".ToLower Call DeleteKelas() Case "Plot".ToLower Call Cekrelasi() Call DeletePlot() End Select End Sub 'data portal
Private Function Cekrelasi() Dim dr As SqlDataReader Dim qry As String
qry = "SELECT * FROM PlotMengajar WHERE MapelID=@mpid" Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open() Try
Using cm As New SqlCommand(qry, cn) cm.Parameters.AddWithValue("@mpid", _mapelID) dr = cm.ExecuteReader _isThere = True End Using Catch ex As Exception Throw ex End Try Catch ex As Exception Throw ex Finally cn.Close() End Try End Using Return _isThere End Function ...
Private Sub DeleteMapel()
Seperti pada saat menambah data, mengedit data juga mengunakan fungsi shared method dan juga instance method untuk prosesnya. Yang jadi pembeda adalah pada fungsi shared method berisi value yang berasal dari form dan tentunya query dalam data portal.
Kode Program 4.8 Mengedit data dari database
...
Private Sub DeleteMapel()
Dim qry As String If _isThere Then
qry="DELETE FROM PlotMengajar Where MapelId=@mpid;"& _ "DELETE FROM Mapel Where MapelId = @mpid;"
Else
qry = "DELETE FROM Mapel Where MapelId = @mpid;"
End If
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
cm.Parameters.AddWithValue("@mpid", _mapelID) cm.ExecuteNonQuery() End Using Catch ex As Exception _isThere = True Call DeleteMapel() Finally cn.Close() End Try End Using End Sub
Dalam proses hapus, data terlebih dahulu dicek punya relasi dengan dengan tabel PlotMengajar atau tidak, kalau data tersebut mempunyai relasi maka digunakanlah query yang pertama (fungsi if) yaitu menghapus terlebih dahulu id mata pelajaran di tabel PlotMengajar kemudian baru menghapus data yang ada di tabel Mapel. Apabila data yang ingin dihapus tidak mempunyai relasi, maka digunakanlah query kedua (fungsi else) untuk menghapus data di tabel Mapel.
4.1.2.3 Algoritma Genetika
Dalam algoritma genetika harus digunakan beberapa variabel acak untuk proses optimasi. Skema memiliki fitur untuk memberikan nilai acak tersebut untuk proses penghitungan optimasi tersebut. Variabel Jumlah gen dan Populasi per generasi menggunakan bilangan asli, untuk menentukannya tergantung dari banyaknya data. Oleh karena itu secara default Jumlah Gene diberi nilai 100 agar semua data di PlotMengajar dapat ditampung. Sedangkan untuk Populasi per generasi diberi nilai default 10 karena dianggap ideal sebagai sampel data. Jika ingin
mengganti variabel disarankan untuk memasukkan nilai yang lebih besar dari nilai sebelumnya, karena pada saat proses penghitungan optimasi dengan nilai yang kecil sering terjadi overload data atau data tidak dapat diproses lebih lanjut karena kurangnya sampel data.
Kemudian untuk variabel probabilitas crossover dan probabilitas mutasi tidak harus diganti, akan tetapi apabila menginginkan hasil yang lebih bervarisasi maka dapat diganti sesuai keinginan. Nilai untuk variabel tersebut mempunyai rentan antara 0 sampai 1, dan tidak boleh bernilai 0 dan atau 1. Secara default nilai variabel untuk Probabilitas crossover dan Probabilitas mutasi masing-masing 0.5 dan 0.1, angka tersebut diperoleh dari hasil trial and error pada saat proses development aplikasi Skema.
Gambar 4.9 Variabel dalam form Jadwal
Jadi fitur variabel sangat membantu untuk pengguna awam menggunakan Skema. Pengguna awam
pun tidak terlalu dipusingkan oleh pengisian variabel karena tingkat kesalahan pemilihan variabel tersebut sudah diperhitungkan sebelumnya. Kesalahan dapat terjadi apabila variabel Jumlah Gen di form lebih sedikit dibanding variabel gen yang ada di Class Library Algoritma. Variabel gen ini didapat dari array 2 dimensi yang berisi data jumlah mata pelajaran, data ruang, dan data waktu.
Pseudo code 4.1. Algoritma Genetika
Kode Program 4.10 Inisialisasi awal
Inisialisasi Populasi Repeat
Evaluasi Populasi
Pilih individu/ kromosom terbaik Lakukan Crossover
Mutasi Populasi Baru
Sampai mendapat individu yg diinginkan dari generasi yg ditetapkan
'inisialisasi awal
'panggil fungsi di class SetParameter
agObj = New SetParameter JumlahGen = agObj.InitialGene mataPelajaran = agObj.InitialMapel guruMP = agObj.InitialGuru
ruang = agObj.InitialRuang() waktu = agObj.InitialWaktu()
'Public class SetParameter Public Function InitialGene()
Dim qry As String = "SELECT COUNT(*) FROM PlotMengajar"
Using cn As New SqlConnection(Utilities.koneksi) Try
cn.Open()
Using cm As New SqlCommand(qry, cn)
jumlahGene = Convert.ToInt32(cm.ExecuteScalar()) 'jumlahGene = jumlahGene - 1 End Using Catch ex As Exception Throw ex Finally cn.Close() End Try End Using Return jumlahGene End Function
Kode Program 4.11 Proses algoritma genetika (garis besar)
Kode Program 4.12 Evaluasi populasi 'inisialisasi populasi
ag = New AG
ag.GenetikAI(jumlahKromosom, mataPelajaran, guruMP, ruang, waktu, probCrossover, probMutasi)
ag.init()
Dim found As Boolean = False
For i As Integer = 0 To maksIterasi ag.hitungFitness()
ag.seleksi() ag.crossover() ag.mutasi()
If ag.cekTerbaik() Then
MsgBox("Jadwal optimal telah ditemukan :D", MsgBoxStyle.Information, "Success!")
found = True
Exit For
End If
Next
If found = False Then
MsgBox("Gagal memproses jadwal optimal :( Silakan ganti parameter di atas", MsgBoxStyle.Critical, "Failed") Exit Sub
End If
Public Sub hitungFitness()
Call hitungGuruBentrok()
Call hitungRuanganBentrok()
_fitness = 1.0F / (1.0F + _tabrakanG + _tabrakanR)
End Sub
Public Sub hitungGuruBentrok()
'guru yg sama mengajar di kelas berbeda dalam satu waktu
_tabrakanG = 0
Dim _isFinish As Boolean = False
_indexSkip = New List(Of Integer)
For i As Integer = 0 To _jumlahGen - 1 _isFinish = False
If Not _indexSkip.Contains(i) Then
For j As Integer = i + 1 To _jumlahGen - 1
If Not _indexSkip.Contains(j) Then If _guruMapel(i) = _guruMapel(j) And
_gen(i, 2) = _gen(j, 2) Then If _isFinish = False Then
_tabrakanG = _tabrakanG + 1 End If _isFinish = True _indexSkip.Add(j) End If End If Next End If Next End Sub
Kode Program 4.13 Seleksi kromosom Public Sub seleksi()
_totalFitness = 0.0F
'cari total fitness semua kromosom
For i As Integer = 0 To _jumlahKromosom - 1
_totalFitness = _totalFitness + _kromosom(i)._fitness Next
'cari probabilitas masing" fitness
For i As Integer = 0 To _jumlahKromosom - 1 _kromosom(i)._probabilitasFitness = _kromosom(i)._fitness / _totalFitness Next
'cari kumulatif masing" fitness
For i As Integer = 0 To _jumlahKromosom - 1
If i = 0 Then _kromosom(i)._kumulatifMax = _kromosom(i)._probabilitasFitness Else _kromosom(i)._kumulatifMax = _kromosom(i - 1)._kumulatifMax + _kromosom(i)._probabilitasFitness End If Next
'kumulatif itu pas kromosom dijumlahkan terus dibagi lagi dengan angka yang sama
Dim r As Random = New Random
_randomSeleksi = New Double(_jumlahKromosom - 1) {}
'memilih
For i As Integer = 0 To _jumlahKromosom - 1 Dim _terpilih As Integer = 0
_randomSeleksi(i) = r.NextDouble() 'cari dimana probabilitasnya yang cocok
For j As Integer = 0 To _jumlahKromosom - 1 If _randomSeleksi(i) <
_kromosom(j)._kumulatifMax Then
terpilih = j ‘utk mengisi ke kromosom yg terpilih
Exit For
End If
Next
For j As Integer = 0 To _jumlahKromosom _hasilSeleksi(i)._gen(j, 0) = _kromosom(_terpilih)._gen(j, 0) _hasilSeleksi(i)._gen(j, 1) = _kromosom(_terpilih)._gen(j, 1) _hasilSeleksi(i)._gen(j, 2) = _kromosom(_terpilih)._gen(j, 2) Next Next _kromosom = _hasilSeleksi End Sub
Kode Program 4.14 Crossover (bagian pertama) Public Sub crossover()
Dim r As New Random
_randomCrossover = New Double(_jumlahKromosom - 1) {} _crossoverTerpilih = New List(Of Integer)
For i As Integer = 0 To _jumlahKromosom - 1 _randomCrossover(i) = r.NextDouble()
If _randomCrossover(i) <= _probabilitasCrossover Then
_crossoverTerpilih.Add(i) End If
Next
If _crossoverTerpilih.Count >= 2 Then
Dim r2 As New Random
Dim titik As Integer = r2.Next(0, _kromosom(0)._jumlahGen - 1)
Dim temp() As Integer = New Integer(2) {}
For i As Integer = 0 To _crossoverTerpilih.Count - 1
For j As Integer = i + 1 To _crossoverTerpilih.Count - 1 Dim sebelum1 As StringBuilder = New StringBuilder Dim sebelum2 As StringBuilder = New StringBuilder Dim sesudah1 As StringBuilder = New StringBuilder Dim sesudah2 As StringBuilder = New StringBuilder For k As Integer = 0 To 3 'jumlah sebelum dan sesudah
sebelum1.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 0).ToString + " ") sebelum1.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 1).ToString + " ") sebelum1.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 2).ToString + " | ") sebelum2.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 0).ToString + " ") sebelum2.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 1).ToString + " ") sebelum2.Append(_kromosom(_crossoverTerpilih(i)). _gen(k, 2).ToString + " | ") Next
For x As Integer = titik To _kromosom(0)._jumlahGen - 1 temp(0) = _kromosom(_crossoverTerpilih(i))._gen(x, 0) temp(1) = _kromosom(_crossoverTerpilih(i))._gen(x, 1) temp(2) = _kromosom(_crossoverTerpilih(i))._gen(x, 2) kromosom(_crossoverTerpilih(i))._gen(x, 0) = _kromosom(_crossoverTerpilih(j))._gen(x, 0) _kromosom(_crossoverTerpilih(i))._gen(x, 1) = _kromosom(_crossoverTerpilih(j))._gen(x, 1) _kromosom(_crossoverTerpilih(i))._gen(x, 2) = _kromosom(_crossoverTerpilih(j))._gen(x, 2) _kromosom(_crossoverTerpilih(j))._gen(x, 0) = temp(0)
Kode Program 4.15 Crossover (bagian kedua)
Kode Program 4.16 Mutasi For k As Integer = 0 To 3 sesudah1.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 0).ToString + " ") sesudah1.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 1).ToString + " ") sesudah1.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 2).ToString + " | ") sesudah2.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 0).ToString + " ") sesudah2.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 1).ToString + " ") sesudah2.Append(_kromosom(_crossoverTerpilih(i))._gen(k, 2).ToString + " | ") Next Next Next End If End Sub
Public Sub mutasi() Dim r3 As New Random
_randomMutasi = New Double(_jumlahKromosom * _kromosom(0)._jumlahGen - 1) {}
For i As Integer = 0 To _randomMutasi.Length - 1 _randomMutasi(i) = r3.NextDouble()
If _randomMutasi(i) < _probabilitasMutasi Then
Dim row, column As Integer
row = Math.Floor(i / _kromosom(0)._jumlahGen) column = i Mod _kromosom(0)._jumlahGen
Dim index As Integer
index = _waktu.IndexOf(_kromosom(row)._gen(column, 2))
If index = _waktu.Count - 1 Then
index = 0 End If _kromosom(row)._gen(column, 2) = _waktu(index + 1) End If Next End Sub
Kode Program 4.17 Populasi baru (apabila ditemukan)
4.2 Hasil Pengujian 4.2.1 Inisialisasi Awal
Inisialisasi awal bertujuan untuk menghimpun data-data dari database yang berhubungan dengan proses Algoritma Genetika yaitu membuat gen. Dalam inisialisasi awal dibutuhkan variabel berbentuk array dan list of array yang berfungsi untuk menampung parameter dan atau value yang diambil dari database.
Public Function cekTerbaik() Dim optimal As Integer = -1 Dim maksimal As Integer = 0 Dim isTerbaik As Boolean = False
For i As Integer = 0 To _jumlahKromosom - 1 If _kromosom(maksimal)._fitness < _kromosom(i)._fitness Then maksimal = i End If If _kromosom(maksimal)._fitness = 1 Then optimal = maksimal Exit For End If Next
If Not optimal = -1 Then
_kromosomTerbaik = _kromosom(optimal) isTerbaik = True Else _kromosomTerbaik = _kromosom(maksimal) isTerbaik = False End If Return isTerbaik End Function End Class
Gambar 4.10 Array value dalam variabel mataPelajaran
4.2.2 Inisialisasi Algoritma Genetika
Setelah mendapatkan beberapa value dari inisialisasi awal, hal berikutnya adalah membuat kromosom. Variabel Populasi per gen menentukan jumlah kromosom yang dibuat, semakin tinggi nilai variabelnya semakin banyak pula jumlah kromosom yang diciptakan.
Pada gambar di atas dapat terlihat bahwa variabel kromosom memiliki nilai list of array 10 karena parameter yang diberikan untuk Populasi per generasi pada form adalah 10. Pada masing-masing list of array terdapat variabel gen yang berfungsi untuk menampung nilai gen yang terbentuk dari data mata pelajaran, guru pengampu, ruang, dan waktu dalam bentuk array.
4.2.3 Hitung Fitness
Pada hitung fitness, setiap kromosom akan dihitung satu persatu nilai fitnessnya. Apabila fitness bernilai mendekati 1 atau nilainya 1 maka kromosom pada indeks itulah yang akan dipilih.
Gambar 4.12 Nilai fitness pada salah satu kromosom
Untuk menghitung fitness perlu dihitung terlebih dahulu nilai variabel pendukungnya. Sub class hitungGuruBentrok dan hitungRuanganBentrok berfungsi untuk mengidentifikasi berapa value untuk variabel _tabrakanG untuk guru dan _tabrakanR untuk ruang. Jadi gambaran sederhananya kalau pada gen di dalam kromosom ada yang sama akan mengurangi nilai variabelnya. Dalam hal ini diasumsikan apabila ada guru yang sama mengajar di kelas berbeda dalam satu waktu maka akan terjadi bentrokan, begitu pula pada ruangan.
Variabel _fitness bertipe single, karena dengan tipe data single nilai didapatkan bisa utuh. Berbeda dengan tipe data decimal yang sangat presisi pada setiap perhitungnya, tipe data single hanya mengandalkan floating number itulah yang
membuatnya lebih cepat memproses perhitungan. Sebagai perbandingan saat membagi angka 1 dengan 3 kemudian dikali lagi 3 maka hasilnya adalah 0.9999 kalau menggunakan tipe data decimal, tapi menghasilkan nilai 1 apabila menggunakan tipe data single. Maka dari itu dipilihlah tipe data single untuk menghitung fitness yang bernilai angka desimal yang banyak. Akan tetapi tipe data ini tidak disarankan untuk perhitungan matematika karena hanya mempunyai panjang 16 bit.
Gambar 4.13 Salah satu kromosom yang nilai fitnessnya 1
4.2.4 Seleksi
Setelah mendapat kromosom dengan nilai fitness 1 proses belum selesai, karena biasanya yang memiliki nilai fitness 1 tidak hanya satu kromosom saja. Oleh sebab itulah dilakukan seleksi.
Pada proses seleksi ada beberapa tahapan yaitu mencari nilai total fitness semua kromosom, mencari probabilitas masing-masing fitness pada setiap kromosom, mencari nilai kumulatif masing-masing fitness pada setiap kromosom, dan yang terakhir memilih kromosom yang lolos seleksi.
Gambar 4.14 Kromosom yang telah terseleksi
4.2.5 Crossover / Kawin Silang
Crossover atau bisa juga disebut kawin silang berfungsi untuk meng-crossover kromosom-kromosom dari hasil seleksi sehingga menghasilkan individu baru. Pada praktiknya, melakukan crossover tidaklah mudah. Sebelum di-crossover variabel terlebih dahulu dimasukkan ke dalam variabel bertipe string builder. Tipe data string builder dipilih karena ada banyak looping yang berisi banyak value. Value dari setiap variabel tersebut kemudian digunakan untuk mengisi parameter dari variabel dengan nama sebelum1 dan sebelum2 yang nantinya akan di-crossover. Kelebihan dari tipe data string builder adalah value dapat diisi perbagian, sehingga value dapat diambil pada
bagian belakang untuk kemudian dijadikan bahan untuk melakukan crossover.
Gambar 4.15 Value sebelum crossover (string builder data type)
Gambar 4.16 Value sesudah crossover (string builder data type)
4.2.6 Mutasi
Mutasi digunakan untuk mendapatkan hasil tidak terduga dari suatu solusi (salah satu atau beberapa value dalam kromosom) dengan cara merubah value dari gen secara acak yang membuat gen tersebut berevolusi. Solusi itu memberikan nilai yang berbeda untuk fungsi fitness. Mutasi hanya merubah suatu kromosom, dan tidak berpengaruh kepada kromosom yang lainnya dalam populasi.
Gambar 4.17 Gen dari kromosom yang telah bermutasi
4.2.7 Cek Fitness Terbaik
Setelah melalui banyak proses seperti yang telah dijelaskan, algoritma genetika masih mempunyai satu proses terakhir sebelum mencapai hasil. Kromosom dari populasi yang telah dibuat dicari nilai fitness yang paling tinggi. Jadi semua kromosom dicari nilai fitnessnya, dengan begitu didapatlah kromosom yang mempunyai nilai fitness tertinggi. Apabila dalam sebuah populasi tidak menemukan kromosom terbaik, maka akan dilakukan proses ulang dari awal pembentukan gen sampai cek fitness terbaik lagi sampai ditemukan fitness yang terbaik.
Gambar 4.18 Kromosom terbaik ditemukan
4.2.8 Hasil
Hasil akan langsung ditampilkan pada DataGridView di samping menu variabel, dengan begitu jadwal langsung dapat lihat. Apabila data tidak ditampilkan maka tinggal klik tombol proses dan aplikasi akan meng-generate hasil yang lainnya.
Gambar 4.16 Hasil Jadwal
4.3 Analisa Sistem
Setelah melalui proses yang panjang dan rumit, aplikasi berhasil mencapai tujuan utam yaitu menghasilkan jadwal tanpa adanya tabrakan. Dari hasil pengujian diatas dapat diketahui bahwa semua data telah dimasukkan dan telah diproses menggunakan algoritma genetika oleh Skema.
Akan tetapi dapat terlihat masih ada beberapa bug yang sebenarnya tidak terlalu fatal akan tetapi tetap harus ada perbaikan untuk versi selanjutnya. Karena maintenance harus selalu dilakukan agar aplikasi yang dibuat mempunyai bug seminimal mungkin.