DAFTAR PUBLIKASI PENULIS
No
Judul Artikel
Penulis
{
Lampiran Skript Program
FrmBuildJadwal
#define SAVE_AS_XL
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
using csPenjadwalanGenetika;
using IniParser;
using Excel = Microsoft.Office.Interop.Excel;
namespace csPenjadwalanGenetika
{
publicpartialclassFrmBuildJadwal : Form
{
privateint maxIterasi;
privateint populasi;
ClassGenetik genetik;
privatereadonlyint kode_jumat;
privatereadonlyint kode_dhuhur;
privatereadonlyint[] range_jumat;
readonlyClassDbConnect _dbConnect = newClassDbConnect();
staticreadonlyFileIniDataParser parser = newFileIniDataParser(); readonlyIniData data = parser.LoadFile("config.ini");
//solution
privateint[,] jadwal_kuliah;
InitializeComponent();
//load config
txtJumlahPopulasi.Text = data["genetik"]["populasi"]; numCrossover.Text = data["genetik"]["crossover"]; numMutasi.Text = data["genetik"]["mutasi"]; txtIterasi.Text = data["genetik"]["max_iterasi"];
kode_jumat = int.Parse(data["genetik"]["kode_jumat"]); kode_dhuhur = int.Parse(data["genetik"]["kode_dhuhur"]); range_jumat = data["genetik"]["range_jumat"].Split( '-').ToIntArray();
}
privatevoid FrmBuildJadwal_Load(object sender, EventArgs e) {
}
privatevoid btnTutup_Click(object sender, EventArgs e) {
Close();
}
privatevoid btnProses_Click(object sender, EventArgs e) {
constint GANJIL = 1;
constint GENAP = 0;
int jenis_semester = cmbSemester.Text == "GANJIL" ? GANJIL : GENAP; string tahun_akademik = cmbTahunAkademik.Text;
populasi = int.Parse(txtJumlahPopulasi.Text);
if (populasi % 2 != 0)
{
MessageBox.Show("Populasi harus kelipatan 2"); return;
float crossOver = float.Parse(numCrossover.Text); //(float)0.7;
float mutasi = float.Parse(numMutasi.Text); //(float)0.4;
maxIterasi = int.Parse(txtIterasi.Text);
genetik = newClassGenetik(
jenis_semester, tahun_akademik,
populasi, crossOver, mutasi,
kode_jumat, range_jumat, kode_dhuhur);
genetik.AmbilData();
genetik.Inisialisasi();
if (!worker.IsBusy)
{
worker.RunWorkerAsync();
btnProses.Enabled = false;
DisableAllParamComponent(true);
btnStop.Enabled = true;
}
}
privatevoid label9_Click(object sender, EventArgs e) {
//MessageBox.Show(
// "Kenapa? \n" +
// "Karena prinsip yang digunakan adalah pernikahan Monogami\n" );
}
privatevoid DisableAllParamComponent(bool disabled)
{
cmbSemester.Enabled = cmbTahunAkademik.Enabled =
txtJumlahPopulasi.Enabled =
numCrossover.Enabled = numMutasi.Enabled =
txtIterasi.Enabled = !disabled;
}
{
object misValue = System.Reflection.Missing.Value;
var xlApp = new Excel.ApplicationClass(); var xlWorkBook = xlApp.Workbooks.Add(misValue);
var xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); int i = 0;
int j = 0;
//export header
for (i = 1; i <= dtGridView.Columns.Count; i++)
{
xlWorkSheet.Cells[1, i] = dtGridView.Columns[i -
1].HeaderText;
}
//export data
for (i = 1; i <= dtGridView.RowCount; i++)
{
for (j = 1; j <= dtGridView.Columns.Count; j++)
{
xlWorkSheet.Cells[i + 1, j] = dtGridView.Rows[i -
1].Cells[j - 1].Value;
}
}
//set font Khmer OS System to data range
Excel.Range myRange =
xlWorkSheet.get_Range(xlWorkSheet.Cells[1, 1],
xlWorkSheet.Cells[dtGridView.RowCount + 1, dtGridView.Columns.Count]);
Excel.Font x = myRange.Font; x.Name = "Arial";
x.Size = 10;
//set bold font to column header
myRange = xlWorkSheet.get_Range(xlWorkSheet.Cells[1, 1],
xlWorkSheet.Cells[1, dtGridView.Columns.Count]);
x.Bold = true;
//autofit all columns
myRange.EntireColumn.AutoFit();
xlApp.DisplayAlerts = false;
xlWorkBook.SaveAs(
Path.GetDirectoryName(Application.ExecutablePath) + "\\report", #if(SAVE_AS_XL)
Excel.XlFileFormat.xlWorkbookNormal, #else
Excel.XlFileFormat.xlHtml,
#endif
misValue,
misValue,
misValue,
misValue,
Excel.XlSaveAsAccessMode.xlExclusive, misValue,
misValue,
misValue,
misValue,
misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
privatestaticvoid releaseObject(object obj)
{
try
{
}
catch (Exception ex) {
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect(); }
}
privatedelegatevoidUpdateUIDelegate(int i, int max, float[] fitnessAfterMutation, bool found);
privatevoid UpdateUI(int i, int max, float[] fitnessAfterMutation, bool
found)
{
if (lblPosition.InvokeRequired)
{
lv.Invoke(newUpdateUIDelegate(UpdateUI), i, max, fitnessAfterMutation, found);
}
else
{
progressBar.Value = (int)((i + 1f) * 100 / max);
lblPosition.Text = string.Format("Generasi ke {0}", (i + 1).ToString(CultureInfo.InvariantCulture));
//if(i == 0) lv.Items.Clear();
float Rata2Fitness = 0;
ListViewItem[] lvItems = newListViewItem[populasi];
string namaSeries = "cr " + numCrossover.Value.ToString() + " | mt " + numMutasi.Value.ToString();
for (int j = 0; j < populasi; j++)
if (fitnessAfterMutation[j] == 1) {
//break;
Debug.WriteLine("DITEMUKAN"); }
var lvItem = newListViewItem((j +
1).ToString(CultureInfo.InvariantCulture));
lvItem.SubItems.Add(fitnessAfterMutation[j].ToString(CultureInfo.InvariantC ulture));
lvItems[j] = lvItem;
Rata2Fitness += fitnessAfterMutation[j];
//GRAFIKFitness---
if (chartFitness.Series.IndexOf(namaSeries) == -1)
{
chartFitness.Series.Add(namaSeries);
chartFitness.Series[namaSeries].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; }
chartFitness.Series[namaSeries].Points.AddXY(i,
(fitnessAfterMutation[j]));
//end
GRAFIKFitness---
}
lv.BeginUpdate();
lv.Items.Clear();
lv.Items.AddRange(lvItems);
lv.EndUpdate();
lblRata2Fitness.Text = string.Format(
(Rata2Fitness /
populasi).ToString(CultureInfo.InvariantCulture));
//GRAFIK
rata2Fitnes---
if (chartRata2Fitnes.Series.IndexOf(namaSeries) == -1)
{
chartRata2Fitnes.Series[namaSeries].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; }
chartRata2Fitnes.Series[namaSeries].Points.AddXY(i,
(Rata2Fitness / populasi));
//end
Grafik---
if (found)
{
btnProses.Enabled = true;
DisableAllParamComponent(false);
btnStop.Enabled = false;
_dbConnect.ExecuteNonQuery("TRUNCATE TABLE jadwal_kuliah");
for (var k = 0; k < jadwal_kuliah.GetLength(0); k++)
{
var q = string.Format("INSERT INTO
jadwal_kuliah(kode_pengampu,kode_jam,kode_hari,kode_ruang) " +
"VALUES({0},{1},{2},{3})",
jadwal_kuliah[k, 0],
jadwal_kuliah[k, 1],
jadwal_kuliah[k, 2],
jadwal_kuliah[k, 3]);
_dbConnect.ExecuteNonQuery(q);
}
//}
//tampilkan
conststring query = "SELECT e.nama as Hari," +
" Concat_WS('-', concat('(', g.kode), concat( (SELECT kode" +
" FROM jam " +
" WHERE kode = (SELECT jm.kode " +
" WHERE
MID(jm.range_jam,1,5) = MID(g.range_jam,1,5)) + (c.sks - 1)),')')) as SESI, " +
" Concat_WS('-', MID(g.range_jam,1,5)," +
" (SELECT MID(range_jam,7,5) " +
" FROM jam " +
" WHERE kode = (SELECT jm.kode " +
" FROM jam jm " +
" WHERE MID(jm.range_jam,1,5) = MID(g.range_jam,1,5)) + (c.sks - 1))) as Jam_Kuliah, " + //" b.kode_mk as `Kode MK`," +
" c.nama as `Nama MK`," +
" c.sks as SKS," +
" c.semester as Smstr," +
" b.kelas as Kelas," +
" d.nama as Dosen," +
" f.nama as Ruang " +
"FROM jadwal_kuliah a " +
"LEFT JOIN pengampu b " +
"ON a.kode_pengampu = b.kode " +
"LEFT JOIN mata_kuliah c " +
"ON b.kode_mk = c.kode " +
"LEFT JOIN dosen d " +
"ON b.kode_dosen = d.kode " +
"LEFT JOIN hari e " +
"ON a.kode_hari = e.kode " +
"LEFT JOIN ruang f " +
"ON a.kode_ruang = f.kode " +
"LEFT JOIN jam g " +
"ON a.kode_jam = g.kode " +
"order by e.kode asc,Jam_Kuliah asc;";
var dt = _dbConnect.GetRecord(query);
dtGridView.DataSource = dt;
}
}
{
btnProses.Enabled = true;
DisableAllParamComponent(false);
btnStop.Enabled = false;
}
}
privatevoid btnStop_Click(object sender, EventArgs e) {
if (!worker.WorkerSupportsCancellation) return;
worker.CancelAsync();
btnProses.Enabled = true;
DisableAllParamComponent(false);
btnStop.Enabled = false;
}
privatevoid FrmBuildJadwal_FormClosing(object sender, FormClosingEventArgs
e)
{
if (!worker.IsBusy) return;
MessageBox.Show("Matikan dulu proses yang sedang berjalan!", "Informasi",
MessageBoxButtons.OK, MessageBoxIcon.Warning); e.Cancel = true;
}
privatevoid worker_DoWork(object sender, DoWorkEventArgs e) {
Stopwatch stopwatch = newStopwatch(); stopwatch.Start();
//loop here
for (int i = 0; i < maxIterasi; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
float[] fitness = genetik.HitungFitness();
genetik.Seleksi(fitness);
genetik.StartCrossOver();
float[] fitnessAfterMutation = genetik.Mutasi();
for (var j = 0; j < fitnessAfterMutation.Length; j++)
{
//Debug.WriteLine(j + " : " + fitnessAfterMutation[j]);
if (ClassHelper.AlmostEquals(fitnessAfterMutation[j], 1.0, 0)) {
jadwal_kuliah = genetik.GetIndividu(j);
UpdateUI(i, maxIterasi, fitnessAfterMutation,
true);
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
MessageBox.Show(string.Format("Solusi ditemukan\n" +
"Waktu yang diperlukan: " +
"{0:00} Jam, {1:00} Menit,\n{2:00} Detik dan {3:00} Milidetik\n" +
"Report disimpan di report.xls",
ts.Hours, ts.Minutes,
ts.Seconds, ts.Milliseconds / 10),
"Informasi", MessageBoxButtons.OK,
MessageBoxIcon.Information);
//---
Export2Excel();
genetik.WriteLog2Disk();
return;
}
}
genetik.WriteLog2Disk();
UpdateUI(i, maxIterasi, fitnessAfterMutation, false);
//end loop here
MessageBox.Show("Solusi TIDAK ditemukan", "Informasi",
MessageBoxButtons.OK, MessageBoxIcon.Warning); //save last log
genetik.WriteLog2Disk();
}
privatevoid btnGrafik_Click(object sender, EventArgs e) {
var myForm = newfrmGrafik(); myForm.Show();
}
}
}
Class Genetika
#define SHOW_LOG
using System;
using System.Globalization;
using System.IO;
using System.Windows.Forms;
namespace csPenjadwalanGenetika
{
internalclassClassGenetik
{
//TODO:NEED INTENSIVE ATTENTIONS
#region Variables
readonlyClassDbConnect _dbConnect = newClassDbConnect();
//
privateconststring PRAKTIKUM = "PRAKTIKUM"; privateconststring TEORI = "TEORI";
privatereadonlyint jenis_semester;
privatereadonlystring tahun_akademik;
privatereadonlyint populasi;
privatereadonlyfloat crossOver;
privatereadonlyfloat mutasi;
privateint[] mata_kuliah; //pengampu
privateint[, ,] individu;
privateint[] sks; //sks terikat pada tabel pengampu
privateint[] dosen;//dosen terikat pada tabel pengampu
privateint[] jam;
privateint[] hari;
privateint[] iDosen;
//waktu keinginan dosen
privatestring[,] waktu_dosen;
privatestring[] jenis_mk;//reguler or praktikum
privateint[] ruangLaboratorium;
privateint[] ruangReguler;
privatestring logAmbilData;
privatestring logInisialisasi;
privatestring log;
privateint[] induk;
//jumat
privatereadonlyint kode_jumat;
privatereadonlyint[] range_jumat;
privatereadonlyint kode_dhuhur;
#endregion
public ClassGenetik(
int jenis_semester, string tahun_akademik, int populasi,
float crossOver, float mutasi,
int kode_jumat, int[] range_jumat, int kode_dhuhur)
{
this.jenis_semester = jenis_semester;
this.tahun_akademik = tahun_akademik;
this.populasi = populasi;
this.crossOver = crossOver;
this.mutasi = mutasi;
this.kode_jumat = kode_jumat;
this.range_jumat = range_jumat;
this.kode_dhuhur = kode_dhuhur;
}
#endregion
#region Ambil data
publicvoid AmbilData()
{
//Fill Array of mata kuliah and SKS Variables
#if(SHOW_LOG)
logAmbilData +=
string.Format("\r===========================[{0}] => Ambil Data....\n",
DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff tt")); #endif
var dtMK_Pengampu = _dbConnect.GetRecord(string.Format(
"SELECT a.kode," +
" b.sks," +
" a.kode_dosen," +
" b.jenis " +
"FROM pengampu a " +
"LEFT JOIN mata_kuliah b " +
"ON a.kode_mk = b.kode " +
"WHERE b.semester%2 = {0} AND a.tahun_akademik = '{1}' " +
"ORDER BY a.kode ASC",
jenis_semester, tahun_akademik));
sks = newint[dtMK_Pengampu.Rows.Count];
dosen = newint[dtMK_Pengampu.Rows.Count];
jenis_mk = newstring[dtMK_Pengampu.Rows.Count];
for (var i = 0; i < dtMK_Pengampu.Rows.Count; i++)
{
mata_kuliah[i] = (int)dtMK_Pengampu.Rows[i][0];
sks[i] = (int)dtMK_Pengampu.Rows[i][1];
dosen[i] = (int)dtMK_Pengampu.Rows[i][2];
jenis_mk[i] = dtMK_Pengampu.Rows[i][3].ToString();//reguler
or praktikum
}
//Fill Array of Jam Variables
var dtJam = _dbConnect.GetRecord("SELECT kode " +
"FROM jam");
jam = newint[dtJam.Rows.Count];
for (var i = 0; i < dtJam.Rows.Count; i++)
{
jam[i] = (int)dtJam.Rows[i][0];
}
//Fill Array of Hari Variables
var dtHari = _dbConnect.GetRecord("SELECT kode " +
"FROM hari " +
"WHERE aktif = 'True'");
hari = newint[dtHari.Rows.Count];
for (var i = 0; i < dtHari.Rows.Count; i++)
{
hari[i] = (int)dtHari.Rows[i][0];
}
var dtRuangReguler = _dbConnect.GetRecord(
string.Format("SELECT kode " +
"FROM ruang " +
"WHERE jenis = '{0}'", TEORI));
ruangReguler = newint[dtRuangReguler.Rows.Count];
{
ruangReguler[i] = (int)dtRuangReguler.Rows[i][0];
}
var dtRuangLaboratorium = _dbConnect.GetRecord(
string.Format("SELECT kode " +
"FROM ruang " +
"WHERE jenis = '{0}'", LABORATORIUM));
ruangLaboratorium = newint[dtRuangLaboratorium.Rows.Count];
for (int i = 0; i < dtRuangLaboratorium.Rows.Count; i++)
{
ruangLaboratorium[i] = (int)dtRuangLaboratorium.Rows[i][0];
}
var dtWaktuDosen = _dbConnect.GetRecord("SELECT kode_dosen, " +
"CONCAT_WS(':',kode_hari,kode_jam) " +
"FROM waktu_tidak_bersedia");
waktu_dosen = newstring[dtWaktuDosen.Rows.Count, 2];
iDosen = newint[dtWaktuDosen.Rows.Count];
for (var i = 0; i < dtWaktuDosen.Rows.Count; i++)
{
iDosen[i] = (int)dtWaktuDosen.Rows[i][0];
//?????????????? ?????????????
waktu_dosen[i, 0] = dtWaktuDosen.Rows[i][0].ToString();
//kode dosen
waktu_dosen[i, 1] = dtWaktuDosen.Rows[i][1].ToString();
//CONCAT_WS(':',kode_hari,kode_jam)
}
#if(SHOW_LOG)
logAmbilData += string.Format(
"Jumlah MataKuliah: {0}\n" +
"Jumlah Jam: {1}\n" +
"Jumlah Hari: {2}\n" +
"Jumlah Ruang: {3}\n",
dtHari.Rows.Count, dtRuangReguler.Rows.Count +
dtRuangLaboratorium.Rows.Count);
#endif
}
#endregion
#region WriteLog2Disk
publicvoid WriteLog2Disk()
{
var filepath = string.Format("{0}\\log.txt",
Path.GetDirectoryName(Application.ExecutablePath));
if (true) File.WriteAllText(filepath, logAmbilData + logInisialisasi + log);
}
#endregion
#region Inisialisasi
publicvoid Inisialisasi()
{
var random = newRandom();
individu = newint[populasi, mata_kuliah.Length, 4];
#if(SHOW_LOG)
logInisialisasi +=
string.Format("\r===========================[{0}] => Ambil Nilai
Parameter....\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff tt")); logInisialisasi += string.Format("Populasi: {0}\n" +
"Crossover: {1}\n" +
"Mutasi: {2}", populasi, crossOver, mutasi);
#endif
for (var i = 0; i < populasi; i++)
{
#if(SHOW_LOG)
"\r\n\n[{0}] => Individu Ke-{1} #MK,JAM,HARI,RUANG",
DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff tt"), (i + 1)); #endif
for (var j = 0; j < mata_kuliah.Length; j++)
{
// Perulangan untuk pembangkitan jadwal
individu[i, j, 0] = j; // Penentuan matakuliah dan
kelas
if (sks[j] == 1)// Penentuan jam secara acak ketika 1 sks
{ individu[i, j, 1] = random.Next(jam.Length); }
if (sks[j] == 2) // Penentuan jam secara acak ketika 2 sks
{ individu[i, j, 1] = random.Next(jam.Length - 1); }
if (sks[j] == 3) // Penentuan jam secara acak ketika 3 sks
{ individu[i, j, 1] = random.Next(jam.Length - 2); }
if (sks[j] == 4) // Penentuan jam secara acak ketika 4 sks
{ individu[i, j, 1] = random.Next(jam.Length - 3); }
//System.Threading.Thread.Sleep(1);
individu[i, j, 2] = random.Next(hari.Length); //
Penentuan hari secara acak
//TODO: jika kuliah reguler => ruang reguler
//TODO: jika kuliah praktikum => ruang lab
//individu[i, j, 3] = random.Next(ruang.Length); // Penentuan ruang secara
acak
if (jenis_mk[j] == TEORI)
{
individu[i, j, 3] =
ruangReguler[random.Next(ruangReguler.Length)];
}
else
{
individu[i, j, 3] =
ruangLaboratorium[random.Next(ruangLaboratorium.Length)];
}
#if(SHOW_LOG)
if (j + 1 < 10)
{
kr = "0" + (j + 1); }
else {
kr = Convert.ToString(j + 1); }
//logInisialisasi += "\r\nKromosom " + kr + " = " +
logInisialisasi += "\r\n" +
mata_kuliah[individu[i, j, 0]] + "," + jam[individu[i, j, 1]] + "," +
hari[individu[i, j, 2]] + "," + individu[i, j, 3];
#endif
}
}
}
#endregion
privatefloat CekFitness(int indv)
{
//float[,] penalty = new float[populasi, 6];
float penalty1 = 0, penalty2 = 0, penalty3 = 0, penalty4 = 0, penalty5 = 0;
for (var i = 0; i < mata_kuliah.Length; i++)
{
for (var j = 0; j < mata_kuliah.Length; j++)//1.Konflik ruang dan waktu dan
3.Konflik dosen
{
//ketika pemasaran matakuliah sama, maka langsung ke perulangan berikutnya
if (i == j) continue;
#region Konflik Ruang dan Waktu
//Ketika jam,hari dan ruangnya sama, maka penalty + satu
if (
(individu[indv, i, 1] == individu[indv, j, 1]) &&
(individu[indv, i, 3] == individu[indv, j, 3])
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[1#A] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}] == Kromosom {5} [{6},{7},{8},{9}]", (i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv, i,
3],
(j + 1), mata_kuliah[individu[indv, j, 0]],
jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv, j, 3]
);
#endif
penalty1 += 1;
}
//Ketika sks lebih dari 1,
//hari dan ruang sama, dan
//jam kedua sama dengan jam pertama matakuliah yang lain, maka penalty + 1
if (sks[i] >= 2)
{
if (
(individu[indv, i, 1] + 1 == individu[indv, j,
1]) &&
(individu[indv, i, 2] == individu[indv, j, 2])
&&
(individu[indv, i, 3] == individu[indv, j, 3])
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[1#B] => Individu ke-{0} ", (indv + 1));
log += string.Format(
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv, i,
3],
(j + 1), mata_kuliah[individu[indv, j, 0]],
jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv, j,
3],
sks[1], sks[j]
);
#endif
penalty1 += 1;
}
}
//Ketika sks lebih dari 2,
//hari dan ruang sama dan
//jam ketiga sama dengan jam pertama matakuliah yang lain, maka penalty + 1
if (sks[i] >= 3)
{
if (
(individu[indv, i, 1] + 2 == individu[indv, j,
1]) &&
(individu[indv, i, 2] == individu[indv, j, 2])
&&
(individu[indv, i, 3] == individu[indv, j, 3])
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[1#C] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv, i,
(j + 1), mata_kuliah[individu[indv, j, 0]],
jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv, j,
3],
sks[1], sks[j]
);
#endif
penalty1 += 1;
}
}
//Ketika sks lebih dari 3,
//hari dan ruang sama dan
//jam keempat sama dengan jam pertama matakuliah yang lain, maka penalty +
1
if (sks[i] >= 4)
{
if (
(individu[indv, i, 1] + 3 == individu[indv, j,
1]) &&
(individu[indv, i, 2] == individu[indv, j, 2])
&&
(individu[indv, i, 3] == individu[indv, j, 3])
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[1#D] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv, i,
3],
(j + 1), mata_kuliah[individu[indv, j, 0]],
jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv, j,
3],
sks[1], sks[j]
#endif
penalty1 += 1;
}
}
#endregion
//______________________Konflik DOSEN
#region Konflik Dosen
if (
//ketika jam sama
individu[indv, i, 1] == individu[indv, j, 1] &&
//dan hari sama
individu[indv, i, 2] == individu[indv, j, 2] &&
//dan dosennya sama
dosen[i] == dosen[j]
)
{
//maka...
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[3#A] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}][DOSEN={12}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}][DOSEN={13}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv, i,
3],
(j + 1), mata_kuliah[individu[indv, j, 0]],
jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv, j,
3],
sks[1], sks[j], dosen[i], dosen[j]
);
#endif
penalty3 += 1;
if (
//jika lebih dari 1 SKS
sks[i] >= 2
)
{
if (
//jam ke-2 == dengan jam ke-1 mk yang lain
(individu[indv, i, 1] + 1) == (individu[indv,
j, 1]) &&
//dan hari sama
(individu[indv, i, 2]) == (individu[indv, j,
2]) &&
//dan dosen sama
dosen[i] == dosen[j]
)
{
//maka...
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[3#B] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}][DOSEN={12}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}][DOSEN={13}]",
(i + 1), mata_kuliah[individu[indv, i,
0]], jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv,
i, 3],
(j + 1), mata_kuliah[individu[indv, j,
0]], jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv,
j, 3],
sks[1], sks[j], dosen[i], dosen[j]
);
#endif
penalty3 += 1;
}
}
if (
sks[i] >= 3
)
{
if (
//jam ke-3 == dengan jam ke-1 mk yang lain
(individu[indv, i, 1] + 2) == (individu[indv,
j, 1]) &&
//dan hari sama
(individu[indv, i, 2]) == (individu[indv, j,
2]) &&
//dan dosen sama
dosen[i] == dosen[j]
)
{
//maka...
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[3#C] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}][DOSEN={12}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}][DOSEN={13}]",
(i + 1), mata_kuliah[individu[indv, i,
0]], jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv,
i, 3],
(j + 1), mata_kuliah[individu[indv, j,
0]], jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv,
j, 3],
sks[1], sks[j], dosen[i], dosen[j]
);
#endif
penalty3 += 1;
}
}
if (
//jika lebih dari 3 SKS
sks[i] >= 4
{
if (
//jam ke-4 == dengan jam ke-1 mk yang lain
(individu[indv, i, 1] + 3) == (individu[indv,
j, 1]) &&
//dan hari sama
(individu[indv, i, 2]) == (individu[indv, j,
2]) &&
//dan dosen sama
dosen[i] == dosen[j]
)
{
//maka...
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[3#D] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}][SKS={10}][DOSEN={12}] == Kromosom {5} [{6},{7},{8},{9}][SKS={11}][DOSEN={13}]",
(i + 1), mata_kuliah[individu[indv, i,
0]], jam[individu[indv, i, 1]], hari[individu[indv, i, 2]], individu[indv,
i, 3],
(j + 1), mata_kuliah[individu[indv, j,
0]], jam[individu[indv, j, 1]], hari[individu[indv, j, 2]], individu[indv,
j, 3],
sks[1], sks[j], dosen[i], dosen[j]
);
#endif
penalty3 += 1;
}
}
#endregion
}//end 1.Konflik ruang dan waktu dan 3.Konflik dosen
#region Konflik sholat Jumat
if (individu[indv, i, 2] + 1 == (kode_jumat)) //2.Konflik sholat jumat
{
if (sks[i] == (1))
{
if (
individu[indv, i, 1] == (range_jumat[0] - 1) ||
individu[indv, i, 1] == (range_jumat[1] - 1) ||
individu[indv, i, 1] == (range_jumat[2] - 1)
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[2#SKS = 1] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3]
);
#endif
penalty2 += 1;
}
}
if (sks[i] == (2))
{
if (
individu[indv, i, 1] == (range_jumat[0] - 2) ||
individu[indv, i, 1] == (range_jumat[0] - 1) ||
individu[indv, i, 1] == (range_jumat[1] - 1) ||
individu[indv, i, 1] == (range_jumat[2] - 1)
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[2#SKS = 2] => Individu ke-{0} ", (indv + 1));
log += string.Format(
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3]
);
#endif
penalty2 += 1;
}
}
if (sks[i] == (3))
{
if (
individu[indv, i, 1] == (range_jumat[0] - 3) ||
individu[indv, i, 1] == (range_jumat[0] - 2) ||
individu[indv, i, 1] == (range_jumat[0] - 1) ||
individu[indv, i, 1] == (range_jumat[1] - 1) ||
individu[indv, i, 1] == (range_jumat[2] - 1)
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[2#SKS = 3] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3]
);
#endif
penalty2 += 1;
}
}
if (sks[i] == (4))
{
individu[indv, i, 1] == (range_jumat[0] - 4) ||
individu[indv, i, 1] == (range_jumat[0] - 3) ||
individu[indv, i, 1] == (range_jumat[0] - 2) ||
individu[indv, i, 1] == (range_jumat[0] - 1) ||
individu[indv, i, 1] == (range_jumat[1] - 1) ||
individu[indv, i, 1] == (range_jumat[2] - 1)
)
{
#if(SHOW_LOG)
log += string.Format("\nHardConstraint[2#SKS = 4] => Individu ke-{0} ", (indv + 1));
log += string.Format(
"Kromosom {0} [{1},{2},{3},{4}]",
(i + 1), mata_kuliah[individu[indv, i, 0]],
jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3]
);
#endif
penalty2 += 1;
}
}
}
#endregion
#region Konflik dengan Waktu Keinginan Dosen
//Boolean penaltyForKeinginanDosen = false;
for (int j = 0; j < iDosen.Length; j++)
{
if (dosen[i] == iDosen[j])
{
string[] hari_jam = waktu_dosen[j, 1].Split(':');
if (
jam[individu[indv, i,
hari[individu[indv, i,
2]].ToString(CultureInfo.InvariantCulture) == hari_jam[0] )
{
//penaltyForKeinginanDosen = true;
#if(SHOW_LOG)
log += string.Format(
"\nHardConstraint[4] => Individu ke {0} Kromosom {1}[{2},{3},{4},{5}][Dosen = {6}]",
(indv + 1), (i + 1),
mata_kuliah[individu[indv, i, 0]], jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3], iDosen[j]);
#endif
penalty4 += 1;
}
}
}
#endregion
#region Konflik waktu dhuhur
if (individu[indv, i, 1] == (kode_dhuhur - 1))
{
#if(SHOW_LOG)
log += string.Format(
"\nHardConstraint[5] => Individu ke {0} Kromosom {1}[{2},{3},{4},{5}][Dosen = {6}]",
(indv + 1), (i + 1),
mata_kuliah[individu[indv, i, 0]], jam[individu[indv, i, 1]],
hari[individu[indv, i, 2]], individu[indv,
i, 3], dosen[i]);
#endif
penalty5 += 1;
#endregion
}
#if(SHOW_LOG)
log += string.Format("\nPenalty Individu ke-{0} : {1} \n", (indv + 1), penalty1 + penalty2 + penalty3 + penalty4 + penalty5);
#endif
float fitness = 1 / (1 + (penalty1 + penalty2 + penalty3 + penalty4 +
penalty5));
return fitness;
}
#region Hitung Fitness
publicfloat[] HitungFitness()
{
//hard constraint
//1.Konflik ruang dan waktu
//2.Konflik sholat jumat
//3.Konflik dosen
//4.Konflik keinginan waktu dosen
//5.Konflik waktu dhuhur
//=>6.praktikum harus pada ruang lab {telah ditetapkan dari awal perandoman
// bahwa jika praktikum harus ada pada LAB dan mata kuliah reguler harus
// pada kelas reguler
//soft constraint //TODO
log = null;
float[] fitness = newfloat[populasi];
#if(SHOW_LOG)
log += "\nRule:\n" +
"Hard Constraint:\n" +
"[1] => Konflik ruang dan Waktu\n" +
"[1#A] => jam,hari dan ruangnya sama\n" +
"[1#B] => sks lebih dari 1 + hari dan ruang sama + jam kedua sama dengan jam pertama matakuliah yang lain\n" +
"[1#C] => sks lebih dari 2 + hari dan ruang sama + jam ketiga sama dengan jam pertama matakuliah yang lain\n" +
"[1#D] => sks lebih dari 3 + hari dan ruang sama + jam keempat sama dengan jam pertama matakuliah yang lain\n" +
"[2] => Konflik sholat jumat\n" +
"[2#SKS = 1] => sks = 1\n" +
"[2#SKS = 2] => sks = 2\n" +
"[2#SKS = 3] => sks = 3\n" +
"[2#SKS = 4] => sks = 4\n" +
"[3] => Konflik Dosen\n" +
"[3#SKS = 1] => sks = 1\n" +
"[3#SKS = 2] => sks = 2\n" +
"[3#SKS = 3] => sks = 3\n" +
"[3#SKS = 4] => sks = 4\n" +
"[4] => Konflik keinginan waktu dosen\n"; #endif
for (var indv = 0; indv < populasi; indv++)
{
//Cek Fitness
fitness[indv] = CekFitness(indv);
#if(SHOW_LOG)
log += string.Format(
"Fitness Individu ke-{0} : {1} \n", (indv + 1), fitness[indv]); #endif
}
//~~~~~buble sort~~~~~~
string[] sort = newstring[populasi];
//fill the data
#if(SHOW_LOG)
log += "\nReview Penalty dan Fitness: (Best Fitness => Worst Fitness)";
#endif
for (int i = 0; i < populasi; i++)
{
sort[i] = string.Format("\nIndividu {0} :Fitness {1}", (i + 1), fitness[i]);
}
try
{
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i = 0; i < populasi - 1; i++)
{
string[] strI = sort[i].Split(',');
float fitI = float.Parse(string.Format("0,{0}", strI[1]));
string[] strJ = sort[i + 1].Split(',');
float fitJ = float.Parse(string.Format("0,{0}", strJ[1]));
if (fitI < fitJ)
{
string sTmp = sort[i];
sort[i] = sort[i + 1];
sort[i + 1] = sTmp;
swapped = true;
}
}
}
}
MessageBox.Show("Kemungkinan data tidak ada untuk Tahun Akademik dan Semester yang terpilih!", "ERROR", MessageBoxButtons.OK,
MessageBoxIcon.Error); throw;
}
#if(SHOW_LOG)
for (var i = 0; i < populasi; i++)
{
log += sort[i];
}
#endif
return fitness;
}
#endregion
#region Seleksi
publicvoid Seleksi(float[] fitness)
{
var jumlah = 0;
int[] rank = newint[populasi];
induk = newint[populasi];
#if(SHOW_LOG)
log += "\n\n"; #endif
for (var i = 0; i < populasi; i++)
{ //proses ranking berdasarkan nilai fitness
rank[i] = 1;
for (var j = 0; j < populasi; j++)
{ //ketika nilai fitness jadwal sekarang lebih dari nilai
fitness jadwal yang lain,
//ranking + 1;
//if (i == j) continue;
{
rank[i] += 1;
}
}
#if(SHOW_LOG)
log += string.Format("Ranking individu {0} = {1}\n", (i + 1), rank[i]);
#endif
jumlah += rank[i];
}
#if(SHOW_LOG)
log += string.Format("[jumlah:{0}] ", jumlah); #endif
var random = newRandom();
#if(SHOW_LOG)
log += "\r\n\nProses Seleksi:\r\n" +
"Induk terpilih: "; #endif
for (var i = 0; i < induk.Length; i++)
{
//proses seleksi berdasarkan ranking yang telah dibuat
//int nexRandom = random.Next(1, jumlah);
//random = new Random(nexRandom);
var target = random.Next(jumlah);
var cek = 0;
for (var j = 0; j < rank.Length; j++)
{
cek += rank[j];
if (cek >= target)
{
induk[i] = j;
#if(SHOW_LOG)
log += string.Format("Individu {0} , ", (j + 1)); #endif
break;
}
}
}
#endregion
//Crossover---
publicvoid StartCrossOver()
{
#if(SHOW_LOG)
log += string.Format("\r\n\r\n===========================PROSES CROSSOVER / PINDAH SILANG (CrossOver values = {0})", crossOver);
#endif
int[, ,] individu_baru = newint[populasi, mata_kuliah.Length, 4];
var random = newRandom();
for (int i = 0; i < populasi; i += 2) //perulangan untuk jadwal yang
terpilih
{
int b = 0;
int nexRandom = random.Next(1, 1000);
random = newRandom(nexRandom); double cr = random.NextDouble();
if (cr < crossOver)
{
//ketika nilai random kurang dari nilai probabilitas pertukaran
//maka jadwal mengalami prtukaran
int a = random.Next(mata_kuliah.Length - 1);
while (b <= a)
{
b = random.Next(mata_kuliah.Length);
}
//penentuan jadwal baru dari awal sampai titik pertama
{
for (int k = 0; k < 4; k++)
{
individu_baru[i, j, k] = individu[induk[i], j,
k];
individu_baru[i + 1, j, k] = individu[induk[i +
1], j, k];
}
}
//Penentuan jadwal baru dai titik pertama sampai titik kedua
for (int j = a; j < b; j++)
{
for (int k = 0; k < 4; k++)
{
individu_baru[i, j, k] = individu[induk[i + 1],
j, k];
individu_baru[i + 1, j, k] = individu[induk[i],
j, k];
}
}
//penentuan jadwal baru dari titik kedua sampai akhir
for (int j = b; j < mata_kuliah.Length; j++)
{
for (int k = 0; k < 4; k++)
{
individu_baru[i, j, k] = individu[induk[i], j,
k];
individu_baru[i + 1, j, k] = individu[induk[i +
1], j, k];
}
}
#if(SHOW_LOG)
log += string.Format("\r\nNilai Random = {0}, maka CrossOver terjadi antara induk {1} dengan induk {2} pada titik {3} dan titik {4}", cr, (i + 1), (i + 2), (a + 1), (b + 1));
}
else
{//Ketika nilai random lebih dari nilai probabilitas
pertukaran, maka jadwal baru sama dengan jadwal terpilih
for (int j = 0; j < mata_kuliah.Length; j++)
{
for (int k = 0; k < 4; k++)
{
individu_baru[i, j, k] = individu[induk[i], j,
k];
individu_baru[i + 1, j, k] = individu[induk[i +
1], j, k];
}
}
#if(SHOW_LOG)
log += string.Format("\r\nNilai random = {0}, maka CrossOver TIDAK TERJADI antara induk {1} dengan induk {2}", cr, (i + 1), (i + 2));
#endif
}
}
//tampilkan individu baru
#if(SHOW_LOG)
for (int i = 0; i < populasi; i++)
{
log += string.Format(
"\r\n\n[{0}] => Individu Baru Ke-{1} #MK,JAM,HARI,RUANG",
DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff tt"), (i + 1));
for (int j = 0; j < mata_kuliah.Length; j++)
{
String kr; if (j + 1 < 10)
{
else
{
kr = Convert.ToString(j + 1); }
//log += "\r\nKromosom " + kr + " = " +
log += "\r\n" +
mata_kuliah[individu_baru[i, j, 0]] + "," + jam[individu_baru[i, j, 1]] + "," +
hari[individu_baru[i, j, 2]] + "," + individu_baru[i, j, 3];
}
}
#endif
individu = newint[populasi, mata_kuliah.Length, 4];
Array.Copy(individu_baru, individu, individu_baru.Length); }
publicfloat[] Mutasi()
{
float[] fitness = newfloat[populasi];
#if(SHOW_LOG)
log += "\r\n\r===========================PROSES MUTASI / PENGGANTIAN KOMPONEN PENJADWALAN SECARA ACAK:\n";
#endif
var random = newRandom();
//proses perandoman atau penggantian komponen untuk tiap jadwal baru
for (int i = 0; i < populasi; i++)
{
int nexRandom = random.Next(1, 1000);
random = newRandom(nexRandom); double r = random.NextDouble();
//System.Threading.Thread.Sleep(20);
#if(SHOW_LOG)
#endif
//Ketika nilai random kurang dari nilai probalitas Mutasi,
//maka terjadi penggantian komponen
if (r < mutasi)
{
//Penentuan pada matakuliah dan kelas yang mana yang akan dirandomkan atau
diganti
int krom = random.Next(mata_kuliah.Length);
switch (sks[krom])
{
case 1:
individu[i, krom, 1] = random.Next(jam.Length);
break;
case 2:
individu[i, krom, 1] = random.Next(jam.Length -
1);
break;
case 3:
individu[i, krom, 1] = random.Next(jam.Length -
2);
break;
case 4:
individu[i, krom, 1] = random.Next(jam.Length -
3);
break;
}
//Proses penggantian hari
individu[i, krom, 2] = random.Next(hari.Length);
//proses penggantian ruang
//individu[i, krom, 3] = random.Next(ruang.Length);
if (jenis_mk[krom] == TEORI)
{
individu[i, krom, 3] =
ruangReguler[random.Next(ruangReguler.Length)];
else
{
individu[i, krom, 3] =
ruangLaboratorium[random.Next(ruangLaboratorium.Length)];
}
#if(SHOW_LOG)
msg = string.Format("terjadi mutasi, pada kromosom ke {0}", (krom + 1));
#endif
}
fitness[i] = CekFitness(i);
#if(SHOW_LOG)
log += string.Format("Individu {0}: Nilai Random = {1}, maka {2} (Fitness = {3})\n\n", (i + 1), r, msg, fitness[i]);
#endif
}
return fitness;
}
publicint[,] GetIndividu(int indv)
{
//return individu;
int[,] individu_solusi = newint[mata_kuliah.Length, 4];
for (int j = 0; j < mata_kuliah.Length; j++)
{
individu_solusi[j, 0] = mata_kuliah[individu[indv, j, 0]];
individu_solusi[j, 1] = jam[individu[indv, j, 1]];
individu_solusi[j, 2] = hari[individu[indv, j, 2]];
//individu_solusi[j, 3] = ruang[individu[indv, j, 3]];
if (jenis_mk[j] == TEORI)
{