std::set<Affinity> AffinityTask::powerSet(const Affinity& affinity)
{
	assert(affinity.size() < 64);
	assert(affinity.size() > 0);
	std::set<Affinity> ret;
	std::vector<CPUID> listedAffinity;
	for(CPUID cpu : affinity)
		listedAffinity.push_back(cpu);

	uint64_t powerCount = 1 << (affinity.size());
	for(uint64_t k=1; k<powerCount; k++)
	{
		Affinity subset;
		for(uint64_t index=0; index<affinity.size(); index++)
		{
			if( (1UL << index) & k )
			{
				subset.insert(listedAffinity[index]);
			}
		}
		ret.insert(subset);
	}
	return ret;
}
AffinityTask::TaskSet AffinityTask::generateTaskSet(Computer* computer, Size numTask,
		RandomDistribution* affinityDistribution,
		Time minPeriod, Time maxPeriod, RandomDistribution* periodDistribution,
		Real targetUtilization, RandomDistribution* utilDistribution)
{
	AffinityTask::TaskSet ret;
	CPUID maxAffinity = computer->getNumCPU();
	UniformDistribution selector;
	Real sum = 0;
	for(Real util : utilDistribution->distribute(numTask, targetUtilization))
	{
		util = std::min(1.0, util);
		Real realAffinity = affinityDistribution->nextDistribution(0, maxAffinity);
		Size currentAffinityCount = ceil(realAffinity);
		currentAffinityCount = std::min(currentAffinityCount, maxAffinity);
		currentAffinityCount = std::max(currentAffinityCount, (Size)1);

		Real realPeriod = periodDistribution->nextDistribution(minPeriod, maxPeriod);
		Time period = ceil(realPeriod);
		period = std::max(minPeriod, period);
		period = std::min(maxPeriod, period);

		Real realExecution = util * (Real)period;
		Time execution = floor(realExecution);
		if(execution == 0)
			continue;

		sum+=util;

		Affinity affinity;

		while(affinity.size() != currentAffinityCount)
		{
			CPUID selected = floor(selector.nextDistribution(0, maxAffinity));
			if(selected == maxAffinity)
				selected = maxAffinity-1;
			affinity.insert(selected);
		}

		AffinityTask* task = new AffinityTask(affinity, computer, period, execution, 0);
		ret.insert(task);
	}
	//printf("Sum of util %f\n", sum);
	return ret;

}