コード例 #1
0
Result *TSPSimulatedAnnealing::solve()
{
	/**
	 * 1). losujesz rozwiazanie
	 * 2). losujesz sąsiada żeby do niego przejść
	 * 3). przechodzisz jak jest lepszy a jak nie to sprawdzasz prawdopodobieństwo przejścia
	 * 4). koniec algorytmu, gdy:
	 * 		- osiągnie daną liczbę kroków
	 * 		- jeżeli nie ma poprawy po określonej liczbie kroków
	 * 		- przy przejśiu sprawdzamy czy temperatuda nie opadła poniżej minimum
	 */
	Result *cur;
	Result *next;
	Result *best = NULL;
	u_int32_t bestDistance = 0, noBadMovesCounter = 0;
	u_int32_t loopCounter = 0;
	u_int32_t neighorsVisited = 0, betterSolutionsCount = 0;
	u_int32_t nextDistance, curDistance, worseSolutions = 0;

	//printf("%f %f %f %d\n", _startTemperature, _endTemperature, _alpha, _maxBadMoves);

	_temperature = _startTemperature;


	cur = generateRandomResult();

//	TSPGreedySolver2 *greedySolver2;
//	greedySolver2 = new TSPGreedySolver2(_instance, "");
//	cur = greedySolver2->solve();
//	delete greedySolver2;

	best = new Result(*cur);
	bestDistance = calculateDistance(cur);

	while ((_temperature > _endTemperature) &&
			(loopCounter < getNumberOfSteps()) && (noBadMovesCounter < _maxBadMoves))
	{
		next = new Result(*cur);
		next->swapRandomly();

		nextDistance = calculateDistance(next);
		next->setCalculatedDistance(nextDistance);
		neighorsVisited++;

		float lotery = ((float) (rand() % RAND_MAX) / (float) RAND_MAX);
		float accProb = acceptanceProbability(curDistance, nextDistance);

		//kiedy przechodzimy do nowego rozwiazania
		if ((nextDistance < curDistance) || (lotery > accProb))
		{
			delete cur;
			cur = next;
			noBadMovesCounter = 0;

			if (nextDistance >= curDistance)
			{
				//printf("worse %f %f %f\n", lotery, accProb, _temperature);
				worseSolutions++;
			}

			if (nextDistance < bestDistance)
			{
				if (best != NULL)
					delete best;
				betterSolutionsCount++;
				best = new Result(*next);
				bestDistance = nextDistance;
				best->setCalculatedDistance(bestDistance);
			}

			curDistance = calculateDistance(cur);
			cur->setCalculatedDistance(curDistance);
		}
		else
		{
			noBadMovesCounter++;
			delete next;
		}
		loopCounter++;
		_temperature *= _alpha;
	}

//	printf("worse: %d\n", worseSolutions);
//	printf("temperature: %f\n", _temperature);
//	printf("loopCounter: %d\n", loopCounter);
//	printf("bad moves: %d\n", noBadMovesCounter);

	best->setNeighborsVisited(neighorsVisited);
	best->setStepsCount(loopCounter);
	best->setBetterSolutionsCount(betterSolutionsCount);

	return best;
}
コード例 #2
0
ファイル: MatrixGraph.cpp プロジェクト: iceslab/PEA_PROJEKT
Data MatrixGraph::simulatedAnnealing(uint temperature)
{
	clock_t overallTime = clock();
	initRand();
	stringstream results;
	vector<uint> route, bestRoute;
	route.reserve(vertexNumber);
	bestRoute.reserve(vertexNumber);
	uint prevCost = greedyAlg(route), bestCost;
	route.pop_back();
	bestRoute = route;
	bestCost = prevCost;

	if (!temperature)
		temperature = vertexNumber << 10;

	default_random_engine gen(uint(time(nullptr)));
	uniform_real_distribution<double> doubleRnd(0.0, 1.0);

	uint i = 0;
	for (; temperature; --temperature, ++i)
	{
		i %= route.size();
		uint firstIndex = rand() % (route.size());
		uint secondIndex = rand() % (route.size() - 1);
		if (secondIndex >= firstIndex)
			++secondIndex;

		vector<uint> tmpVector(route);
		uint tmp = tmpVector[firstIndex];
		tmpVector[firstIndex] = tmpVector[secondIndex];
		tmpVector[secondIndex] = tmp;

		uint tmpCost = calculateCost(tmpVector);
		if (tmpCost < prevCost)
		{
			route = tmpVector;
			prevCost = tmpCost;
		}
		else
		{
			if (acceptanceProbability(prevCost, tmpCost, temperature) >= doubleRnd(gen))
			{
				route = tmpVector;
				prevCost = tmpCost;
			}
		}

		// Śledzenie najlepszego rozwiązania
		if (prevCost < bestCost)
		{
			bestRoute = route;
			bestCost = prevCost;
		}
	}

	double duration = (clock() - overallTime) / (double)CLOCKS_PER_SEC;
	results << "Koszt drogi: " << bestCost << "\nCalkowity czas trwania: " << duration << " sekund\n";
	return Data(bestRoute, bestCost, results.str(), duration);

}