Пример #1
0
/**
 * Generates a random chain connecting the start and end observations of the
 * given data object for the given period. The chain is simple in the sense
 * that no two ministeps cancel each other out.
 */
void Chain::connect(int period, MLSimulation * pMLSimulation)
{
	this->clear();
	this->lperiod = period;
	vector<MiniStep *> miniSteps;

	// Create the required ministeps

	for (unsigned variableIndex = 0;
		variableIndex < this->lpData->rDependentVariableData().size();
		variableIndex++)
	{
		LongitudinalData * pVariableData =
			this->lpData->rDependentVariableData()[variableIndex];
		NetworkLongitudinalData * pNetworkData =
			dynamic_cast<NetworkLongitudinalData *>(pVariableData);
		BehaviorLongitudinalData * pBehaviorData =
			dynamic_cast<BehaviorLongitudinalData *>(pVariableData);

		if (pNetworkData)
		{
			const Network * pNetwork1 = pNetworkData->pNetwork(period);
			const Network * pNetwork2 = pNetworkData->pNetwork(period + 1);

			for (int i = 0; i < pNetwork1->n(); i++)
			{
				IncidentTieIterator iter1 = pNetwork1->outTies(i);
				IncidentTieIterator iter2 = pNetwork2->outTies(i);

				while (iter1.valid() || iter2.valid())
				{
					if (iter1.valid() &&
						(!iter2.valid() || iter1.actor() < iter2.actor()))
					{
						if (!pNetworkData->structural(i, iter1.actor(),
								period)
							//	|| !pNetworkData->structural(i, iter1.actor(),
							//	period + 1)
							)
						{
							miniSteps.push_back(
								new NetworkChange(pNetworkData,
									i,
									iter1.actor(), false));
							iter1.next();
						}
						else
						{
							// create step in structural subchain?
						}
					}
					else if (iter2.valid() &&
						(!iter1.valid() || iter2.actor() < iter1.actor()))
					{
						if (!pNetworkData->structural(i, iter2.actor(),
								period)
							//	|| !pNetworkData->structural(i, iter2.actor(),
							// period + 1)
							)
						{
							miniSteps.push_back(
								new NetworkChange(pNetworkData,
									i,
									iter2.actor(), false));
							iter2.next();
						}
						else
						{
							// create step in structural subchain?
						}
					}
					else
					{
						iter1.next();
						iter2.next();
					}
				}
			}
		}
		else if (pBehaviorData)
		{
			for (int i = 0; i < pBehaviorData->n(); i++)
			{
				int delta = pBehaviorData->value(period + 1, i) -
					pBehaviorData->value(period, i);
				int singleChange = 1;

				if (delta < 0)
				{
					delta = -delta;
					singleChange = -1;
				}

				for (int j = 0; j < delta; j++)
				{
					if (!pBehaviorData->structural(period, j)
						//|| !pBehaviorData->structural(period, j + 1)
						)

					{
						miniSteps.push_back(
							new BehaviorChange(pBehaviorData,
								i,
								singleChange));
					}
					else
					{
						// create step in structural subchain?
					}
				}
			}
		}
	}

	// If we have no constraints we can go ahead and add to the chain in a
	// random order. If we do have contraints we need to make sure our chain
	// is valid. For now we have two distinct loops:

	if (this->lpData->rNetworkConstraints().size()  == 0)
	{
		// Randomize the ministeps

		for (unsigned i = 1; i < miniSteps.size(); i++)
		{
			int j = nextInt(i + 1);
			MiniStep * pTempMiniStep = miniSteps[i];
			miniSteps[i] = miniSteps[j];
			miniSteps[j] = pTempMiniStep;
		}

		// And finally add the ministeps to this chain

		for (unsigned i = 0; i < miniSteps.size(); i++)
		{
			this->insertBefore(miniSteps[i], this->lpLast);
		}
	}
	else
	{
		unsigned count = 0;
		vector<MiniStep *> remainingMiniSteps;
		while(miniSteps.size() > 0 &&
			count < this->lpData->rDependentVariableData().size())
		{
			count++;
			remainingMiniSteps.clear();
			for (unsigned i = 0; i < miniSteps.size(); i++)
			{
				// first try random insert
				//const NetworkChange * pNetworkChange =
				//	dynamic_cast<const NetworkChange *>(miniSteps[i]);
				MiniStep * pMiniStep =
					this->randomMiniStep(this->lpFirst->pNext(),
						this->lpLast);
				bool valid = false;
				if (miniSteps[i]->behaviorMiniStep())
				{
					valid = true;
				}
				else
				{
					// get current state at this place
					pMLSimulation->initialize(this->lperiod);
					pMLSimulation->executeMiniSteps(this->lpFirst->pNext(),
						pMiniStep);
					// see if valid here
					DependentVariable * pVariable =
						pMLSimulation->rVariables()[miniSteps[i]->variableId()];
					//	PrintValue(getMiniStepDF(*miniSteps[i]));

					if (!pVariable->validMiniStep(miniSteps[i]))
					{
						//		Rprintf("first inval\n");
						// no go, so try to find somewhere else to put it
						MiniStep * pLastMiniStep =
							this->pLastMiniStepForLink(miniSteps[i]);
						if (pLastMiniStep != this->lpFirst)
						{
							//		Rprintf("lastl\n");
							//	PrintValue(getMiniStepDF(*pLastMiniStep));
							pMiniStep =
								this->randomMiniStep(pLastMiniStep->pNext(),
									this->lpLast);
							//	PrintValue(getMiniStepDF(*pMiniStep));
							pMLSimulation->initialize(this->lperiod);
							pMLSimulation->executeMiniSteps(this->lpFirst->
								pNext(), pMiniStep);
							// see if valid here
							if (!pVariable->validMiniStep(miniSteps[i]))
							{
								//		Rprintf("second inval\n");
								// no go, so try to find somewhere else to put
								// it
								MiniStep * pFirstMiniStep =
									this->pFirstMiniStepForLink(miniSteps[i]);
								//	if (pFirstMiniStep != this->lpFirst)
								//{
								//	PrintValue(getMiniStepDF(*pFirstMiniStep));
								pMiniStep =
									this->randomMiniStep(this->
										lpFirst->pNext(),
										pFirstMiniStep);
								//	PrintValue(getMiniStepDF(*pMiniStep));
								pMLSimulation->initialize(this->lperiod);
								pMLSimulation->
									executeMiniSteps(pFirstMiniStep,
										pMiniStep);
								// see if valid here
								if (pVariable->validMiniStep(miniSteps[i]))
								{
									Rprintf("thirsd true val\n");
									valid = true;
								}
								//	}
							}
							else
							{
								valid = true;
							}
						}
					}
					else
					{
						valid = true;
					}
				}
				if (valid)
				{
					this->insertBefore(miniSteps[i], pMiniStep);
				}
				else
				{
					remainingMiniSteps.push_back(miniSteps[i]);
				}
			}
			miniSteps = remainingMiniSteps;
		}
		//	PrintValue(getChainDF(*this, false));
		//	Rprintf("****** count %d\n", count);
		if (miniSteps.size() > 0)
		{
			for (unsigned i = 0; i < miniSteps.size(); i++)
			{
				PrintValue(getMiniStepDF(*miniSteps[i]));
			}

			error("Cannot create minimal chain due to constraints");
		}
	}
}