/** * this implements the core of the algorithm use a starter method to define the abort criteria, eg * # iterations or duration * * @return best Individual that was found (valid and invalid) * @author jochen */ private Individual startAlgorithm() { startTime = System.currentTimeMillis(); // System.out.println("Start Algorithm for Problem " + problem.getInstanceName() + " (Fees: " + // Config.getFee() +")"); /* create start population **************************************************/ if (currentPopulation == null) { currentPopulation = new PopulationImpl(problem, populationSize); } // System.out.println(currentPopulation.getBestIndividual()); /* evolve ********************************************************************/ while (!stop()) { /* create a new empty child-population ***********************************/ Population newGeneration = new PopulationImpl(this.problem); /* adds the best individual to new generation ****************************/ newGeneration.add(currentPopulation.getBestIndividual()); /* add some random individuals from foreign countries to new population *****/ for (int j = 0; j < populationSize * Config.getPercentageForeignIndividuals(); j++) { currentPopulation.remove(currentPopulation.getWorstIndividual()); } for (int j = 0; j < populationSize * Config.getPercentageForeignIndividuals(); j++) { currentPopulation.add(IndividualImpl.generateRandomIndividual(problem)); } /* create a new generation with doubled size as current ******************/ while (newGeneration.getSize() < populationSize * Config.getNewGenerationSize()) { // size of new population // higher value results in higher selection pressure /* selection *******************************************************/ Individual mum = null, dad = null; if (Config.getSelectionMethod() == 0) { // random mum = currentPopulation.getRandomIndividual(); dad = currentPopulation.getRandomIndividual(); } else if (Config.getSelectionMethod() == 1) { // roulette wheel mum = currentPopulation.getIndividualByRouletteWheel(); dad = currentPopulation.getIndividualByRouletteWheel(); } /* recombine *******************************************************/ Individual baby = mum.haveSex(dad); /* mutate **********************************************************/ if (Math.random() < Config.getOddsMutation()) { double random = Math.random(); if (random < 0.3) { baby.mutateNearNeighbor(); } else if (random < 0.5) { baby.mutateOnlyCurrentFacilities(); } else if (random < 0.7) { for (int i = 0; i < (int) (Math.random() * 5); i++) { baby.mutateNearNeighbor(); } } else if (random < 0.8) { baby.mutateSwitchCustomers(); } else if (random < 0.85) { baby.mutateBanFacilityAndFindNewFromCurretUsed(); } else if (random < 0.9) { baby.mutateCloseAndOpenAFacility(); } else if (random < 0.95) { baby.mutateBanFacilityAndFindNewFacilityByRouletteWheel(); } } /* add new individual to new generation ****************************/ newGeneration.add(baby); } /* finally select best of new Generation *******************************/ newGeneration.selectBest(populationSize); /* replace current population with the new population ************************/ currentPopulation = newGeneration; /* Print best indivual every n times *********************************/ if (Config.getPrintEachTimes() != 0 && currentGeneration % Config.getPrintEachTimes() == 0) { System.out.println(currentPopulation.getBestIndividual()); } } // End for status.setTimeStopped(Calendar.getInstance()); stopTime = System.currentTimeMillis(); /* return best Individual *************************************************/ if (Config.isReturnOnlyValidIndividuals()) { return currentPopulation.getBestValidIndividual(); } else { return currentPopulation.getBestIndividual(); } }