KHE_SOLN simulatedAnnealing(KHE_SOLN soln, KHE_INSTANCE instance, Config &config) { KHE_SOLN bestSoln = soln; KHE_COST costAfter, costBefore; KHE_TRANSACTION t; soln = KheSolnCopy(bestSoln); int neighborhood = 0; int reheats = -1; int iterTemp = 0; double currentTemp = config.saTempIni; double delta, random; while (reheats < config.saReheats && config.getRemainingTime() > 0) { restartMoves(); while (iterTemp < config.saMax && config.getRemainingTime() > 0) { iterTemp++; neighborhood = 0; // Gerando vizinho costBefore = KheSolnCost(soln); t = KheTransactionMake(soln); KheTransactionBegin(t); generateNeighbor(soln, instance, neighborhood); KheTransactionEnd(t); costAfter = KheSolnCost(soln); delta = (KheHardCost(costAfter) - KheHardCost(costBefore)) * 10000.0 + (KheSoftCost(costAfter) - KheSoftCost(costBefore)) / (KheHardCost(KheSolnCost(bestSoln)) * 10000.0 + KheSoftCost(KheSolnCost(bestSoln))); random = (1 + rand() % 100000) / 100000.0; if (delta <= 0) { if (isBetterSolution(soln, bestSoln)) { KheSolnDelete(bestSoln); bestSoln = KheSolnCopy(soln); printToLog(soln, config, neighborhood, iterTemp, currentTemp); iterTemp = 0; restartMoves(); } } else if (random < exp(-delta / currentTemp)) { restartMoves(); } else { KheTransactionUndo(t); } KheTransactionDelete(t); } currentTemp = currentTemp * config.saAlpha; iterTemp = 0; if (currentTemp <= config.saTempMin) { reheats++; currentTemp = config.saTempIni; KheSolnDelete(soln); soln = KheSolnCopy(bestSoln); printf("Reaquecendo (time: %d)\n", config.getRunTime()); } } KheSolnDelete(soln); return bestSoln; }
KHE_SOLN vns(KHE_SOLN soln, KHE_INSTANCE instance, Config &config) { int bestHardFitness = KheHardCost(KheSolnCost(soln)); int bestSoftFitness = KheSoftCost(KheSolnCost(soln)); int startingNeighborhood = 1; int neighborhood = startingNeighborhood; int neighborHardFitness; int neighborSoftFitness; bool hasMove; bool neighborhoodImprove; while (config.getRemainingTime() > 0) { restartMoves(); hasMove = true; neighborhoodImprove = false; if (neighborhood != PERMUT_RESOURCES && ((neighborhood != TASK_RESOURCE_SWAP && neighborhood != TASK_SWAP) || config.assignResourcesConst == true)) { for (int i = 0; i < config.vnsMax && hasMove && config.getRemainingTime() > 0; ++i) { KHE_TRANSACTION t = KheTransactionMake(soln); KheTransactionBegin(t); hasMove = generateNeighbor(soln, instance, neighborhood); KheTransactionEnd(t); // verifica se houve melhora na solucao neighborHardFitness = KheHardCost(KheSolnCost(soln)); neighborSoftFitness = KheSoftCost(KheSolnCost(soln)); if (neighborHardFitness < bestHardFitness || (neighborHardFitness == bestHardFitness && neighborSoftFitness < bestSoftFitness)) { bestHardFitness = neighborHardFitness; bestSoftFitness = neighborSoftFitness; printToLog(soln, config, neighborhood, i, 0.0); neighborhoodImprove = true; KheTransactionDelete(t); break; } else if (neighborHardFitness > bestHardFitness || neighborSoftFitness > bestSoftFitness) { // caso a solucao seja pior que a anterior KheTransactionUndo(t); // desfaz o movimento KheTransactionDelete(t); // desfaz o movimento } } } if (neighborhoodImprove) neighborhood = startingNeighborhood; else if (neighborhood + 1 == MAX_NEIGHBOR) neighborhood = startingNeighborhood; else ++neighborhood; } return soln; }
double Recuit::process(int iterations) { // Code du recuit // on pars de la solution du modèle et on l'ameilore double lambda_t = 0.95, base_temp = 1000.0,temp = base_temp, temp_iterations = 100; double cur_value = model->solutionCost(), min_value = cur_value; for(int i = 0;i<iterations;i++) { // Itérations de température temp = base_temp; for(int j = 0;j<temp_iterations;j++) { // Nouvelle solution QVector<Potato*> potatoes = generateNeighbor(); double new_value = model->solutionCost(potatoes); if((new_value < cur_value || pass(temp,new_value-cur_value)) && potatoes.size() > 0) { // Nouvelle solution acceptée cur_value = new_value; // Nouvelle solution minimale if(new_value < min_value && model->isValidSolution(potatoes)) { qDebug() << "New solution;" << new_value << ";" << i << ";" << j << ";" << i*100+j; model->solution = potatoes; min_value = cur_value; } } temp *= lambda_t; } if(i%(iterations/10) == 0) { qDebug() << i << "itérations"; } } //renvoie la valeur totale de la solution //dans l'attribut model, remplis la liste des solutions avec des patates return model->solutionCost(); }
KHE_SOLN ils(KHE_SOLN soln, KHE_INSTANCE instance, Config &config) { soln = descent(soln, soln, instance, config.ilsBlMax, config); KHE_SOLN bestSoln = KheSolnCopy(soln); KHE_COST cost; int perturbationSize = config.ilsPertIni; int iters = 0; int neighborhood = 0; int pertubationChanges = 0; while (config.getRemainingTime() > 0 && pertubationChanges < config.ilsIters) { restartMoves(); for (int j = 0; j < perturbationSize; ++j) { neighborhood = rand() % 100 < 50 ? 6 : 7; generateNeighbor(soln, instance, neighborhood); } cost = KheSolnCost(soln); printf("PERTURBED Level %d Hard cost: %d Soft cost: %d\n", perturbationSize, KheHardCost(cost), KheSoftCost(cost)); soln = descent(soln, bestSoln, instance, config.ilsBlMax, config); // Houve melhora na solucao? if (isBetterSolution(soln, bestSoln)) { KheSolnDelete(bestSoln); bestSoln = KheSolnCopy(soln); perturbationSize = config.ilsPertIni; iters = 0; } else { KheSolnDelete(soln); soln = KheSolnCopy(bestSoln); iters++; } if (iters >= config.ilsMax) { iters = 0; perturbationSize = (config.ilsPertIni + 1) % (config.ilsPertMax + 1); pertubationChanges++; } } KheSolnDelete(soln); return bestSoln; }
KHE_SOLN descent(KHE_SOLN soln, KHE_SOLN bestSoln, KHE_INSTANCE instance, int iterMax, Config &config) { int bestKnownHardFitness = KheHardCost(KheSolnCost(bestSoln)); int bestKnownSoftFitness = KheSoftCost(KheSolnCost(bestSoln)); int bestHardFitness = KheHardCost(KheSolnCost(soln)); int bestSoftFitness = KheSoftCost(KheSolnCost(soln)); int iter = 0, neighborhood = 0; bool hasMove = true; while (hasMove && iter < iterMax && config.getRemainingTime() > 0) { // gera o vizinho e executa o movimento KHE_TRANSACTION t = KheTransactionMake(soln); KheTransactionBegin(t); neighborhood = 0; hasMove = generateNeighbor(soln, instance, neighborhood); KheTransactionEnd(t); // verifica se houve melhora na solucao int neighborHardFitness = KheHardCost(KheSolnCost(soln)); int neighborSoftFitness = KheSoftCost(KheSolnCost(soln)); if (neighborHardFitness < bestHardFitness || (neighborHardFitness == bestHardFitness && neighborSoftFitness < bestSoftFitness)) { bestHardFitness = neighborHardFitness; bestSoftFitness = neighborSoftFitness; if (neighborHardFitness < bestKnownHardFitness || (neighborHardFitness == bestKnownHardFitness && neighborSoftFitness < bestKnownSoftFitness)) printToLog(soln, config, neighborhood, iter, 0.0); restartMoves(); iter = 0; } else if (neighborHardFitness > bestHardFitness || neighborSoftFitness > bestSoftFitness) { // caso a solucao seja pior que a anterior KheTransactionUndo(t); // desfaz o movimento } KheTransactionDelete(t); iter++; } return soln; }