Пример #1
0
void Restaurant::updateSeatingForDpp(void) {

	for (int idx=0; idx<numPatrons; idx++)
		{
		// get a pointer to the element and its current table
		Patron *p = patrons[idx];
		Table *tablePtr = p->getTable();

		// remove the element from the table
		tablePtr->removePatronFromTable(p);
		if (tablePtr->getNumPatrons() == 0)
			deleteTable(tablePtr);
		
		// calculate the likelihood when the element is seated at all possible tables
		vector<double> probs;
		for (int i=0; i<getNumTables(); i++)
			{
			Table *tp = getTable(i);
			probs.push_back( tp->lnLikelihood(p) + log(tp->getNumPatrons()) );
			}
		probs.push_back( p->getLnLikelihoodalone() + log(concentrationParm) );
		normalizeVector( probs );

		// pick a table for reassignment
		int whichTable = multinomialRv(probs);
			
		// add the element to that table
		if (whichTable < getNumTables())
			{
			tablePtr = getTable(whichTable);
			tablePtr->addPatronToTable(p);
			}
		else
			{
			tablePtr = new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial);
			addTableToRestaurant( tablePtr );
			tablePtr->addPatronToTable(p);
			}
		}
}
Пример #2
0
void Restaurant::updateSeatingForFixedTables(void) {

	// allocate memory for reassignment probabilities
	vector<double> probs;
	
	// loop over all patrons, attempting to reseat each
	for (int idx=0; idx<numPatrons; idx++)
		{
		// get a pointer to the element and its current table
		Patron *p = patrons[idx];
		Table *tablePtr = p->getTable();

		// remove the element from the table
		tablePtr->removePatronFromTable(p);
		if (assumingAdmixture == true)
			popCounts[ p->getIndividual() ][ getIndexForTable(tablePtr) ]--;
		
		// calculate the likelihood when the element is seated at all possible tables
		for (int i=0; i<getNumTables(); i++)
			{
			Table *tp = getTable(i);
			double lnC = 0.0;
			if (assumingAdmixture == true)
				lnC = log( popProbs[ p->getIndividual() ][ i ] );
			probs.push_back( tp->lnLikelihood(p) + lnC );
			}
		normalizeVector( probs );

		// pick a table for reassignment
		tablePtr = getTable( multinomialRv(probs) );
			
		// add the element to that table
		tablePtr->addPatronToTable(p);
		if (assumingAdmixture == true)
			popCounts[ p->getIndividual() ][ getIndexForTable(tablePtr) ]++;
			
		// clear the probs vector
		probs.clear();
		}
}
Пример #3
0
void Restaurant::initializeTables(void) {

	if (assumingDpp == true)
		{
		// Dirichlet process prior model
		for (int i=0; i<numPatrons; i++)
			{
			double probNewTable = concentrationParm / (i + concentrationParm);
			double u = ranPtr->uniformRv();
			bool successfullyAddedPatron = false;
			if (u < probNewTable)
				{
				Table *tab = new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial);
				tables.push_back( tab );
				tab->addPatronToTable( patrons[i] );
				patrons[i]->setTable(tab);
				successfullyAddedPatron = true;
				}
			else
				{
				double sum = probNewTable;
				for (vector<Table *>::iterator p=tables.begin(); p != tables.end(); p++)
					{
					sum += (double)(*p)->getNumPatrons() / (i + concentrationParm);
					if (u < sum)
						{
						(*p)->addPatronToTable( patrons[i] );
						patrons[i]->setTable( (*p) );
						successfullyAddedPatron = true;
						break;
						}
					}
				}
			if (successfullyAddedPatron == false)
				{
				Stmessage::error("Failed to add patron to table");
				return;
				}
			}
		}
	else
		{
		// fixed number of tables
		for (int i=0; i<modelPtr->getNumPopulations(); i++)
			tables.push_back( new Table(this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), lnFactorial) );
		MbVector<int> patronIndices(numPatrons);
		for (int i=0; i<numPatrons; i++)
			patronIndices[i] = i;
		for (int i=0; i<tables.size(); i++)
			{
			int whichPatron = (int)(ranPtr->uniformRv()*(numPatrons-i));
			Patron *p = patrons[ patronIndices[whichPatron] ];
			tables[i]->addPatronToTable( p );
			p->setTable(tables[i]);
			int tempIdx = patronIndices[numPatrons-i-1];
			patronIndices[numPatrons-i-1] = patronIndices[whichPatron];
			patronIndices[whichPatron] = tempIdx;
			}
		for (int i=tables.size(); i<numPatrons; i++)
			{
			int whichPatron = (int)(ranPtr->uniformRv()*(numPatrons-i));
			Patron *p = patrons[ patronIndices[whichPatron] ];
			int whichTable = (int)(ranPtr->uniformRv()*tables.size());
			tables[whichTable]->addPatronToTable( p );
			p->setTable(tables[whichTable]);
			int tempIdx = patronIndices[numPatrons-i-1];
			patronIndices[numPatrons-i-1] = patronIndices[whichPatron];
			patronIndices[whichPatron] = tempIdx;
			}
		}
}
Пример #4
0
void Franchise::updateSeating(void) {

	// loop over the restaurants
	for (vector<Restaurant *>::iterator r=restaurants.begin(); r != restaurants.end(); r++)
		{
		// loop over the patrons in a restaurant
		for (int idx=0; idx<(*r)->getNumPatronsInRestaurant(); idx++)
			{
			// get a pointer to the patron and its current table
			Patron *p = (*r)->getRestaurantPatron(idx);
			Table *tablePtr = p->getTable();
			Menu *menuItemPtr = tablePtr->getMenuItem();

			// remove the element from the table
			tablePtr->removePatronFromTable(p);
			if (tablePtr->getNumPatrons() == 0)
				{
				menuItemPtr->deleteTableFromMenu(tablePtr);
				if (menuItemPtr->getNumTables() == 0)
					deleteMenuItem(menuItemPtr);
				(*r)->deleteTable(tablePtr);
				}
				
			// calculate the probability of reseating patron at each of the tables
			int n = (*r)->getNumTables() + 1;
			vector<double> probs;
			for (int i=0; i<(*r)->getNumTables(); i++)
				{
				Table *t = (*r)->getTable(i);
				Menu *m = t->getMenuItem();
				int n_jt = t->getNumPatrons();
				probs.push_back( m->lnLikelihood(p) + log(n_jt) );
				}
			vector<double> lnProbsNew;
			probs.push_back( log(restaurantAlpha) + lnLikelihoodNewTable(p, lnProbsNew) );
			(*r)->normalizeVector(probs);
			
			// pick a table
			int whichTable = (*r)->multinomialRv( probs );
			Table *newTablePtr = NULL;
			if  (whichTable < n-1)
				newTablePtr = (*r)->getTable(whichTable);
			
			// seat the patron
			if (newTablePtr == NULL)
				{
				// we are seating the patron at a new table, which may have an already used menu item, or a brand new menu item
				Table *newRestaurantTablePtr = new Table( (*r), ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), (*r)->getFactorialPtr() );
				newRestaurantTablePtr->addPatronToTable( p );
				(*r)->addTableToRestaurant( newRestaurantTablePtr );
				(*r)->normalizeVector(lnProbsNew);
				whichTable = (*r)->multinomialRv( lnProbsNew );
				Menu *newMenuItemPtr = NULL;
				if (whichTable < lnProbsNew.size()-1)
					{
					newMenuItemPtr = menus[whichTable];
					}
				else
					{
					newMenuItemPtr = new Menu( this, ranPtr, observationsPtr, observationsPtr->getNumUniqueAlleles(), (*r)->getFactorialPtr() );
					menus.push_back( newMenuItemPtr );
					}
				newMenuItemPtr->addTableToMenu( newRestaurantTablePtr );
				newRestaurantTablePtr->setMenuItem(newMenuItemPtr);
				}
			else
				{
				// otherwise, we are seating the element at one of the pre-existing tables
				newTablePtr->addPatronToTable( p );
				}
			
		//print();
		//getchar();
			}
		}
}