void Neighborhood::move(unsigned int old_x, unsigned int old_y)
{
	//unsigned int new_x = mtrand(0, (size_x - 1));
	//unsigned int new_y = mtrand(0, (size_y - 1));
	//
	//	while (neighborhood_[new_x, new_y].getType() != "empty")
	//	{

	//		new_x = mtrand(0, (size_x - 1));
	//		new_y = mtrand(0, (size_y - 1));


	//	}

	//	
	//		neighborhood_[new_x, new_y].getType() = neighborhood_[old_x, old_y].getType();
	//		neighborhood_[old_x, old_y].getType() = "empty";
		
	

	for (;;)
	{
		unsigned int x = mtrand(0, size_x - 1);
		unsigned int y = mtrand(0, size_y - 1);
															// not my code, borrowed from HyrekanDragon because mine^^ wouldnt work
		if (get(x, y).getType() == "empty")
		{
			set(x, y, get(old_x, old_y));
			set(old_x, old_y, Shape("empty"));

			break;
		}
	}

}
示例#2
0
Neighborhood::Neighborhood(unsigned int size_x, unsigned int size_y)
    : size_x(size_x), size_y(size_y) {

    neighborhood_ = new Shape[size_x * size_y];

    for(int i = 0; i < (size_x * size_y); i++) {

        neighborhood_[i].setType("empty");

    }
    for(int i=0, j=128; i < (j * RATIO_FILLED); i++) {
        int x = mtrand(0, size_x - 1);
        int y = mtrand(0, size_y - 1);

        if(this -> get(x, y).getType() == "empty") {

            if( mtrand(0,1) == 0) {

                neighborhood_[i].setType("triangle");

            }
            else {

                neighborhood_[i].setType("square");

            }
            j--;
        }
    }

}
Neighborhood::Neighborhood(unsigned int size_x, unsigned int size_y) : size_x(size_x), size_y(size_y)
{

	for (double i = 0; (i / (size_x*size_y)) < RATIO_FILLED; i++)
	{
		neighborhood_ = new Shape[size_x * size_y];

		// fill with non-empty shapes so that the ratio of non-empty to empty
		// shapes is `RATIO_FILLED` (from `constants.h`)
		for (int filled = 0; filled < size_x*size_y*RATIO_FILLED; )
		{
			unsigned int x = mtrand(0, size_x - 1);
			unsigned int y = mtrand(0, size_y - 1);

			if (this->get(x, y).getType() == "empty") {
				this->set(x, y, mtrand(0, 1) ? Shape("triangle")
					: Shape("square"));
				filled++;
			}
		}



	}

}
void Neighborhood::move(unsigned int old_x, unsigned int old_y) {
    for (;;) {
        unsigned int x = mtrand(0, size_x-1);
        unsigned int y = mtrand(0, size_y-1);

        if (get(x, y).getType() == "empty") {
            set(x, y, get(old_x, old_y));
            set(old_x, old_y, Shape("empty"));

            break;
        }
    }
}
GAindividual mutateNetwork(GAindividual p)
{
	ReactionNetwork * r = (ReactionNetwork*)(p);
	int n0, n1, i;
	double * iv;
	int * fixed;
	GAMutateFnc f;

	GAindividual net;

	if (!r || (r->type < 0) || (r->type > NUMBER_OF_NETWORK_TYPES)) return p;

	f = mutateFunctions[r->type];
	n0 = getNumSpecies(r);

	if (f)
	{
		net = f(r->network);
		r->network = net;
		n1 = getNumSpecies(r);
		if (n0 != n1)
		{
			iv = r->initialValues;
			fixed = r->fixed;
			r->initialValues = (double*)malloc(n1 * sizeof(double));
			r->fixed = (int*)malloc(n1 * sizeof(double));
			for (i=0; i < n0 && i < n1; ++i)
			{
				r->initialValues[i] = iv[i];
				r->fixed[i] = fixed[i];
			}
			for (i=n0; i < n1; ++i)
			{
				r->initialValues[i] = AVG_INIT_VALUES * mtrand();
				r->fixed[i] = 0;
			}
			free(iv);
		}

		if (mtrand() < MUTATE_INIT_VALUE_PROB)
		{
			r->initialValues[ (int)(mtrand() * getNumSpecies(r)) ] *= 2.0 * mtrand();
		}
		return r;
	}

	return 0;
}
示例#6
0
/*Mix two parameter arrays*/
void * crossover(void * individual1, void * individual2)
{
   int i;
   Parameters 	* net1 = (Parameters*)individual1,
				* net2 = (Parameters*)individual2,
				* net3 = (Parameters*)clone(individual1);
   
   if (mtrand() < 0.5)
   {
      for (i = 0; i < (*net3).numParams; ++i)
      {
         (*net3).params[i] = (*net1).params[i];
      }
      for (i = 0; i < (*net3).numVars; ++i)
      {
         (*net3).alphas[i] = (*net2).alphas[i];
      }
   }
   else
   {
      for (i = 0; i < (*net3).numVars; ++i)
      {
         (*net3).alphas[i] = 0.5 * ((*net1).alphas[i] + (*net2).alphas[i]);
      }
      for (i = 0; i < (*net3).numParams; ++i)
      {
         (*net3).params[i] = 0.5 * ((*net1).params[i] + (*net2).params[i]);
      }
   }
   normalize((*net3).alphas , (*net3).numVars);
   return ((void*)net3);
}
示例#7
0
int main(int argc, char ** argv)
{
  int numElems, seed, range;
  int * elems;
  if (argc != 5)
  {
    printf("Usage: %s output_file num_elements random_seed range\n", *argv);
    return 0;
  }
  FILE * fp = fopen(argv[1], "wb");
  MTRand mtrand(atoi(argv[3]));

  elems = new int[16 * 1024];
  numElems = atoi(argv[2]);
  range = atoi(argv[4]);
  int numLeft = numElems;
  printf("writing %s.\n", argv[1]); fflush(stdout);
  while (numLeft > 0)
  {
    printf("\r                                                        \r%d / %d", numElems - numLeft, numElems); fflush(stdout);
    int numToGen = std::min(16 * 1024, numLeft);
    numLeft -= numToGen;
    for (int i = 0; i < numToGen; ++i) elems[i] = mtrand.randInt(range);
    fwrite(elems, sizeof(int) * numToGen, 1, fp);
  }
  printf("\r                                                          \r%d / %d\ndone\n", numElems, numElems); fflush(stdout);

  fclose(fp);
}
示例#8
0
void SteadyState::fitConservationRules( 
	gsl_matrix* U, const vector< double >& eliminatedTotal,
		vector< double >&y
	)
{
	int numConsv = total_.size();
	int lastJ = numVarPools_;
	for ( int i = numConsv - 1; i >= 0; --i ) {
		for ( unsigned int j = 0; j < numVarPools_; ++j ) {
			double g = gsl_matrix_get( U, i, j );
			if ( fabs( g ) > EPSILON ) {
				// double ytot = calcTot( g, i, j, lastJ );
				double ytot = 0.0;
				for ( int k = j; k < lastJ; ++k ) {
					y[k] = mtrand();
					ytot += y[k] * gsl_matrix_get( U, i, k );
				}
				assert( fabs( ytot ) > EPSILON );
				double lastYtot = 0.0;
				for ( unsigned int k = lastJ; k < numVarPools_; ++k ) {
					lastYtot += y[k] * gsl_matrix_get( U, i, k );
				}
				double scale = ( eliminatedTotal[i] - lastYtot ) / ytot;
				for ( int k = j; k < lastJ; ++k ) {
					y[k] *= scale;
				}
				lastJ = j;
				break;
			}
		}
	}
}
示例#9
0
void Neighborhood::move(unsigned int old_x, unsigned int old_y) {

    int new_x, new_y;

    do {

        new_x = mtrand(0, size_x-1);
        new_y = mtrand(0, size_y-1);

    } while(get(new_x, new_y).getType() != "empty");


    set(new_x, new_y, get(old_x, old_y));
    set(old_x, old_y, Shape("empty"));


}
Neighborhood::Neighborhood(unsigned int size_x, unsigned int size_y)
	: size_x(size_x), size_y(size_y){

	neighborhood_ = new Shape[size_x * size_y]();

	for (int filled = 0; filled < size_x*size_y*RATIO_FILLED;) {
		unsigned int x = mtrand(0, size_x - 1);
		unsigned int y = mtrand(0, size_y - 1);

		if (this->get(x, y).getType() == "empty") {
			this->set(x, y, mtrand(0, 1) ? Shape("triangle")
				: Shape("square"));

			filled++;
		}
	}
}
示例#11
0
GApopulation randomEnzymeNetworks(int num)
{
	int i,j;
	MassActionNetwork * mnet;
	EnzymeNetwork * enet;
	GApopulation pop = randomMassActionNetworks(num);

	for (i=0; i < num; ++i)
	{
		mnet = (MassActionNetwork*)pop[i];
		enet = (EnzymeNetwork*) malloc(sizeof(EnzymeNetwork));
		enet->enzymes = (int*) malloc( mnet->reactions * sizeof(int) );
		enet->Keq = (double*) malloc( mnet->reactions * sizeof(double) );
		enet->h = (double*) malloc( mnet->reactions * sizeof(double) );
		enet->alpha = (double*) malloc( mnet->reactions * sizeof(double) );
		enet->S_half = (double*) malloc( mnet->reactions * sizeof(double) );
		enet->P_half = (double*) malloc( mnet->reactions * sizeof(double) );
		for (j=0; j < mnet->reactions; ++j)
		{
			enet->enzymes[j] = (int)(mtrand() * mnet->species);
			enet->Keq[j] = mtrand() * pow(2, (KEQ_LN_MIN + (KEQ_LN_MAX - KEQ_LN_MIN) * mtrand()));
			enet->alpha[j] = mtrand() * pow(2, (ALPHA_LN_MIN + (ALPHA_LN_MAX - ALPHA_LN_MIN) * mtrand()));
			enet->h[j] = H_MIN + (H_MAX - H_MIN) * mtrand();
			enet->S_half[j] = S_HALF_MIN + (S_HALF_MAX - S_HALF_MIN) * mtrand();
			enet->P_half[j] = P_HALF_MIN + (P_HALF_MAX - P_HALF_MIN) * mtrand();
		}
		enet->massActionNetwork = mnet;
		pop[i] = enet;
	}
	
	return pop;
}
void GssaStoich::innerProcessFunc( Eref e, ProcInfo info )
{
	double nextt = info->currTime_ + info->dt_;
	while ( t_ < nextt ) {
		// Figure out when the reaction will occur. The atot_
		// calculation actually estimates time for which reaction will
		// NOT occur, as atot_ sums all propensities.
		if ( atot_ <= 0.0 ) { // Nothing is going to happen.
			// We have to advance t_ because we may resume calculations
			// with a different atot at a later time.
			t_ = nextt;
			break;
		}
		unsigned int rindex = pickReac(); // Does a randnum call
		if ( rindex >= rates_.size() ) {
			// Probably cumulative roundoff error here. Simply
			// recalculate atot to avoid, and redo.
			updateAllRates();
			continue;
		}
		transN_.fireReac( rindex, S_ );

		// Ugly stuff for molecules buffered after run started.
		// Inherited from Stoich. Here we just need to restore the
		// n's in the dynamic buf list to their nInit. Note that
		// any updates of nInit will percolate through the
		// kineticHub to GssaStoich::setMolN, which will update
		// all rates, so things should keep track.
		// Only issue is that the changing of the mode itself should
		// trigger the update of all rates.
		updateDynamicBuffers();
		// Math expns must be first, because they may alter 
		// substrate mol #.
		updateDependentMathExpn( dependentMathExpn_[ rindex ] );
		// The rates list includes rates dependent on mols changed
		// by the MathExpns.
		updateDependentRates( dependency_[ rindex ] );

		double r = mtrand();
		while ( r <= 0.0 )
			r = mtrand();
		t_ -= ( 1.0 / atot_ ) * log( r );
		// double dt = ( 1.0 / atot_ ) * log( 1.0 / mtrand() );
	}
}
示例#13
0
/**
 * Returns number of synapses formed.
 * Fills it in transpose form, because we need to count and index the 
 * number of synapses on the target, so we need to iterate over the sources
 * in the inner loop. Once full, does the transpose.
 * Should really have a seed argument for the random number.
 * Later need a way to fast-forward mtrand to just the entries we
 * need to fill.
 */
unsigned int SparseMsg::randomConnect( double probability )
{
	unsigned int nRows = matrix_.nRows(); // Sources
	unsigned int nCols = matrix_.nColumns();	// Destinations
	matrix_.clear();
	unsigned int totalSynapses = 0;
	vector< unsigned int > sizes( nCols, 0 );
	unsigned int totSynNum = 0;
	Element* syn = e2_;
	unsigned int startData = syn->localDataStart();
	unsigned int endData = startData + syn->numLocalData();

	assert( nCols == syn->numData() );

	matrix_.transpose();
	for ( unsigned int i = 0; i < nCols; ++i ) {
		vector< unsigned int > synIndex;
		// This needs to be obtained from current size of syn array.
		// unsigned int synNum = sizes[ i ];
		unsigned int synNum = 0;
		for ( unsigned int j = 0; j < nRows; ++j ) {
			double r = mtrand(); // Want to ensure it is called each time round the loop.
			if ( r < probability ) {
				synIndex.push_back( synNum );
				++synNum;
				++totSynNum;
			} else {
				synIndex.push_back( ~0 );
			}
		}
			
		if ( i >= startData && i < endData ) {
			e2_->resizeField( i - startData, synNum );
		}
			totalSynapses += synNum;
			matrix_.addRow( i, synIndex );
		/*
		 * This is the correct form, but I need to implement something
		 * to check up for target nodes in order to use this.
		if ( i >= startData && i < endData ) {
			e2_->resizeField( i - startData, synNum );
			totalSynapses += synNum;
			matrix_.addRow( i, synIndex );
		} else {
			synIndex.resize( 0 );
			synIndex.assign( nRows, ~0 );
			matrix_.addRow( i, synIndex );
		}
		*/
	}

	matrix_.transpose();
	// cout << Shell::myNode() << ": sizes.size() = " << sizes.size() << ", ncols = " << nCols << ", startSynapse = " << startSynapse << endl;
	e1()->markRewired();
	e2()->markRewired();
	return totalSynapses;
}
示例#14
0
int main(){
    int i,j,a[L];
    printf("generate the default data:\n");
    mtrand(a, 30);
    printf("the default data is bellow:\n");
    printArray(a, L);
    quickSort(a, 0, L-1);
    printf("the sort data is bellow:\n");
    printArray(a, L);
    getche();
}
示例#15
0
/*randomly change the values of a parameter array*/
void * mutate(void * individual)
{
   int i,j,n,m;
   Parameters * p = (Parameters*)individual;

   n = p->numParams;
   m = p->numVars;

   if (mtrand() < 0.5)
   {
      i = (int)(mtrand() * n);
      p->params[i] *= randnum;
   }
   else
   {
      j = (int)(mtrand() * m);
      p->alphas[j] *= 2.0 * randnum - 1.0;
   }
   normalize (p->alphas , m);
   return (p);
}
示例#16
0
int check_token_for_MT19937_time_seed(const char *token)
{
	unsigned char tb[128] = {0};
	hex_str_to_binary(token, tb);

	struct mt *rng = init_mtrand();

	int i, r, t = time(NULL);
	for (i = 0; i < 1000; ++i) {
		seed_mtrand(rng, t - i);
		r = mtrand(rng);
		if (memcmp(&r, tb, 4) == 0) {
			return t;
		}
		if (tb[0] == (r & 0xff) && tb[1] == (mtrand(rng) & 0xff) &&
				tb[2] == (mtrand(rng) & 0xff)) {
			return t;
		}
	}
	return 0;
}
示例#17
0
文件: other.cpp 项目: nafest/zenbench
 virtual void SetUp() override
 {
     zenbench::Benchmark::SetUp();
     std::mt19937  mtrand;
     
     
     vec.resize(size);
     // put your initialization code here
     for (int i = 0; i < size; i++)
     {
         vec[i] = mtrand();
     }
 }
示例#18
0
size_t CGameServer::CreateEntity(const tstring& sClassName, size_t iHandle, size_t iSpawnSeed)
{
	if (CVar::GetCVarBool("net_debug"))
		TMsg(tstring("Creating entity: ") + sClassName + "\n");

	auto it = CBaseEntity::GetEntityRegistration().find(sClassName);
	if (it == CBaseEntity::GetEntityRegistration().end())
	{
		TAssert(!"Entity does not exist. Did you forget to REGISTER_ENTITY ?");
		return ~0;
	}

	CBaseEntity::s_iOverrideEntityListIndex = iHandle;
	iHandle = it->second.m_pfnCreateCallback();
	CBaseEntity::s_iOverrideEntityListIndex = ~0;

	CEntityHandle<CBaseEntity> hEntity(iHandle);
	hEntity->m_sClassName = sClassName;

	hEntity->SetSaveDataDefaults();

	size_t iPostSeed = mtrand();

	if (iSpawnSeed)
		hEntity->SetSpawnSeed(iSpawnSeed);
	else
		hEntity->SetSpawnSeed(mtrand()%99999);	// Don't pick a number so large that it can't fit in (int)

	hEntity->SetSpawnTime(GameServer()->GetGameTime());

	hEntity->Spawn();

	mtsrand(iPostSeed);

	if (dynamic_cast<CGame*>(hEntity.GetPointer()))
		m_hGame = CEntityHandle<CGame>(hEntity->GetHandle());

	return iHandle;
}
void RandomSpike::innerProcessFunc(const Conn* c, ProcInfo p)
{
    double t = p->currTime_;
    
    if ( reset_ )
    {
        state_ = resetValue_;
    }
    if ( absRefract_ > t - lastEvent_ )
    {
        return;
    }

    double prob = 0.0;
    if (isi_ >= 0.0){ // this is being fed by an RNG
        if ((lastEvent_ + isi_ - t >= 0.0) && (lastEvent_ + isi_ - t < p->dt_)){
            prob = 1.0;
        }
    } else {
        prob = rate_*p->dt_;
    }
    if ( prob >= 1 || prob > mtrand())
    {
        lastEvent_ = t;
        if (!isEqual(minAmp_,maxAmp_))
        {
            state_ = mtrand()*( maxAmp_ - minAmp_ ) + minAmp_;
        }
        else
        {
            state_ = minAmp_;
        }        
	send1 <double> ( c->target(), eventSlot, t);    
	send1 <double> ( c->target(), outputSlot, state_);    
    }
}
unsigned int GssaStoich::pickReac()
{
	double r = mtrand() * atot_;
	double sum = 0.0;
	// This is an inefficient way to do it. Can easily get to 
	// log time or thereabouts by doing one or two levels of 
	// subsidiary tables. Too many levels causes slow-down because
	// of overhead in managing the tree. 
	// Slepoy, Thompson and Plimpton 2008
	// report a linear time version.
	for ( vector< double >::iterator i = v_.begin(); i != v_.end(); ++i )
		if ( r < ( sum += *i ) )
			return static_cast< unsigned int >( i - v_.begin() );
	return v_.size();
}
// Static func
void GssaStoich::reinitFunc( const Conn* c )
{
	Stoich::reinitFunc( c );
	GssaStoich* s = static_cast< GssaStoich* >( c->data() );
	// Here we round off up or down with prob depending on fractional
	// part of the init value.
	for ( vector< double >::iterator i = s->S_.begin(); 
		i != s->S_.end(); ++i ) {
		double base = floor( *i );
		double frac = *i - base;
		if ( mtrand() > frac )
			*i = base;
		else
			*i = base + 1.0;
	}
	s->t_ = 0.0;
	s->updateAllRates();
}
void StochSpikeGen::innerProcessFunc(const Conn* conn, ProcInfo p)
{
    double t = p->currTime_;
    if ( V_ > threshold_ ) {
        if ((t + p->dt_/2.0) >= (lastEvent_ + refractT_)){
            if (!edgeTriggered_ || (edgeTriggered_ && !fired_)) {
                if (mtrand() > Pr_){
                    send1< double >( conn->target(), eventSlot, t );
                    lastEvent_ = t;
                    state_ = amplitude_;
                    fired_ = true;
                }
            } else {
                state_ = 0.0;                
            }
        }
    } else {
        state_ = 0.0;
        fired_ = false;
    }    
}
示例#23
0
// In this Update() function we need to update all of our characters. Move them around or whatever we want to do.
// http://www.youtube.com/watch?v=c4b9lCfSDQM
void CGame::Update(float dt)
{
	Vector x0 = m_hPlayer->GetGlobalOrigin();

	// The approach function http://www.youtube.com/watch?v=qJq7I2DLGzI
	m_hPlayer->m_vecMovement.x = Approach(m_hPlayer->m_vecMovementGoal.x, m_hPlayer->m_vecMovement.x, dt * 65);
	m_hPlayer->m_vecMovement.z = Approach(m_hPlayer->m_vecMovementGoal.z, m_hPlayer->m_vecMovement.z, dt * 65);

	Vector vecForward = m_hPlayer->GetGlobalView();
	vecForward.y = 0;
	vecForward.Normalize();

	Vector vecUp(0, 1, 0);

	// Cross product http://www.youtube.com/watch?v=FT7MShdqK6w
	Vector vecRight = vecUp.Cross(vecForward);

	float flSaveY = m_hPlayer->m_vecVelocity.y;
	m_hPlayer->m_vecVelocity = vecForward * m_hPlayer->m_vecMovement.x + vecRight * m_hPlayer->m_vecMovement.z;
	m_hPlayer->m_vecVelocity.y = flSaveY;

	// Update position and vecMovement. http://www.youtube.com/watch?v=c4b9lCfSDQM
	m_hPlayer->SetTranslation(m_hPlayer->GetGlobalOrigin() + m_hPlayer->m_vecVelocity * dt);
	m_hPlayer->m_vecVelocity = m_hPlayer->m_vecVelocity + m_hPlayer->m_vecGravity * dt;

	// Make sure the player doesn't fall through the floor. The y dimension is up/down, and the floor is at 0.
	Vector vecTranslation = m_hPlayer->GetGlobalOrigin();
	if (vecTranslation.y < 0)
		m_hPlayer->SetTranslation(Vector(vecTranslation.x, 0, vecTranslation.z));

	// Grab the player's translation and make a translation only matrix. http://www.youtube.com/watch?v=iCazI3nKBf0
	Vector vecPosition = m_hPlayer->GetGlobalOrigin();
	Matrix4x4 mPlayerTranslation;
	mPlayerTranslation.SetTranslation(vecPosition);

	// Create a set of basis vectors that do what we need.
	vecForward = m_hPlayer->GetGlobalView();
	vecForward.y = 0;       // Flatten the angles so that the box doesn't rotate up and down as the player does.
	vecForward.Normalize(); // Re-normalize, we need all of our basis vectors to be normal vectors (unit-length)
	vecUp = Vector(0, 1, 0);  // The global up vector
	vecRight = -vecUp.Cross(vecForward).Normalized(); // Cross-product: https://www.youtube.com/watch?v=FT7MShdqK6w

	// Use these basis vectors to make a matrix that will transform the player-box the way we want it.
	// http://youtu.be/8sqv11x10lc
	Matrix4x4 mPlayerRotation(vecForward, vecUp, vecRight);

	Matrix4x4 mPlayerScaling = Matrix4x4();

	// Produce a transformation matrix from our three TRS matrices.
	// Order matters! http://youtu.be/7pe1xYzFCvA
	m_hPlayer->SetGlobalTransform(mPlayerTranslation * mPlayerRotation * mPlayerScaling);

	Vector x1 = m_hPlayer->GetGlobalOrigin();
	float flPlayerDistanceTraveled = m_hPlayer->m_flDistanceTraveled;

	// Add the distance traveled this frame.
	flPlayerDistanceTraveled += (x1 - x0).Length();

	m_hPlayer->m_flDistanceTraveled = flPlayerDistanceTraveled;

	float flMonsterSpeed = 0.5f;
	for (size_t i = 0; i < MAX_CHARACTERS; i++)
	{
		CCharacter* pCharacter = GetCharacterIndex(i);
		if (!pCharacter)
			continue;

		if (!pCharacter->m_bEnemyAI)
			continue;

		// Update position and movement. http://www.youtube.com/watch?v=c4b9lCfSDQM
		pCharacter->m_vecVelocity = (m_hPlayer->GetGlobalOrigin() - pCharacter->GetGlobalOrigin()).Normalized() * flMonsterSpeed;

		pCharacter->SetTranslation(pCharacter->GetGlobalOrigin() + pCharacter->m_vecVelocity * dt);
	}

	if (Game()->GetTime() >= m_projectile_initial_time + 8)
	{
		m_projectile_position[0] = m_projectile_initial_position;
		m_projectile_velocity[0] = m_projectile_initial_velocity = Vector((float)(mtrand()%1000)/250-2, 2.5, (float)(mtrand()%1000)/250-2) * 5;
		m_projectile_initial_time = Game()->GetTime();
		m_projectile_break_time = Game()->GetTime() + PredictProjectileMaximumHeightTime(m_projectile_initial_velocity, m_projectile_gravity);
		m_projectile_number = 1;
	}

	if (Game()->GetTime() >= m_projectile_break_time && m_projectile_number == 1)
	{
		for (int i = 1; i < MAX_PROJECTILES; i++)
		{
			m_projectile_position[i] = m_projectile_position[0];
			m_projectile_velocity[i] = m_projectile_velocity[0] + Vector((float)(mtrand()%1000)/250-2, (float)(mtrand()%1000)/250-2, (float)(mtrand()%1000)/250-2);
		}
		m_projectile_number = MAX_PROJECTILES;
	}

	// Simulate the projectile
	for (int i = 0; i < m_projectile_number; i++)
	{
		m_projectile_position[i] = m_projectile_position[i] + m_projectile_velocity[i] * dt;
		m_projectile_velocity[i] = m_projectile_velocity[i] + m_projectile_gravity * dt;

		if (m_projectile_position[i].y < 0)
		{
			MakePuff(m_projectile_position[i]);
			m_projectile_position[i].y = 9999999; // Move it way up high and out of sight until it gets reset. Sort of a hack, no big deal.
		}
	}
}
示例#24
0
void CGameServer::GenerateSaveCRC(size_t iInput)
{
	mtsrand(m_iSaveCRC^iInput);
	m_iSaveCRC = mtrand();
}
示例#25
0
GAindividual crossoverEnzymeNetwork(GAindividual individualA, GAindividual individualB)  //crossover between complexes in two networks
{
	int i,j, n;
	EnzymeNetwork * net1, * net2, * net3;
	
	if (mtrand() > CROSSOVER_PROB) return mutateEnzymeNetwork(cloneEnzymeNetwork(individualA));
	
	if (!individualA) return mutateEnzymeNetwork(cloneEnzymeNetwork(individualB));
	if (!individualB) return mutateEnzymeNetwork(cloneEnzymeNetwork(individualA));
	
	net1 = (EnzymeNetwork*)(individualA);  //parents
	net2 = (EnzymeNetwork*)(individualB);
	
	if (net1->massActionNetwork->reactions < 3) return mutateEnzymeNetwork(cloneEnzymeNetwork(net2));  //if parents are too small
	if (net2->massActionNetwork->reactions < 3) return mutateEnzymeNetwork(cloneEnzymeNetwork(net1));
	
	net3 =  (EnzymeNetwork*) malloc (sizeof(EnzymeNetwork));

	net3->massActionNetwork = crossoverMassActionNetwork(net1->massActionNetwork,net2->massActionNetwork);

	n = net3->massActionNetwork->reactions;

	net3->enzymes = (int*)malloc(n * sizeof(int));
	net3->Keq = (double*)malloc(n * sizeof(double));
	net3->h = (double*)malloc(n * sizeof(double));
	net3->alpha = (double*)malloc(n * sizeof(double));
	net3->P_half = (double*)malloc(n * sizeof(double));
	net3->S_half = (double*)malloc(n * sizeof(double));

	//get some set of enzymes from one parent and some from the other

	for (i=0; i < n; ++i)
	{
		net3->enzymes[i] = (int)(mtrand() * net3->massActionNetwork->species);
		net3->Keq[i] = mtrand() * pow(2, (KEQ_LN_MIN + (KEQ_LN_MAX - KEQ_LN_MIN) * mtrand()));
		net3->h[i] = H_MIN + (H_MAX - H_MIN) * mtrand();
		net3->alpha[i] = mtrand() * pow(2, (ALPHA_LN_MIN + (ALPHA_LN_MAX - ALPHA_LN_MIN) * mtrand()));
		net3->S_half[i] = S_HALF_MIN + (S_HALF_MAX - S_HALF_MIN) * mtrand();
		net3->P_half[i] = P_HALF_MIN + (P_HALF_MAX - P_HALF_MIN) * mtrand();
	}

	j = (int)(mtrand() * net3->massActionNetwork->reactions);
	for (i=0; i < j && i < net1->massActionNetwork->reactions && i < net3->massActionNetwork->reactions; ++i)
	{
		net3->enzymes[i] = net1->enzymes[i];
		net3->Keq[i] = net1->Keq[i];
		net3->h[i] = net1->h[i];
		net3->alpha[i] = net1->alpha[i];
		net3->S_half[i] = net1->S_half[i];
		net3->P_half[i] = net1->P_half[i];

		if (net3->enzymes[i] >= net3->massActionNetwork->species)
			net3->enzymes[i] = (int)(mtrand() * net3->massActionNetwork->species);
	}
	for (i=0; (i+j) < net3->massActionNetwork->reactions && i < net2->massActionNetwork->reactions; ++i)
	{
		net3->enzymes[i+j] = net2->enzymes[i];
		net3->Keq[i+j] = net2->Keq[i];
		net3->h[i+j] = net2->h[i];
		net3->alpha[i+j] = net2->alpha[i];
		net3->S_half[i+j] = net2->S_half[i];
		net3->P_half[i+j] = net2->P_half[i];
		if (net3->enzymes[i+j] >= net3->massActionNetwork->species)
			net3->enzymes[i+j] = (int)(mtrand() * net3->massActionNetwork->species);
	}
	return (GAindividual)(net3);
}
示例#26
0
GApopulation randomNetworks(int sz0)
{
	int i, j, r, k, n, total = 0;
	ReactionNetwork * rnet;
	GApopulation P0 = 0, P;

	P = (GAindividual*) malloc( sz0 * sizeof (GAindividual) );

	r = (int)(networkProbs[MASS_ACTION_NETWORK] * sz0);

	if (r > 0 && r <= sz0)
	{
		P0 = randomMassActionNetworks(r);
		for (i=0; i < r; ++i)
		{
			rnet = (ReactionNetwork*) malloc(sizeof(ReactionNetwork));
			rnet->type = MASS_ACTION_NETWORK;
			rnet->network = P0[i];
			//rnet->id = i+total;
			//rnet->parents = 0;
			n = getNumSpecies(rnet);
			rnet->initialValues = (double*)malloc(n*sizeof(double));
			rnet->fixed = (int*)malloc(n*sizeof(double));
			for (j=0; j < n; ++j)
			{
				rnet->initialValues[j] = AVG_INIT_VALUES * mtrand();
				rnet->fixed[j] = 0;
			}

			P[total+i] = rnet;
		}
		total += r;
	}

	r = (int)(networkProbs[ENZYME_NETWORK] * sz0);

	if (r > 0 && r <= sz0)
	{
		P0 = randomEnzymeNetworks(r);
		for (i=0; i < r; ++i)
		{
			rnet = (ReactionNetwork*) malloc(sizeof(ReactionNetwork));
			rnet->type = ENZYME_NETWORK;
			rnet->network = P0[i];
			//rnet->id = i+total;
			//rnet->parents = 0;
			n = getNumSpecies(rnet);
			rnet->initialValues = (double*)malloc(n*sizeof(double));
			rnet->fixed = (int*)malloc(n*sizeof(double));
			for (j=0; j < n; ++j)
			{
				rnet->initialValues[j] = AVG_INIT_VALUES * mtrand();
				rnet->fixed[j] = 0;
			}

			P[total+i] = rnet;
		}
		total += r;
	}

	r = (int)(networkProbs[GENE_REGULATION_NETWORK] * sz0);
	if (r > 0 && r <= sz0)
	{
		P0 = randomGeneRegulationNetworks(r);
		for (i=0; i < r; ++i)
		{
			rnet = (ReactionNetwork*) malloc(sizeof(ReactionNetwork));
			rnet->type = GENE_REGULATION_NETWORK;
			rnet->network = P0[i];
			//rnet->parents = 0;
			n = getNumSpecies(rnet);
			rnet->initialValues = (double*)malloc(n*sizeof(double));
			rnet->fixed = (int*)malloc(n*sizeof(double));
			for (j=0; j < n; ++j)
			{
				rnet->initialValues[j] = AVG_INIT_VALUES * mtrand();
				rnet->fixed[j] = 0;
			}

			//rnet->id = i+total;
			P[total+i] = rnet;
		}
		total += r;
	}

	if (total < sz0)
	{
		k = sz0 - total;
		P0 = randomProteinInteractionNetworks(k);
		for (i=0; i < k; ++i)
		{
			rnet = (ReactionNetwork*) malloc(sizeof(ReactionNetwork));
			rnet->type = PROTEIN_INTERACTION_NETWORK;
			rnet->network = P0[i];
			//rnet->parents = 0;
			n = getNumSpecies(rnet);
			rnet->initialValues = (double*)malloc(n*sizeof(double));
			rnet->fixed = (int*)malloc(n*sizeof(double));
			for (j=0; j < n; ++j)
			{
				rnet->initialValues[j] = AVG_INIT_VALUES * mtrand();
				rnet->fixed[j] = 0;
			}

			//rnet->id = i+total;
			P[i+total] = rnet;
		}
	}

	return P;
}
示例#27
0
GAindividual mutateEnzymeNetwork(GAindividual individual)
{
	int i,j,n;
	double r;
	EnzymeNetwork * net, *net2;
	MassActionNetwork * mnet;

	if (!individual) 
		return individual;
	
	net = (EnzymeNetwork*)individual;
	mnet = net->massActionNetwork;

	if (!mnet) 
		return individual;
	
	r = mtrand();

	n = 0;

	for (i=0; i < mnet->reactions; ++i)
	{
		if (((mnet->reactant1[i] == -1 && mnet->reactant2[i] > -1) ||  //uni-uni
			 (mnet->reactant1[i] > -1 && mnet->reactant2[i] == -1))
			&&
			((mnet->product1[i] == -1 && mnet->product2[i] > -1) ||
			 (mnet->product1[i] > -1 && mnet->product2[i] == -1))
			)
			++n;
	}

	if (n > 0)
	{
		j = (int)(mtrand() * n);

		for (i=0; i < mnet->reactions; ++i)
		{
			if (((mnet->reactant1[i] == -1 && mnet->reactant2[i] > -1) ||  //uni-uni
				 (mnet->reactant1[i] > -1 && mnet->reactant2[i] == -1))
				&&
				((mnet->product1[i] == -1 && mnet->product2[i] > -1) ||
				 (mnet->product1[i] > -1 && mnet->product2[i] == -1))
				)
				--j;
			if (j < 0)
				break;
		}

		if (i >= mnet->reactions)
			return individual;

		//i = (int)(mtrand() * mnet->reactions);

		if (r < MUTATE_KEQ_PROB) //mutate km
		{
			net->Keq[i] *= 2.0 * mtrand();
			if (net->Keq[i] > pow(2,KEQ_LN_MAX) || net->Keq[i] < pow(2,KEQ_LN_MIN))
			{
				net->Keq[i] = mtrand() * pow(2,KEQ_LN_MIN + (KEQ_LN_MAX - KEQ_LN_MIN) * mtrand());
			}
			return (GAindividual)(net);
		}
		if (r < (MUTATE_KEQ_PROB+MUTATE_S_HALF_PROB))   //mutate s_half
		{
			net->S_half[i] *= 2.0 * mtrand();
			if (net->S_half[i] > S_HALF_MAX || net->S_half[i] < S_HALF_MIN)
			{
				net->S_half[i] = S_HALF_MIN + (S_HALF_MAX - S_HALF_MIN) * mtrand();
			}
			return (GAindividual)(net);
		}
		if (r < (MUTATE_KEQ_PROB+MUTATE_S_HALF_PROB+MUTATE_P_HALF_PROB))   //mutate s_half
		{
			net->P_half[i] *= 2.0 * mtrand();
			if (net->P_half[i] > P_HALF_MAX || net->P_half[i] < P_HALF_MIN)
			{
				net->P_half[i] = P_HALF_MIN + (P_HALF_MAX - P_HALF_MIN) * mtrand();
			}
			return (GAindividual)(net);
		}
		if (r < (MUTATE_KEQ_PROB+MUTATE_S_HALF_PROB+MUTATE_P_HALF_PROB+MUTATE_ENZYME_PROB))   //mutate enzyme
		{
			net->enzymes[i] = (int)(mtrand() * net->massActionNetwork->species);
			return (GAindividual)(net);
		}
		if (r < (MUTATE_KEQ_PROB+MUTATE_S_HALF_PROB+MUTATE_P_HALF_PROB+MUTATE_ENZYME_PROB+MUTATE_H_PROB))   //mutate h
		{
			net->h[i] *= 2.0 * mtrand();
			if (net->h[i] > H_MAX || net->h[i] < H_MAX)
			{
				net->h[i] = H_MIN + (H_MAX - H_MIN) * mtrand();
			}
			return (GAindividual)(net);
		}
		if (r < (MUTATE_H_PROB+MUTATE_KEQ_PROB+MUTATE_S_HALF_PROB+MUTATE_P_HALF_PROB+MUTATE_ENZYME_PROB+MUTATE_ALPHA_PROB)) //mutate alpha
		{
			net->alpha[i] *= 2.0 * mtrand();
			if (net->alpha[i] > pow(2,ALPHA_LN_MAX) || net->alpha[i] < pow(2,ALPHA_LN_MIN))
			{
				net->alpha[i] = mtrand() * pow(2, ALPHA_LN_MIN + (ALPHA_LN_MAX - ALPHA_LN_MIN) *mtrand());
			}
			return (GAindividual)(net);
		}
	}
	
	n = net->massActionNetwork->reactions;

	mnet = (MassActionNetwork*)mutateMassActionNetwork(net->massActionNetwork);
	
	if (n == mnet->reactions)
	{
		net->massActionNetwork = mnet;
		net2 = net;
	}
	else
	{
		net->massActionNetwork = 0;

		net2 = (EnzymeNetwork*)malloc(sizeof(EnzymeNetwork));

		net2->massActionNetwork = mnet;
		net2->enzymes = (int*)malloc(mnet->reactions * sizeof(int));
		net2->Keq = (double*)malloc(mnet->reactions * sizeof(double));
		net2->h = (double*)malloc(mnet->reactions * sizeof(double));
		net2->alpha = (double*)malloc(mnet->reactions * sizeof(double));
		net2->P_half = (double*)malloc(mnet->reactions * sizeof(double));
		net2->S_half = (double*)malloc(mnet->reactions * sizeof(double));

		for (i=0; i < mnet->reactions; ++i)
		{
			net2->enzymes[i] = (int)(mtrand() * mnet->species);
			net2->Keq[i] = mtrand() * pow(2, (KEQ_LN_MIN + (KEQ_LN_MAX - KEQ_LN_MIN) * mtrand()));
			net2->h[i] = H_MIN + (H_MAX - H_MIN) * mtrand();
			net2->alpha[i] = mtrand() * pow(2, (ALPHA_LN_MIN + (ALPHA_LN_MAX - ALPHA_LN_MIN) * mtrand()));
			net2->P_half[i] = mtrand() * (P_HALF_MAX - P_HALF_MIN) + P_HALF_MIN;
			net2->S_half[i] = mtrand() * (S_HALF_MAX - S_HALF_MIN) + S_HALF_MIN;
		}

		for (i=0; i < n && i < mnet->reactions; ++i)
		{
			net2->enzymes[i] = net->enzymes[i];
			net2->Keq[i] = net->Keq[i];
			net2->h[i] = net->h[i];
			net2->alpha[i] = net->alpha[i];
			net2->P_half[i] = net->P_half[i];
			net2->S_half[i] = net->S_half[i];
		}

		deleteEnzymeNetwork(net);
	}

	return (GAindividual)(net2);
}
示例#28
0
CGameServer::CGameServer(IWorkListener* pWorkListener)
{
	TAssert(!s_pGameServer);
	s_pGameServer = this;

	m_bAllowPrecaches = false;

	GameNetwork()->SetCallbacks(this, CGameServer::ClientConnectCallback, CGameServer::ClientEnterGameCallback, CGameServer::ClientDisconnectCallback);

	m_pWorkListener = pWorkListener;

	m_iMaxEnts = g_cfgEngine.read("MaxEnts", 1024);

	CBaseEntity::s_apEntityList.resize(m_iMaxEnts);

	m_pCameraManager = NULL;

	m_iSaveCRC = 0;

	m_bLoading = true;
	m_bRestartLevel = false;

	m_flHostTime = 0;
	m_flGameTime = 0;
	m_flFrameTime = 0;
	m_flTimeScale = 1;
	m_flNextClientInfoUpdate = 0;
	m_iFrame = 0;

	size_t iPostSeed = mtrand();

	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	TMsg("Creating physics model... ");
	GamePhysics();	// Just make sure it exists.
	TMsg("Done.\n");

	TMsg("Registering entities... ");

	if (m_pWorkListener)
		m_pWorkListener->SetAction("Registering entities", CBaseEntity::GetEntityRegistration().size());

	tmap<tstring, bool> abRegistered;

	for (tmap<tstring, CEntityRegistration>::iterator it = CBaseEntity::GetEntityRegistration().begin(); it != CBaseEntity::GetEntityRegistration().end(); it++)
		abRegistered[it->first] = false;

	tvector<tstring> asRegisterStack;

	size_t i = 0;
	for (tmap<tstring, CEntityRegistration>::iterator it = CBaseEntity::GetEntityRegistration().begin(); it != CBaseEntity::GetEntityRegistration().end(); it++)
	{
		CEntityRegistration* pRegistration = &it->second;

		if (abRegistered[it->first])
			continue;

		asRegisterStack.clear();
		asRegisterStack.push_back(it->first);

		// Make sure I register all parent classes before I register this one.
		if (pRegistration->m_pszParentClass)
		{
			tstring sThisClass = it->first;
			tstring sParentClass = pRegistration->m_pszParentClass;
			while (!abRegistered[sParentClass])
			{
				// Push to the top, we'll register from the top first.
				asRegisterStack.push_back(sParentClass);

				CEntityRegistration* pRegistration = &CBaseEntity::GetEntityRegistration()[sParentClass];

				sThisClass = sParentClass;
				sParentClass = pRegistration->m_pszParentClass?pRegistration->m_pszParentClass:"";

				if (!sParentClass.length())
					break;
			}
		}

		// The top of the stack is the highest entity on the tree that I must register first.
		while (asRegisterStack.size())
		{
			CBaseEntity::GetEntityRegistration()[asRegisterStack.back()].m_pfnRegisterCallback();
			abRegistered[asRegisterStack.back()] = true;
			asRegisterStack.pop_back();
		}

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(++i);
	}
	TMsg("Done.\n");

	mtsrand(iPostSeed);

	CBaseEntity::s_iNextEntityListIndex = 0;

	m_iPort = 0;
	m_iClient = NETWORK_LOCAL;

	m_bHalting = false;

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
示例#29
0
// The Game Loop http://www.youtube.com/watch?v=c4b9lCfSDQM
void CGame::GameLoop()
{
	m_hPlayer = CreateCharacter();

	// Initialize the box's position etc
	m_hPlayer->SetGlobalOrigin(Point(0, 0, 0));
	m_hPlayer->m_vecMovement = Vector(0, 0, 0);
	m_hPlayer->m_vecMovementGoal = Vector(0, 0, 0);
	m_hPlayer->m_vecVelocity = Vector(0, 0, 0);
	m_hPlayer->m_vecGravity = Vector(0, -10, 0);
	m_hPlayer->m_flSpeed = 15;
	m_hPlayer->m_clrRender = Color(0.8f, 0.4f, 0.2f, 1.0f);
	m_hPlayer->m_bHitByTraces = false;
	m_hPlayer->m_aabbSize = AABB(-Vector(0.5f, 0, 0.5f), Vector(0.5f, 2, 0.5f));
	m_hPlayer->m_bTakesDamage = true;

	Vector vecMonsterMin = Vector(-1, 0, -1);
	Vector vecMonsterMax = Vector(1, 2, 1);

	/*CCharacter* pTarget1 = CreateCharacter();
	pTarget1->SetTransform(Vector(2, 2, 2), 0, Vector(0, 1, 0), Vector(6, 0, 6));
	pTarget1->m_aabbSize.vecMin = vecMonsterMin;
	pTarget1->m_aabbSize.vecMax = vecMonsterMax;
	pTarget1->m_iBillboardTexture = m_iMonsterTexture;
	pTarget1->m_bEnemyAI = true;
	pTarget1->m_bTakesDamage = true;

	CCharacter* pTarget2 = CreateCharacter();
	pTarget2->SetTransform(Vector(2, 2, 2), 0, Vector(0, 1, 0), Vector(6, 0, -6));
	pTarget2->m_aabbSize.vecMin = vecMonsterMin;
	pTarget2->m_aabbSize.vecMax = vecMonsterMax;
	pTarget2->m_iBillboardTexture = m_iMonsterTexture;
	pTarget2->m_bEnemyAI = true;
	pTarget2->m_bTakesDamage = true;

	CCharacter* pTarget3 = CreateCharacter();
	pTarget3->SetTransform(Vector(3, 3, 3), 0, Vector(0, 1, 0), Vector(-6, 0, 8));
	pTarget3->m_aabbSize.vecMin = vecMonsterMin;
	pTarget3->m_aabbSize.vecMax = vecMonsterMax;
	pTarget3->m_iBillboardTexture = m_iMonsterTexture;
	pTarget3->m_bEnemyAI = true;
	pTarget3->m_bTakesDamage = true;*/

	Vector vecPropMin = Vector(-.1f, 0, -.1f);
	Vector vecPropMax = Vector(.1f, .2f, .1f);

	mtsrand(0);

	for (int i = 0; i < 800; i++)
	{
		float rand1 = (float)(mtrand()%1000)/1000; // [0, 1]
		float rand2 = (float)(mtrand()%1000)/1000; // [0, 1]

		float theta = rand1 * 2.0f * (float)M_PI;
		float radius = sqrt(rand2);

		Vector position = Vector(radius * cos(theta), 0, radius * sin(theta));
		position = position * 50;

		CCharacter* pProp = CreateCharacter();
		pProp->SetTransform(Vector(1, 1, 1), 0, Vector(0, 1, 0), position);
		pProp->m_aabbSize.vecMin = vecPropMin;
		pProp->m_aabbSize.vecMax = vecPropMax;
		pProp->m_clrRender = Color(0.4f, 0.8f, 0.2f, 1.0f);
		pProp->m_iTexture = m_iCrateTexture;
	}

	CRenderingContext c(GetRenderer());
	c.RenderBox(Vector(-1, 0, -1), Vector(1, 2, 1));
	c.CreateVBO(m_iMeshVB, m_iMeshSize);

	float flPreviousTime = 0;
	float flCurrentTime = Application()->GetTime();

	while (true)
	{
		// flCurrentTime will be lying around from last frame. It's now the previous time.
		flPreviousTime = flCurrentTime;
		flCurrentTime = Application()->GetTime();

		float dt = flCurrentTime - flPreviousTime;

		// Keep dt from growing too large.
		if (dt > 0.15f)
			dt = 0.15f;

		Update(dt);

		Draw();
	}
}
示例#30
0
GAindividual crossoverNetwork(GAindividual p1, GAindividual p2)
{
	ReactionNetwork * r1 = (ReactionNetwork*)(p1);
	ReactionNetwork * r2 = (ReactionNetwork*)(p2);
	GACrossoverFnc f;
	GAindividual net;
	ReactionNetwork * r;
	int i,j,sz1,sz2;

	if (mtrand() > CROSSOVER_PROB || r1->type != r2->type || r2->type < 0 || r2->type >= NUMBER_OF_NETWORK_TYPES)
		return mutateNetwork(p1);

	f = crossoverFunctions[r2->type];

	if (f)
	{
		net = f(r1->network,r2->network);
		r = (ReactionNetwork*)malloc(sizeof(ReactionNetwork));
		r->type = r1->type;
		r->network = net;
		//r->id = r1->id;

		sz1 = getNumSpecies(r1);
		sz2 = getNumSpecies(r2);
		j = getNumSpecies(r);

		r->initialValues = (double*)malloc(j * sizeof(double));
		r->fixed = (int*)malloc(j * sizeof(double));

		for (i=0; i < sz1 && i < j; ++i)
		{
			r->initialValues[i] = r1->initialValues[i];
			r->fixed[i] = r1->fixed[i];
		}
		for (i=0; i < sz2 && (sz1+i) < j; ++i)
		{
			r->initialValues[sz1+i] = r2->initialValues[i];
			r->fixed[sz1+i] = r2->fixed[i];
		}
		for (i=sz1+sz2; i < j; ++i)
		{
			r->initialValues[i] = AVG_INIT_VALUES * mtrand();
			r->fixed[i] = 0;
		}

		/*
		i = j = sz1 = sz2 = 0;
		if (r1->parents)
		{
			while (r1->parents[i])
			{
				++i;
			}
		}

		j = 0;
		if (r2->parents)
		{
			while (r2->parents[j])
			{
				++j;
			}
		}

		sz1 = i + j;

		r->parents = 0;
		if (TRACK_NETWORK_PARENTS)
		{
			if (sz1 > 0)
			{
				p = (int*)malloc(sz1 * sizeof(int));

				for (k=0; k < i; ++k)
					p[k] = r1->parents[k];

				for (k=0; k < j; ++k)
					p[k+i] = r2->parents[k];

				sz2 = 0;

				for (i=0; i < sz1; ++i)
				{
					for (j=0; j < i; ++j)
						if (p[j] == p[i]) break;
					if (i == j)
						++sz2;
				}

				r->parents = (int*) malloc((sz2+1)*sizeof(int));
				r->parents[sz2] = 0;

				k = 0;
				for (i=0; i < sz1; ++i)
				{
					for (j=0; j < i; ++j)
						if (p[j] == p[i]) break;
					if (i == j)
					{
						r->parents[k] = p[i];
						++k;
					}
				}
				free(p);
			}
			else
			{
				r->parents = (int*) malloc((3)*sizeof(int));
				r->parents[2] = 0;

				r->parents[0] = r1->id;
				r->parents[1] = r2->id;
			}
		}
		*/
		return r;
	}

	return mutateNetwork(p1);
}