Esempio n. 1
0
void arsaRawParallel(arsaRawArgs& args)
{
	long n = args.n;
	Rbyte* rawDist = args.rawDist;
	std::vector<double>& levels = args.levels;
	double cool = args.cool;
	double temperatureMin = args.temperatureMin;
	if(temperatureMin <= 0)
	{
		throw std::runtime_error("Input temperatureMin must be positive");
	}
	
	long nReps = args.nReps;
	std::vector<int>& permutation = args.permutation;
	std::function<void(unsigned long, unsigned long)> progressFunction = args.progressFunction;
	bool randomStart = args.randomStart;

	int maxMove = args.maxMove;
	if(maxMove < 0)
	{
		throw std::runtime_error("Input maxMove must be non-negative");
	}

	double effortMultiplier = args.effortMultiplier;
	if(effortMultiplier <= 0)
	{
		throw std::runtime_error("Input effortMultiplier must be positive");
	}

	permutation.resize(n);
	if(n == 1)
	{
		permutation[0] = 0;
		return;
	}
	else if(n < 1)
	{
		throw std::runtime_error("Input n must be positive");
	}

	//We skip the initialisation of D, R1 and R2 from arsa.f, and the computation of asum. 
	//Next the original arsa.f code creates nReps random permutations, and holds them all at once. This doesn't seem necessary, we create them one at a time and discard them
	double zbestAllReps = -std::numeric_limits<double>::infinity();
	//A copy of the best permutation found
	std::vector<int> bestPermutationThisRep(n);
	//We use this to build the random permutations
	std::vector<int> consecutive(n);
	for(R_xlen_t i = 0; i < n; i++) consecutive[i] = (int)i;
	std::vector<int> deltaComponents(levels.size());
	//We're doing lots of simulation, so we use the old-fashioned approach to dealing with Rs random number generation
	GetRNGstate();

	std::vector<change> stackOfChanges;
	std::vector<bool> dirty(n, false);
	for(int repCounter = 0; repCounter < nReps; repCounter++)
	{
		//create the random permutation, if we decided to use a random initial permutation
		if(randomStart)
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				double rand = unif_rand();
				R_xlen_t index = (R_xlen_t)(rand*(n-i));
				if(index == n-i) index--;
				bestPermutationThisRep[i] = consecutive[index];
				std::swap(consecutive[index], *(consecutive.rbegin()+i));
			}
		}
		else
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				bestPermutationThisRep[i] = consecutive[i];
			}
		}
		//calculate value of z
		double z = 0;
		for(R_xlen_t i = 0; i < n-1; i++)
		{
			R_xlen_t k = bestPermutationThisRep[i];
			for(R_xlen_t j = i+1; j < n; j++)
			{
				R_xlen_t l = bestPermutationThisRep[j];
				z += (j-i) * levels[rawDist[l*n + k]];
			}
		}
		double zbestThisRep = z;
		double temperatureMax = 0;
		//Now try 5000 random swaps
		for(R_xlen_t swapCounter = 0; swapCounter < (R_xlen_t)(5000*effortMultiplier); swapCounter++)
		{
			R_xlen_t swap1, swap2;
			getPairForSwap(n, swap1, swap2);
			double delta = computeDelta(bestPermutationThisRep, swap1, swap2, rawDist, levels, deltaComponents);
			if(delta < 0)
			{
				if(fabs(delta) > temperatureMax) temperatureMax = fabs(delta);
			}
		}
		double temperature = temperatureMax;
		std::vector<int> currentPermutation = bestPermutationThisRep;
		int nloop = (int)((log(temperatureMin) - log(temperatureMax)) / log(cool));
		long totalSteps = (long)(nloop * 100 * n * effortMultiplier);
		long done = 0;
		//Rcpp::Rcout << "Steps needed: " << nloop << std::endl;
		for(R_xlen_t idk = 0; idk < nloop; idk++)
		{
			//Rcpp::Rcout << "Temp = " << temperature << std::endl;
			for(R_xlen_t k = 0; k < (R_xlen_t)(100*n*effortMultiplier); k++)
			{
				R_xlen_t swap1, swap2;
				//swap
				if(unif_rand() <= 0.5)
				{
					getPairForSwap(n, swap1, swap2);
					change newChange;
					newChange.isMove = false;
					newChange.swap1 = swap1; newChange.swap2 = swap2;

					if(dirty[swap1] || dirty[swap2])
					{
						#pragma omp parallel for
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							deltaForChange(*i, currentPermutation, rawDist, levels);
						}
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
						}
						done += stackOfChanges.size();
						progressFunction(done, totalSteps);
						stackOfChanges.clear();
						std::fill(dirty.begin(), dirty.end(), false);
					}
					else dirty[swap1] = dirty[swap2] = true;
					stackOfChanges.push_back(newChange);
				}
				//insertion
				else
				{
					getPairForMove(n, swap1, swap2, maxMove);
					bool canDefer = true;
					for(R_xlen_t i = std::min(swap1, swap2); i != std::max(swap1, swap2)+1; i++) canDefer &= !dirty[i];
					change newChange;
					newChange.isMove = true;
					newChange.swap1 = swap1; 
					newChange.swap2 = swap2;
					if(canDefer)
					{
						std::fill(dirty.begin() + std::min(swap1, swap2), dirty.begin() + std::max(swap1, swap2)+1, true);
					}
					else
					{
						#pragma omp parallel for
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							deltaForChange(*i, currentPermutation, rawDist, levels);
						}
						for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
						{
							makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
						}

						done += stackOfChanges.size();
						progressFunction(done, totalSteps);
						stackOfChanges.clear();
						std::fill(dirty.begin(), dirty.end(), false);
					}
					stackOfChanges.push_back(newChange);
				}
			}
			#pragma omp parallel for
			for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
			{
				deltaForChange(*i, currentPermutation, rawDist, levels);
			}
			for(std::vector<change>::iterator i = stackOfChanges.begin(); i != stackOfChanges.end(); i++)
			{
				makeChange(*i, currentPermutation, rawDist, levels, z, zbestThisRep, bestPermutationThisRep, temperature);
			}

			done += stackOfChanges.size();
			progressFunction(done, totalSteps);
			stackOfChanges.clear();
			std::fill(dirty.begin(), dirty.end(), false);
			temperature *= cool;
		}
		if(zbestThisRep > zbestAllReps)
		{
			zbestAllReps = zbestThisRep;
			permutation.swap(bestPermutationThisRep);
		}
	}
	PutRNGstate();
}
Esempio n. 2
0
ZPatcher::PatchFileList_t* ZPatcher::GetDifferences(std::string& oldVersion, std::string& newVersion, ProgressCallback progressFunction)
{
	PatchFileList_t* patchFileList = new PatchFileList_t();

	std::vector<std::string> oldVersionFileList;
	GetFilesInDirectory(oldVersionFileList, oldVersion);

	std::vector<std::string> newVersionFileList;
	GetFilesInDirectory(newVersionFileList, newVersion);

	// Sort them now to avoid worries later. (Easier to find added/deleted files)
	std::sort(oldVersionFileList.begin(), oldVersionFileList.end());
	std::sort(newVersionFileList.begin(), newVersionFileList.end());

	unsigned int oldFileIndex = 0;
	unsigned int newFileIndex = 0;

	fprintf(stdout, "Detecting file differences between folders...\n");

	while (oldFileIndex < oldVersionFileList.size() && newFileIndex < newVersionFileList.size())
	{
		float progress = (oldFileIndex + newFileIndex) * 100.0f / (oldVersionFileList.size() + newVersionFileList.size());
		progressFunction(progress, oldFileIndex + newFileIndex, oldVersionFileList.size() + newVersionFileList.size());

		const std::string& oldFileName = oldVersionFileList[oldFileIndex];
		const std::string& newFileName = newVersionFileList[newFileIndex];

		if (oldFileName == newFileName)
		{
			// Check if we are dealing with directories.
			size_t fileNameLength = oldFileName.length();
			if (fileNameLength > 0 && oldFileName[fileNameLength - 1] != '/')
			{
				// Check if the files have the same contents
				bool identical;
				bool success = AreFilesIdentical(oldVersion + "/" + oldFileName, newVersion + "/" + newFileName, identical);

				assert(success == true); // TODO: Handle this.

				if (success != true)
				{
					fprintf(stderr, "\n\nError comparing files! Patch file might be inconsistent! Check the logs for details.\n\n");
				}

				if (success && !identical)
				{
					patchFileList->ModifiedFileList.push_back(oldFileName);
				}
			}

			oldFileIndex++;
			newFileIndex++;

		}
		else if (oldFileName < newFileName)
		{
			// The new version doesn't contain this file.
			patchFileList->RemovedFileList.push_back(oldFileName);
			oldFileIndex++;
		}
		else
		{
			// The old version doesn't contain this file.
			patchFileList->AddedFileList.push_back(newFileName);
			newFileIndex++;
		}
	}

	// Okay, one of the lists is smaller than the other. Add or Remove all missing files, depending on the file list.
	while (oldFileIndex < oldVersionFileList.size())
	{
		float progress = (oldFileIndex + newFileIndex) * 100.0f / (oldVersionFileList.size() + newVersionFileList.size());
		progressFunction(progress, oldFileIndex + newFileIndex, oldVersionFileList.size() + newVersionFileList.size());

		patchFileList->RemovedFileList.push_back(oldVersionFileList[oldFileIndex]);
		oldFileIndex++;
	}

	while (newFileIndex < newVersionFileList.size())
	{
		float progress = (newFileIndex + newFileIndex) * 100.0f / (newVersionFileList.size() + newVersionFileList.size());
		progressFunction(progress, oldFileIndex + newFileIndex, oldVersionFileList.size() + newVersionFileList.size());

		patchFileList->AddedFileList.push_back(newVersionFileList[newFileIndex]);
		newFileIndex++;
	}

	progressFunction(100.0f, oldFileIndex + newFileIndex, oldVersionFileList.size() + newVersionFileList.size());
	fprintf(stdout, "\n\n");

	return patchFileList;
}
Esempio n. 3
0
void arsaRaw(arsaRawArgs& args)
{
	long n = args.n;
	Rbyte* rawDist = args.rawDist;
	std::vector<double>& levels = args.levels;
	double cool = args.cool;
	double temperatureMin = args.temperatureMin;
	if(temperatureMin <= 0)
	{
		throw std::runtime_error("Input temperatureMin must be positive");
	}
	
	long nReps = args.nReps;
	std::vector<int>& permutation = args.permutation;
	std::function<void(unsigned long, unsigned long)> progressFunction = args.progressFunction;
	bool randomStart = args.randomStart;

	int maxMove = args.maxMove;
	if(maxMove < 0)
	{
		throw std::runtime_error("Input maxMove must be non-negative");
	}

	double effortMultiplier = args.effortMultiplier;
	if(effortMultiplier <= 0)
	{
		throw std::runtime_error("Input effortMultiplier must be positive");
	}

	permutation.resize(n);
	if(n == 1)
	{
		permutation[0] = 0;
		return;
	}
	else if(n < 1)
	{
		throw std::runtime_error("Input n must be positive");
	}
	//We skip the initialisation of D, R1 and R2 from arsa.f, and the computation of asum. 
	//Next the original arsa.f code creates nReps random permutations, and holds them all at once. This doesn't seem necessary, we create them one at a time and discard them
	double zbestAllReps = -std::numeric_limits<double>::infinity();
	//A copy of the best permutation found
	std::vector<int> bestPermutationThisRep(n);
	//We use this to build the random permutations
	std::vector<int> consecutive(n);
	for(R_xlen_t i = 0; i < n; i++) consecutive[i] = (int)i;
	std::vector<int> deltaComponents(levels.size());
	//We're doing lots of simulation, so we use the old-fashioned approach to dealing with Rs random number generation
	GetRNGstate();

	for(int repCounter = 0; repCounter < nReps; repCounter++)
	{
		//create the random permutation, if we decided to use a random initial permutation
		if(randomStart)
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				double rand = unif_rand();
				R_xlen_t index = (R_xlen_t)(rand*(n-i));
				if(index == n-i) index--;
				bestPermutationThisRep[i] = consecutive[index];
				std::swap(consecutive[index], *(consecutive.rbegin()+i));
			}
		}
		else
		{
			for(R_xlen_t i = 0; i < n; i++)
			{
				bestPermutationThisRep[i] = consecutive[i];
			}
		}
		//calculate value of z
		double z = 0;
		for(R_xlen_t i = 0; i < n-1; i++)
		{
			R_xlen_t k = bestPermutationThisRep[i];
			for(R_xlen_t j = i+1; j < n; j++)
			{
				R_xlen_t l = bestPermutationThisRep[j];
				z += (j-i) * levels[rawDist[l*n + k]];
			}
		}
		double zbestThisRep = z;
		double temperatureMax = 0;
		//Now try 5000 random swaps
		for(R_xlen_t swapCounter = 0; swapCounter < (R_xlen_t)(5000*effortMultiplier); swapCounter++)
		{
			R_xlen_t swap1, swap2;
			getPairForSwap(n, swap1, swap2);
			double delta = computeDelta(bestPermutationThisRep, swap1, swap2, rawDist, levels, deltaComponents);
			if(delta < 0)
			{
				if(fabs(delta) > temperatureMax) temperatureMax = fabs(delta);
			}
		}
		double temperature = temperatureMax;
		std::vector<int> currentPermutation = bestPermutationThisRep;
		int nloop = (int)((log(temperatureMin) - log(temperatureMax)) / log(cool));
		long totalSteps = (long)(nloop * 100 * n * effortMultiplier);
		long done = 0;
		long threadZeroCounter = 0;
		//Rcpp::Rcout << "Steps needed: " << nloop << std::endl;
		for(R_xlen_t idk = 0; idk < nloop; idk++)
		{
			//Rcpp::Rcout << "Temp = " << temperature << std::endl;
			for(R_xlen_t k = 0; k < (R_xlen_t)(100*n*effortMultiplier); k++)
			{
				R_xlen_t swap1, swap2;
				//swap
				if(unif_rand() <= 0.5)
				{
					getPairForSwap(n, swap1, swap2);
					double delta = computeDelta(currentPermutation, swap1, swap2, rawDist, levels, deltaComponents);
					if(delta > -1e-8)
					{
						z += delta;
						std::swap(currentPermutation[swap1], currentPermutation[swap2]);
						if(z > zbestThisRep)
						{
							zbestThisRep = z;
							bestPermutationThisRep = currentPermutation;
						}
					}
					else
					{
						if(unif_rand() <= exp(delta / temperature))
						{
							z += delta;
							std::swap(currentPermutation[swap1], currentPermutation[swap2]);
						}
					}
				}
				//insertion
				else
				{
					getPairForMove(n, swap1, swap2, maxMove);
					double delta = computeMoveDelta(deltaComponents, swap1, swap2, currentPermutation, rawDist, n, levels);
					int permutedSwap1 = currentPermutation[swap1];
					if(delta > -1e-8 || unif_rand() <= exp(delta / temperature))
					{
						z += delta;
						if(swap2 > swap1)
						{
							for(R_xlen_t i = swap1; i < swap2; i++)
							{
								currentPermutation[i] = currentPermutation[i+1];
							}
							currentPermutation[swap2] = (int)permutedSwap1;
						}
						else
						{
							for(R_xlen_t i = swap1; i > swap2; i--)
							{
								currentPermutation[i] = currentPermutation[i-1];
							}
							currentPermutation[swap2] = (int)permutedSwap1; 
						}
					}
					if(delta > -1e-8 && z > zbestThisRep)
					{
						bestPermutationThisRep = currentPermutation;
						zbestThisRep = z;
					}
				}
				done++;
				threadZeroCounter++;
				if(threadZeroCounter % 100 == 0)
				{
					progressFunction(done, totalSteps);
				}
			}
			temperature *= cool;
		}
		if(zbestThisRep > zbestAllReps)
		{
			zbestAllReps = zbestThisRep;
			permutation.swap(bestPermutationThisRep);
		}
	}
	PutRNGstate();
}