示例#1
0
        public void Solve(string filepath, int AlgoChoosed)
        {
            int i = 0;
            int j = 0;

            VariasiRuangan[] variasiRuangan;
            FileParser       fp = new FileParser(filepath);

            string[] jadwal = fp.getJadwal();

            //Isi listMK
            listMK = new List <MataKuliah>();
            for (int k = 0; k < fp.getBanyakJadwal(); k++)
            {
                MataKuliah mk = new MataKuliah(jadwal[k]);
                listMK.Add(mk);
            }

            string[] rrr = fp.getRuangan();

            //Isi ListR
            listR = new List <Ruangan>();
            for (int k = 0; k < fp.getBanyakRuangan(); k++)
            {
                Ruangan r = new Ruangan(rrr[k]);
                listR.Add(r);
            }
            listR          = sortListRuangan(listR);
            variasiRuangan = new VariasiRuangan[fp.getBanyakRuangan()];
            while (i < fp.getBanyakRuangan())
            {
                variasiRuangan[j]         = new VariasiRuangan();
                variasiRuangan[j].nama    = listR[i].getNamaRuangan();
                variasiRuangan[j].variasi = 1;
                i++;
                if (i >= fp.getBanyakRuangan())
                {
                    break;
                }
                while (variasiRuangan[j].nama.Equals(listR[i].getNamaRuangan(), StringComparison.Ordinal))
                {
                    variasiRuangan[j].variasi++;
                    i++;
                    if (i >= fp.getBanyakRuangan())
                    {
                        break;
                    }
                }
                if (i >= fp.getBanyakRuangan())
                {
                    break;
                }
                j++;
            }

            //Cek Algo yang dipakai
            if (AlgoChoosed == 1)
            {
                RandomRestart rr = new RandomRestart();
                rr.randomRestart(ref listMK, listR, fp.getBanyakJadwal(), fp.getBanyakRuangan(), variasiRuangan);
            }
            if (AlgoChoosed == 2)
            {
                SimulatedAnnealing sa = new SimulatedAnnealing();
                sa.simulatedAnnealing(ref listMK, listR, fp.getBanyakJadwal(), fp.getBanyakRuangan(), variasiRuangan);
            }
            if (AlgoChoosed == 3)
            {
                GeneticAlgorithm ga = new GeneticAlgorithm();
                listMK = ga.geneticAlgorithm(500, listMK, listR, fp.getBanyakJadwal(), fp.getBanyakRuangan(), variasiRuangan);
            }

            //Menjalankan perhitungan konflik dan efektifitas
            Checker ch = new Checker();
            Others  ot = new Others();

            ch.hitungKonflik(listMK);

            jmlK = ch.getJumlahKonflik();
            jmlO = ot.hitungEfektif(listMK, listR) * 100;
        }
        public List <MataKuliah> geneticAlgorithm(int stepCount, List <MataKuliah> listMK, List <Ruangan> listR, int banyakJadwal, int banyakRuangan, VariasiRuangan[] varR)
        {
            List <List <MataKuliah> > sample       = new List <List <MataKuliah> >();
            List <List <MataKuliah> > temp         = new List <List <MataKuliah> >();
            List <MataKuliah>         tempSolution = new List <MataKuliah>();

            MataKuliah[] listTemp    = new MataKuliah[banyakJadwal + 1];
            Random       rng         = new Random(Guid.NewGuid().GetHashCode());
            Initializer  init        = new Initializer();
            int          size        = 1024;
            int          minConflict = int.MaxValue;

            int[]             fitness         = new int[size];
            float[]           chanceThreshold = new float[size];
            int               maxFitness      = (banyakJadwal - 1) * (banyakJadwal) / 2;
            int               totalFitness;
            float             randomNumber;
            int               randomNumberI;
            int               index   = 0;
            Checker           check   = new Checker();
            Boolean           found   = false;
            int               minTime = 0;
            int               maxTime = 0;
            IEnumerable <int> possibleDay;

            //Initial generation
            for (int i = 0; i < size; i++)
            {
                init.Initialize(listMK, listR, banyakJadwal, banyakRuangan, varR);
                sample.Add(deepClone(listMK, banyakJadwal));
            }

            //Series of Genetic Algorithm process
            for (int step = 0; step < stepCount; step++)
            {
                index = 0;
                //Console.WriteLine();
                //if (step % 25000 == 0)
                //{
                //Console.WriteLine("Process : " + step);
                //}

                //Calculate fitness function
                totalFitness = 0;
                for (int i = 0; i < size; i++)
                {
                    check.hitungKonflik(sample[i]);
                    fitness[i]   = maxFitness - check.getJumlahKonflik();
                    totalFitness = totalFitness + fitness[i];
                }
                //Console.WriteLine("Fitness function done");

                //Selection chance
                chanceThreshold[0] = ((float)fitness[0]) / ((float)totalFitness);
                for (int i = 1; i < size; i++)
                {
                    chanceThreshold[i] = chanceThreshold[i - 1] + ((float)fitness[i]) / ((float)totalFitness);
                }
                //Console.WriteLine("Selection chance done");

                //Selection
                temp = new List <List <MataKuliah> >();
                for (int i = 0; i < size; i++)
                {
                    randomNumber = ((float)rng.Next(0, 1001)) / 1000f;
                    while ((index < size) && (randomNumber > chanceThreshold[index]))
                    {
                        index++;
                    }
                    if (index == size)
                    {
                        index = (size - 1);
                    }
                    temp.Add(deepClone(sample[index], banyakJadwal));
                }

                sample = temp;
                //Console.WriteLine("Selection done");

                //Crossover
                for (int i = 0; i < size; i = i + 2)
                {
                    randomNumberI = rng.Next(0, banyakJadwal);
                    if (randomNumberI != (banyakJadwal - 1))
                    {
                        index = (randomNumberI + 1);
                        int length = (banyakJadwal - index);
                        sample[i].CopyTo((index), listTemp, 0, (banyakJadwal - index));
                        for (int j = 0; j < length; j++)
                        {
                            sample[i][index]     = sample[i + 1].GetRange(index, 1)[0];
                            sample[i + 1][index] = listTemp[j];
                            index++;
                        }
                    }
                }
                //Console.WriteLine("Crossover done");

                //Mutation
                for (int i = 0; i < size; i++)
                {
                    index         = 0;
                    found         = false;
                    randomNumberI = rng.Next(0, (banyakJadwal + 1));
                    if (randomNumberI != banyakJadwal)
                    {
                        if (!sample[i][randomNumberI].getRuanganDom().Equals("-", StringComparison.Ordinal))
                        {
                            sample[i][randomNumberI].setRuanganSol(sample[i][randomNumberI].getRuanganDom());
                            while (!found)
                            {
                                if (sample[i][randomNumberI].getRuanganSol().Equals(listR[index].getNamaRuangan(), StringComparison.Ordinal))
                                {
                                    found = true;
                                }
                                else
                                {
                                    index++;
                                }
                            }

                            //Calculate Possible Day
                            possibleDay = sample[i][randomNumberI].getHariDom().Intersect(listR[index].getHariAvailable());

                            //Calculate Possible Time
                            if (listR[index].getjamMulai() > sample[i][randomNumberI].getJamDomAwal())
                            {
                                minTime = listR[index].getjamMulai();
                            }
                            else
                            {
                                minTime = sample[i][randomNumberI].getJamDomAwal();
                            }
                            if (listR[index].getjamAkhir() < sample[i][randomNumberI].getJamDomAkhir())
                            {
                                maxTime = listR[index].getjamAkhir();
                            }
                            else
                            {
                                maxTime = sample[i][randomNumberI].getJamDomAkhir();
                            }
                        }
                        //If there's room restriction
                        else
                        {
                            index = rng.Next(0, banyakRuangan);
                            sample[i][randomNumberI].setRuanganSol(listR[index].getNamaRuangan());
                            //Calculate Possible Day
                            possibleDay = sample[i][randomNumberI].getHariDom().Intersect(listR[index].getHariAvailable());

                            //Calculate Possible Time
                            if (listR[index].getjamMulai() > sample[i][randomNumberI].getJamDomAwal())
                            {
                                minTime = listR[index].getjamMulai();
                            }
                            else
                            {
                                minTime = sample[i][randomNumberI].getJamDomAwal();
                            }
                            if (listR[index].getjamAkhir() < sample[i][randomNumberI].getJamDomAkhir())
                            {
                                maxTime = listR[index].getjamAkhir();
                            }
                            else
                            {
                                maxTime = sample[i][randomNumberI].getJamDomAkhir();
                            }

                            //If assignment is not possible, do reassignment to room
                            while ((possibleDay.ToArray().Length == 0) || ((minTime + sample[i][randomNumberI].getSks()) > maxTime))
                            {
                                index = rng.Next(0, banyakRuangan);
                                sample[i][randomNumberI].setRuanganSol(listR[index].getNamaRuangan());
                                possibleDay = sample[i][randomNumberI].getHariDom().Intersect(listR[index].getHariAvailable());
                                if (listR[index].getjamMulai() > sample[i][randomNumberI].getJamDomAwal())
                                {
                                    minTime = listR[index].getjamMulai();
                                }
                                else
                                {
                                    minTime = sample[i][randomNumberI].getJamDomAwal();
                                }
                                if (listR[index].getjamAkhir() < sample[i][randomNumberI].getJamDomAkhir())
                                {
                                    maxTime = listR[index].getjamAkhir();
                                }
                                else
                                {
                                    maxTime = sample[i][randomNumberI].getJamDomAkhir();
                                }
                            }
                        }
                        index = rng.Next(0, possibleDay.ToArray().Length);
                        sample[i][randomNumberI].setHariSol(possibleDay.ElementAt(index));
                        index = rng.Next(minTime, (maxTime + 1 - sample[i][randomNumberI].getSks()));
                        sample[i][randomNumberI].setJamSol(index);
                    }
                }
                for (int i = 0; i < size; i++)
                {
                    check.hitungKonflik(sample[i]);
                    if (check.getJumlahKonflik() < minConflict)
                    {
                        minConflict  = check.getJumlahKonflik();
                        tempSolution = deepClone(sample[i], banyakJadwal);
                    }
                }
            }
            //Console.WriteLine("Mutation Done");
            for (int i = 0; i < size; i++)
            {
                check.hitungKonflik(sample[i]);
                fitness[i] = maxFitness - check.getJumlahKonflik();
            }
            if ((maxFitness - minConflict) > fitness.Max())
            {
                return(tempSolution);
            }
            else
            {
                return(sample[Array.IndexOf(fitness, fitness.Max())]);
            }
        }