- •Содержание
- •Введение
- •1 Постановка задачи
- •2 Модель решения задачи
- •3 Алгоритм решения задачи
- •4 Реализация методов решения задачи
- •5 Архитектура программы
- •6 Графический интерфейс пользователя
- •7 Тестирование программы
- •8 Демонстрация работы программы
- •Заключение
- •Список использованных источников
- •Приложение а
Заключение
В данном курсовом проекте было разработано приложение, позволяющее расположить перестановки технологических операций с наименьшем временем. Для поиска наименьшего времени перестановки был применен генетический алгоритм.
При написании курсового проекта были выполнены все поставленные задачи, разработан соответствующий функционал.
Программа реализована в среде разработки Intellij Idea 2016 на языке программирования Java.
Тестирование разработанного приложения показало наличие мелких ошибок, которые были исправлены. После исправления ошибок программа успешно работает.
В ходе выполнения курсового проекта было установлено, что при увеличении времени стагнации эффективность алгоритма увеличивается.
Список использованных источников
1. https://habrahabr.ru/post/138091/ - Разработка. Генетические алгоритмы. От теории к практике.
2. https://ru.wikipedia.org/Генетический_алгоритм - Электронный ресурс Википедия
3. Прихожий А.А. Конспект лекций «Моделирование и оптимальное проектирование» - Мн., 2013.
4. http://lc.kubagro.ru/aidos/aidos04/1.3.6.htm – Генетические алгоритмы и моделирование биологической эволюции.
Приложение а
Листинг программы
package engine; import matrix.Result; public interface FitnessFunction { int getFitnessFunctionResult(int[] displacedOperations); void getGenerationBestResult(int[][] geneticoperationNumbers, Result result); }
package engine;
import matrix.FirstGeneration;
import matrix.Result;
import matrix.Time;
import java.util.Random;
public class FitnessFunctionMax implements FitnessFunction {
public FitnessFunctionMax(Time time, FirstGeneration firstGeneration){
this.setRandom(new Random());
this.setTime(time);
this.setFirstGeneration(firstGeneration);
this.setGeneticSize(firstGeneration.getSize());
}
private FirstGeneration firstGeneration;
private Time time;
private Random random;
private int geneticSize;
public int getFitnessFunctionResult(int []displacedOperations){
int fullTime = 0;
int firstOperation;
int lastOperation;
for(int operationIndex = 0; operationIndex < geneticSize - 1; operationIndex++){
firstOperation = displacedOperations[operationIndex] - 1;
lastOperation = displacedOperations[operationIndex + 1] - 1;
fullTime += getTime().getMatrixTime()[firstOperation][lastOperation];
}
return fullTime;
}
public void getGenerationBestResult(int[][] geneticoperationNumbers, Result result){
int bestResult = this.getFitnessFunctionResult(geneticoperationNumbers[0]);
int[] tmp;
for (int[] gen : geneticoperationNumbers) {
int resultFitnessFunction = this.getFitnessFunctionResult(gen);
if (bestResult >= resultFitnessFunction) {
tmp = new int[gen.length];
System.arraycopy(gen, 0, tmp, 0, gen.length);
result.setResult(tmp);
bestResult = resultFitnessFunction;
}
}
result.setResultValue(bestResult);
}
private Random getRandom() {
return random;
}
private void setRandom(Random random) {
this.random = random;
}
public FirstGeneration getFirstGeneration() {
return firstGeneration;
}
public void setFirstGeneration(FirstGeneration firstGeneration) {
this.firstGeneration = firstGeneration;
}
public Time getTime() {
return time;
}
public void setTime(Time time) {
this.time = time;
}
public int getGeneticSize() {
return geneticSize;
}
public void setGeneticSize(int geneticSize) {
this.geneticSize = geneticSize;
}
}
package engine; import matrix.BestResult; import matrix.FirstGeneration; import matrix.Result; import matrix.Time; import java.util.Random; public class GeneticEngine { public GeneticEngine(Time time, FirstGeneration firstGeneration, FitnessFunction fitnessFunction, int stagnationTime){ this.setTime(time); this.setFirstGeneration(firstGeneration); this.setStagnationTime(stagnationTime); this.setPopulationSize(firstGeneration.getPopulationSize()); this.setGeneticSize(firstGeneration.getSize()); this.setFitnessFunction(fitnessFunction); this.random = new Random(); this.reversalOperationNumbers = new int[getPopulationSize()][getGeneticSize()]; this.setGeneticOperationsCurrent(new int[getPopulationSize()][getGeneticSize()]); this.reversalOperationNumbers = firstGeneration.getReversalOperationNumbers().clone(); this.setBestResults(new BestResult()); } private Time time; private FirstGeneration firstGeneration; //number of gens private int geneticSize; private int populationSize; private int stagnationTime; //reversal operationNumbers (population) private int[][] reversalOperationNumbers; //array to store reversal operations private int[][] geneticOperationsCurrent; //fitness function local private FitnessFunction fitnessFunction; //random generator private Random random; private BestResult bestResults; public void run(){ Result result = new Result(); //get parameters this.getFitnessFunction().getGenerationBestResult(this.getreversalOperationNumbers(), result); this.getBestResults().setFirstGenerationBestResultValue(result.getResultValue()); this.getBestResults().setFirstGenerationBestResult(result.getResult()); this.getBestResults().setTime(time); int[][]reversalOperationNumbers = this.getreversalOperationNumbers().clone(); int[][] geneticOperationsCurrent = new int[getPopulationSize()][getGeneticSize()]; int fitnessFunctionCurrentResult; int bestResulCurrentGeneration = result.getResultValue(); long start = System.currentTimeMillis(); //long run = start; long cur = System.currentTimeMillis(); while (cur - start < getStagnationTime() * 1000) { this.selection(reversalOperationNumbers, geneticOperationsCurrent, populationSize); this.crossing(geneticOperationsCurrent, populationSize); this.mutation(geneticOperationsCurrent); fitnessFunctionCurrentResult = this.getFitnessFunction().getFitnessFunctionResult(geneticOperationsCurrent[0]); int fitnessFunctionGenerationResult; for (int index = 1; index < populationSize; index++) { fitnessFunctionGenerationResult = this.getFitnessFunction().getFitnessFunctionResult(geneticOperationsCurrent[index]); fitnessFunctionCurrentResult = fitnessFunctionCurrentResult > fitnessFunctionGenerationResult ? fitnessFunctionGenerationResult : fitnessFunctionCurrentResult; } if (bestResulCurrentGeneration > fitnessFunctionCurrentResult){ bestResulCurrentGeneration = fitnessFunctionCurrentResult; int[][] tmp = reversalOperationNumbers; this.setreversalOperationNumbers(geneticOperationsCurrent); this.setgeneticOperationsCurrent(tmp); reversalOperationNumbers = geneticOperationsCurrent; geneticOperationsCurrent = tmp; start = System.currentTimeMillis(); } cur = System.currentTimeMillis(); } int bestFitnessFunctionResult = fitnessFunction.getFitnessFunctionResult(getreversalOperationNumbers()[0]); for (int[] genom : this.getreversalOperationNumbers()) { int fitnessFunctionResult = this.fitnessFunction.getFitnessFunctionResult(genom); if (bestFitnessFunctionResult >= fitnessFunctionResult) { bestFitnessFunctionResult = fitnessFunctionResult; this.getBestResults().setBestResult(genom); this.getBestResults().setBestResuktValue(bestFitnessFunctionResult); } } } private void selection(int[][] reversalOperationNumbers, int[][] geneticOperationsCurrent, int populationSize) { for (int i = 0; i < populationSize; i++) { int index1 = getRandom().nextInt(populationSize); int index2 = getRandom().nextInt(populationSize); int fr1 = this.fitnessFunction.getFitnessFunctionResult(reversalOperationNumbers[index1]); int fr2 = this.fitnessFunction.getFitnessFunctionResult(reversalOperationNumbers[index2]); geneticOperationsCurrent[i] = fr1 >= fr2 ? reversalOperationNumbers[index2].clone() : reversalOperationNumbers[index1].clone(); } } private void crossing(int[][] geneticOperationsCurrent, int populationSize) { for (int i = 0; i < populationSize / 2; i++) { int index1 = i << 1; int index2 = index1 | 1; cross(geneticOperationsCurrent[index1], geneticOperationsCurrent[index2]); } } private void cross(int[] genom1, int[] genom2) { int index1 = this.getRandom().nextInt(this.geneticSize); int index2 = this.getRandom().nextInt(this.geneticSize); int startIndex = Math.min(index1, index2); int endIndex = Math.max(index1, index2); for (int i= startIndex; i <= endIndex; i++){ int rep = genom2[i]; int tmp = genom1[i]; genom1[i] = rep; genom2[i] = tmp; for (int index = 0; index < genom1.length; index ++ ){ if (genom1[index] == rep && index != i){ genom1[index] = tmp; } } for (int index = 0; index < genom2.length; index ++ ){ if (genom2[index] == tmp && index != i){ genom2[index] = rep; } } } } // Mutation - Mutate all genom in generation private void mutation(int[][] geneticOperationsCurrent) { for (int[] genom : geneticOperationsCurrent) { if (getRandom().nextDouble() <= 0.1) { mutate(genom); } } } private void mutate(int[] genom) { int randomValue = (int) (Math.random() * (genom.length)); int randomValue2 = (int) (Math.random() * (genom.length)); int value = genom[randomValue]; genom[randomValue] = genom[randomValue2]; genom[randomValue2] = value; } private int getGeneticSize() { return geneticSize; } private void setGeneticSize(int geneticSize) { this.geneticSize = geneticSize; } private int getPopulationSize() { return populationSize; } private void setPopulationSize(int populationSize) { this.populationSize = populationSize; } private int[][] getreversalOperationNumbers() { return reversalOperationNumbers; } private FitnessFunction getFitnessFunction() { return fitnessFunction; } private void setFitnessFunction(FitnessFunction fitnessFunction) { this.fitnessFunction = fitnessFunction; } private void setgeneticOperationsCurrent(int[][] geneticOperationsCurrent) { this.setGeneticOperationsCurrent(geneticOperationsCurrent); } private void setreversalOperationNumbers(int[][] reversalOperationNumbers) { this.reversalOperationNumbers = reversalOperationNumbers; } private Random getRandom() { return random; } public Time getTime() { return time; } public void setTime(Time time) { this.time = time; } public FirstGeneration getFirstGeneration() { return firstGeneration; } public void setFirstGeneration(FirstGeneration firstGeneration) { this.firstGeneration = firstGeneration; } public int[][] getGeneticOperationsCurrent() { return geneticOperationsCurrent; } public void setGeneticOperationsCurrent(int[][] geneticOperationsCurrent) { this.geneticOperationsCurrent = geneticOperationsCurrent; } public BestResult getBestResults() { return bestResults; } public void setBestResults(BestResult bestResults) { this.bestResults = bestResults; } public int getStagnationTime() { return stagnationTime; } public void setStagnationTime(int stagnationTime) { this.stagnationTime = stagnationTime; } }
package matrix; public class BestResult { private int firstGenerationBestResultValue; private int[] firstGenerationBestResult; private int bestResuktValue; private int[] bestResult; private Time time; public int getFirstGenerationBestResultValue() { return firstGenerationBestResultValue; } public void setFirstGenerationBestResultValue(int firstGenerationBestResultValue) { this.firstGenerationBestResultValue = firstGenerationBestResultValue; } public int[] getFirstGenerationBestResult() { return firstGenerationBestResult; } public void setFirstGenerationBestResult(int[] firstGenerationBestResult) { this.firstGenerationBestResult = firstGenerationBestResult; } public int getBestResuktValue() { return bestResuktValue; } public void setBestResuktValue(int bestResuktValue) { this.bestResuktValue = bestResuktValue; } public int[] getBestResult() { return bestResult; } public void setBestResult(int[] bestResult) { this.bestResult = bestResult; } public Time getTime() { return time; } public void setTime(Time time) { this.time = time; } }
package matrix; public class FirstGeneration { public FirstGeneration(int size, int populationSize, Time time){ this.setSize(size); this.setPopulationSize(populationSize); this.setTime(time); this.setOperationNumbers(new int[size]); this.setReversalOperationNumbers(new int[populationSize][size]); this.fillOperationNumbers(); this.fillReversalOperationNumbers(); this.reverseOperations(); } private void fillOperationNumbers(){ //if operationNumbers don't found if (this.getOperationNumbers() == null){ return; } //fill operationNumbers array for(int index = 0; index < this.getOperationNumbers().length; index++){ getOperationNumbers()[index] = index + 1; } } private void fillReversalOperationNumbers(){ if (getReversalOperationNumbers() == null){ return; } //initialization replaced operationNumbers for(int index = 0; index < getPopulationSize(); index++){ System.arraycopy(getOperationNumbers(), 0, getReversalOperationNumbers()[index], 0, getSize()); } //replace operation's positions' for(int index = 1; index < getPopulationSize(); index++){ changeOperationNumbers(getReversalOperationNumbers()[index]); } } private void changeOperationNumbers(int []replaces){ int size = replaces.length; for(int index = 0; index < size; index++){ int randomValue = (int) (Math.random() * (size)); int x = replaces[index]; replaces[index] = replaces[randomValue]; replaces[randomValue] = x; } } private void reverseOperations() { int []reversalOperationsFirstGeneration = getOperationNumbers().clone(); int []operationWeight = new int[reversalOperationsFirstGeneration.length - 1]; int firstOperation; int lastOperation; for(int operationIndex = 0; operationIndex < reversalOperationsFirstGeneration.length - 1; operationIndex++){ firstOperation = reversalOperationsFirstGeneration[operationIndex] - 1; lastOperation = reversalOperationsFirstGeneration[operationIndex + 1] - 1; operationWeight[operationIndex] = time.getMatrixTime()[firstOperation][lastOperation]; } qsort(operationWeight, reversalOperationsFirstGeneration, 0, operationWeight.length - 1); } private void qsort(int[] arrayToSort, int[] arrayToMix,int l, int r){ int i = l; int j = r; int tmp; int pivot = arrayToSort[(l+r)>>1]; while (i <= j) { while (arrayToSort[i] < pivot) {i+=1;} while (arrayToSort[j] > pivot) {j-=1;} if (i <= j) { tmp = arrayToSort[i]; arrayToSort[i] = arrayToSort[j]; arrayToSort[j] = tmp; tmp = arrayToMix[i]; arrayToMix[i] = arrayToMix[j]; arrayToMix[j] = tmp; tmp = arrayToMix[i + 1]; arrayToMix[i + 1] = arrayToMix[j + 1]; arrayToMix[j + 1] = tmp; i+=1; j-=1; } } if (l < j){ qsort(arrayToSort, arrayToMix, l, j); } if (i < r){ qsort(arrayToSort, arrayToMix, i, r); } } private int size; private int populationSize; private int[] operationNumbers; private int[][]reversalOperationNumbers; private Time time; public int getSize() { return size; } private void setSize(int size) { this.size = size; } public int getPopulationSize() { return populationSize; } private void setPopulationSize(int populationSize) { this.populationSize = populationSize; } public int[] getOperationNumbers() { return operationNumbers; } private void setOperationNumbers(int[] operationNumbers) { this.operationNumbers = operationNumbers; } public int[][] getReversalOperationNumbers() { return reversalOperationNumbers; } private void setReversalOperationNumbers(int[][] reversalOperationNumbers) { this.reversalOperationNumbers = reversalOperationNumbers; } public Time getTime() { return time; } private void setTime(Time time) { this.time = time; } }
package matrix; public class Result { public Result(int resultValue, int[]result){ this.setResult(result); this.setResultValue(resultValue); } public Result(){} private int[] result; private int resultValue; public int[] getResult() { return result; } public void setResult(int[] result) { this.result = result; } public int getResultValue() { return resultValue; } public void setResultValue(int resultValue) { this.resultValue = resultValue; } }
package matrix; import java.util.Random; public class Time { public Time(int size, int time){ this.setSize(size); this.setMaxTime(time); //matrix this.setMatrixTime(new int[size][size]); //set random this.setRandom(new Random()); //fill time matrix fillMatrix(); } private Random random; private int [][]matrixTime; private int size; private int maxTime; private void fillMatrix(){ for (int row = 0; row < getSize(); row++){ for (int column = 0; column < getSize(); column++){ if (row == column){ matrixTime[row][column] = 0; } else{ matrixTime[row][column] = random.nextInt(getMaxTime()) + 1; } } } System.out.println("Matrix time"); System.out.println(); for(int[]x: getMatrixTime()) { for (int y : x) { System.out.format("%4d ", y); } System.out.println(); } } public int[][] getMatrixTime() { return matrixTime; } private void setMatrixTime(int[][] matrixTime) { this.matrixTime = matrixTime; } private void setSize(int size) { this.size = size; } public int getMaxTime() { return maxTime; } private void setMaxTime(int maxTime) { this.maxTime = maxTime; } private void setRandom(Random random) { this.random = random; } public int getSize() { return size; } }
var generateMatrix = function () { var geneticSize = $("#geneticSize").val(); var operationTime = $("#time").val(); $.ajax( { type: "GET", url: "time", data: {"geneticSize": geneticSize, "operationTime": operationTime}, dataType: "json", success: function(response){ var matrixTime = response['matrixTime']; var outMatrixTime = $("#out"); var answer = ""; for(var i = 0; i < geneticSize; i++){ for (var k = 0; k < geneticSize; k++){ answer += print(operationTime, matrixTime[i][k]) + " "; } answer += '\n'; } outMatrixTime.text(answer); } }); }; var execute = function () { var populationSize = $("#populationSize").val(); var stagnationTime = $("#stagnationTime").val(); $.ajax( { type: "GET", url: "genetic", data: {"populationSize": populationSize, "stagnationTime": stagnationTime}, dataType: "json", success: function(response){ var firstGenerationBestResult = response['firstGenerationBestResult']; var bestResult = response['bestResult']; var outResult = $("#outResult"); var firstGenBestRes = "First generation best result: "; var firstGenBestResValue = "First generation best result value: "; var firstGenArr = ""; var answer = ""; for(var i = 0; i < firstGenerationBestResult.length; i++){ firstGenArr += print(firstGenerationBestResult.length, firstGenerationBestResult[i]) + " "; } answer += firstGenBestRes + firstGenArr + '\n' + firstGenBestResValue + response['firstGenerationBestResultValue'].toString() + ' s' + '\n'; var bestResultArray = "Best result: "; var bestResultValue = "Best result value: "; var bestArray = ""; for(var i = 0; i < bestResult.length; i++){ bestArray += print(bestResult.length, bestResult[i]) + " "; } answer += bestResultArray + bestArray + '\n' + bestResultValue + response['bestResuktValue'].toString() + ' s' + '\n'; outResult.text(answer); } }); }; var print = function (size, value) { var length = size.toString().length; var str = ""; for(var i = 0; i < length - value.toString().length; i++){ str = str + " "; } return str + value.toString(); };
.
