bool CVMState::moveCentsToTransactionStorage(int cents) {
     int* changeArray = new int[3];
     changeArray = makeChange(cents, totalQuarters,
                              totalDimes, totalNickels, changeArray);
     if (changeArray == NULL) {
         delete changeArray;
         return false;
     } else {
         moveChangeToTransactionStorage(changeArray);
         delete changeArray;
         return true;
     }
 }
 bool CVMState::moveCentsToMainStorage(int cents) {
     int* changeArray = new int[3];
     changeArray = makeChange(cents, currentQuarters,
                              currentDimes, currentNickels, changeArray);
     if (changeArray == NULL) {
         delete changeArray;
         return false;
     } else {
         moveChangeToMainStorage(changeArray);
         delete changeArray;
         return true;
     }
 }
Esempio n. 3
0
int makeChange(int n, int denom) {
	int next_denom = 0;
	switch (denom) {
		case 25:
		next_denom = 10;
	break;
		case 10:
		next_denom = 5;
	break;
		case 5:
		next_denom = 1;
	break;
		case 1:
		printf("makeChange: %d, %d\n", n, denom);
		return 1;
	}	
	
	int ways = 0;
	for (int i = 0; i * denom <= n; i++) {
		ways += makeChange(n - i * denom, next_denom);
	}
	return ways;
}
 int* CVMState::makeChangeFor(int changeCents, int* changeArray) {
     changeArray = makeChange(changeCents, currentQuarters,
                              currentDimes, currentNickels, changeArray);
     return changeArray;
 }
Esempio n. 5
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();
}