void drawTree(double x, double y, double r, double theta, int depth) { if (depth < MAX_DEPTH) { double growth = randomReal(0.1, 0.4); setColor(TREE_COLORS[depth]); GPoint branchPt = drawPolarLine(x, y, r * growth, theta); int numChildren = randomInteger(2, 8); for (int i = 0; i < numChildren; i++) { double thetaPrime = theta + randomReal(-45, +45); drawTree(branchPt.getX(), branchPt.getY(), (1.0 - growth) * r, thetaPrime, depth + 1); } } }
LearningProblemState* QLearner::doLearningIteration(LearningProblemState * state) { // Pick a new state once in a while if (randomReal() < nu) { state = problem->getRandomState(); } // Get the list of actions LearningProblemAction* actions = problem->getActions(state); LearningProblemAction* action = NULL; // Check if we should use a random action, or the best one if (randomReal() < rho) { unsigned randPos = randomInt(actions->getCount()); action = actions->getAtPositionInList(randPos); } else { action = getBestAction(state); } // Make sure we've got something to do if (action != NULL) { // Carry out the action LearningProblemActionResult result = problem->getResult(state, action); // Get the current q value real q = getQValue(state, action); // Get the q of the best action from the new state real maxQ = getBestQValue(result.state); // recalculate the q q = ((real)1.0-alpha) * q + alpha * (result.reward + gamma * maxQ); // Store the new Q value storeQValue(state, action, q); return result.state; } // Otherwise we need to get a new state - we've reached the // end of the road. else { return problem->getRandomState(); } }
SDL_Texture* TileManager::getVert(int left, int right, SDL_Renderer *renderer) { if (left < 0 || left >= vert.size() || right < 0 || right >= vert.size()) log(1, "ERROR VERT %d %d",left,right); if (left == right) return tiles[left].tex; // same texture if (vert[left][right] == NULL) { // merged texture SDL_Surface *tmp; Uint8 *l, *r; l = (Uint8 *)tiles[left].sur->pixels; r = (Uint8 *)tiles[right].sur->pixels; int width = 128; int height = 128; tmp = SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); Uint32 *pixels = (Uint32 *)tmp->pixels; for (int x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { // use random with chances equaling the cube of the distance double rnd = randomReal(0, 1); double p1, p2; p1 = 1.0 / ((128 - x)*(128 - x)*(128 - x)); p2 = 1.0 / ((x + 1)*(x + 1)*(x + 1)); if (p1 / (p1 + p2) <= rnd) pixels[(y * tmp->w) + x] = 0xff000000 | l[3 * ((y * tmp->w) + x)] | l[3 * ((y * tmp->w) + x) + 1] << 8 | l[3 * ((y * tmp->w) + x) + 2] << 16; else pixels[(y * tmp->w) + x] = 0xff000000 | r[3 * ((y * tmp->w) + x)] | r[3 * ((y * tmp->w) + x) + 1] << 8 | r[3 * ((y * tmp->w) + x) + 2] << 16; } } SDL_Texture *tmptex = SDL_CreateTextureFromSurface(renderer, tmp); SDL_FreeSurface(tmp); vert[left][right] = tmptex; } return vert[left][right]; }
void GeneticPopulation::crossover( const Weights& parent1, const Weights& parent2, Weights& child1, Weights& child2) const { assert(parent1.size() == parent2.size()); if (randomReal(0, 1) > crossoverRate || parent1 == parent2) { child1 = parent1; child2 = parent2; return; } unsigned crossoverPoint = static_cast<unsigned>(randomInt(0, parent1.size())); child1.clear(); child2.clear(); //create the offspring for (unsigned i = 0; i < crossoverPoint; ++i) { child1.push_back(parent1[i]); child2.push_back(parent2[i]); } for (unsigned i = crossoverPoint; i < parent1.size(); ++i) { child1.push_back(parent2[i]); child2.push_back(parent1[i]); } }
static bool randomRealSeemsReasonable(double low, double high) { int i, counts[N_RANGES]; double d, range, expected; bool ok; range = high - low; for (i = 0; i < N_RANGES; i++) { counts[i] = 0; } ok = true; for (i = 0; ok && i < N_TRIALS; i++) { d = randomReal(low, high); if (d < low || d >= high) { reportError("RandomReal returned out of range value %g", d); ok = false; } else { counts[(int)(N_RANGES * (d - low) / range)]++; } } expected = (double) N_TRIALS / N_RANGES; for (i = 0; ok && i < N_RANGES; i++) { if (counts[i] < 0.5 * expected) { reportError("Low count for outcome %d", i); ok = false; } else if (counts[i] > 1.5 * expected) { reportError("High count for outcome %d", i); ok = false; } } return ok; }
SDL_Texture* TileManager::getHori(int top, int bot, SDL_Renderer *renderer) { if (top < 0 || top >= vert.size() || bot < 0 || bot >= vert.size()) log(1, "ERROR HORI %d %d",top,bot); if (top == bot) return tiles[top].tex; if (hori[top][bot] == NULL) { SDL_Surface *tmp; Uint8 *l, *r; l = (Uint8 *)tiles[top].sur->pixels; r = (Uint8 *)tiles[bot].sur->pixels; int width = 128; int height = 128; tmp = SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); Uint32 *pixels = (Uint32 *)tmp->pixels; for (int x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { // use random with chances equaling the cube of the distance double rnd = randomReal(0, 1); double p1, p2; p1 = 1.0 / ((128 - y)*(128 - y)*(128 - y)); p2 = 1.0 / ((y + 1)*(y + 1)*(y + 1)); if (p1/(p1+p2)<=rnd) pixels[(y * tmp->w) + x] = 0xff000000 | l[3 * ((y * tmp->w) + x)] | l[3 * ((y * tmp->w) + x) + 1] << 8 | l[3 * ((y * tmp->w) + x) + 2] << 16; else pixels[(y * tmp->w) + x] = 0xff000000 | r[3 * ((y * tmp->w) + x)] | r[3 * ((y * tmp->w) + x) + 1] << 8 | r[3 * ((y * tmp->w) + x) + 2] << 16; } } SDL_Texture *tmptex = SDL_CreateTextureFromSurface(renderer, tmp); SDL_FreeSurface(tmp); hori[top][bot] = tmptex; } return hori[top][bot]; }
int Box::changeMolecule(int molIdx) { Real maxTranslation = environment->maxTranslation; Real maxRotation = environment->maxRotation; saveChangedMol(molIdx); //Pick an atom in the molecule about which to rotate int atomIndex = randomReal(0, molecules[molIdx].numOfAtoms); Atom vertex = molecules[molIdx].atoms[atomIndex]; const Real deltaX = randomReal(-maxTranslation, maxTranslation); const Real deltaY = randomReal(-maxTranslation, maxTranslation); const Real deltaZ = randomReal(-maxTranslation, maxTranslation); const Real degreesX = randomReal(-maxRotation, maxRotation); const Real degreesY = randomReal(-maxRotation, maxRotation); const Real degreesZ = randomReal(-maxRotation, maxRotation); moveMolecule(molecules[molIdx], vertex, deltaX, deltaY, deltaZ, degreesX, degreesY, degreesZ); keepMoleculeInBox(molIdx); return molIdx; }
GeneticPopulation::GeneticPopulation(unsigned populationSize, unsigned numberOfWeights) { for (unsigned i = 0; i < populationSize; ++i) { Weights weights(numberOfWeights); for (Weight& weight : weights) { weight = randomReal(-1, 1); } population.push_back(Genome(weights)); } }
bool SimCalcs::acceptMove(Real oldEnergy, Real newEnergy) { // Always accept decrease in energy if (newEnergy < oldEnergy) { return true; } // Otherwise use random number to determine weather to accept return exp(-(newEnergy - oldEnergy) / sb->kT) >= randomReal(0.0, 1.0); }
Genome GeneticPopulation::pickRoulette() const { float slice = randomReal(0, totalFitness); float fitnessSoFar = 0; for (const Genome& genome : population) { fitnessSoFar += genome.fitness; if (genome.fitness >= slice) { return genome; } } //we shouldn't ever get here (only if rounding error occurs) return population.back(); }
SDL_Texture* TileManager::getAll(int id0, int id1, int id2, int id3, SDL_Renderer *renderer) { if (id0 < 0 || id0 >= vert.size() || id1 < 0 || id1 >= vert.size() || id2 < 0 || id2 >= vert.size() || id3 < 0 || id3 >= vert.size()) log(1, "ERROR HORI %d %d %d %d", id0,id1,id2,id3); if (id0==id1 && id1==id2 && id2==id3) return tiles[id0].tex; if (all[id0][id1][id2][id3] == NULL) { SDL_Surface *tmp; Uint8 *l, *r, *t, *b; t = (Uint8 *)tiles[id0].sur->pixels; r = (Uint8 *)tiles[id1].sur->pixels; b = (Uint8 *)tiles[id2].sur->pixels; l = (Uint8 *)tiles[id3].sur->pixels; int width = 128; int height = 128; tmp = SDL_CreateRGBSurface(0, width, height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); Uint32 *pixels = (Uint32 *)tmp->pixels; for (int x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { // use random with chances equaling the cube of the distance double rnd = randomReal(0, 1); double p1, p2; p1 = 1.0 / ((128 - y)*(128 - y)*(128 - y)); p2 = 1.0 / ((y + 1)*(y + 1)*(y + 1)); if (p1 / (p1 + p2) <= rnd) { p1 = 1.0 / ((128 - x)*(128 - x)*(128 - x)); p2 = 1.0 / ((x + 1)*(x + 1)*(x + 1)); if (p1 / (p1 + p2) <= rnd) { pixels[(y * tmp->w) + x] = 0xff000000 | t[3 * ((y * tmp->w) + x)] | t[3 * ((y * tmp->w) + x) + 1] << 8 | t[3 * ((y * tmp->w) + x) + 2] << 16; } else { pixels[(y * tmp->w) + x] = 0xff000000 | r[3 * ((y * tmp->w) + x)] | r[3 * ((y * tmp->w) + x) + 1] << 8 | r[3 * ((y * tmp->w) + x) + 2] << 16; } } else { p1 = 1.0 / ((128 - x)*(128 - x)*(128 - x)); p2 = 1.0 / ((x + 1)*(x + 1)*(x + 1)); if (p1 / (p1 + p2) <= rnd) { pixels[(y * tmp->w) + x] = 0xff000000 | l[3 * ((y * tmp->w) + x)] | l[3 * ((y * tmp->w) + x) + 1] << 8 | l[3 * ((y * tmp->w) + x) + 2] << 16; } else { pixels[(y * tmp->w) + x] = 0xff000000 | b[3 * ((y * tmp->w) + x)] | b[3 * ((y * tmp->w) + x) + 1] << 8 | b[3 * ((y * tmp->w) + x) + 2] << 16; } } } } SDL_Texture *tmptex = SDL_CreateTextureFromSurface(renderer, tmp); SDL_FreeSurface(tmp); all[id0][id1][id2][id3] = tmptex; } return all[id0][id1][id2][id3]; }
void SimCalcs::intermolecularMove(int molIdx) { Real maxT = sb->maxTranslate; Real maxR = sb->maxRotate; int molStart = sb->moleculeData[MOL_START][molIdx]; int molLen = sb->moleculeData[MOL_LEN][molIdx]; int vertexIdx = (int)randomReal(0, molLen); const Real deltaX = randomReal(-maxT, maxT); const Real deltaY = randomReal(-maxT, maxT); const Real deltaZ = randomReal(-maxT, maxT); const Real rotX = randomReal(-maxR, maxR); const Real rotY = randomReal(-maxR, maxR); const Real rotZ = randomReal(-maxR, maxR); Real** rBCoords = GPUCopy::rollBackCoordinatesPtr(); Real** aCoords = GPUCopy::atomCoordinatesPtr(); Real* bSize = GPUCopy::sizePtr(); int* pIdxes = GPUCopy::primaryIndexesPtr(); int** molData = GPUCopy::moleculeDataPtr(); // Do the move here #pragma acc parallel loop deviceptr(aCoords, rBCoords) \ if (on_gpu) for (int i = 0; i < molLen; i++) { for (int j = 0; j < NUM_DIMENSIONS; j++) { rBCoords[j][i] = aCoords[j][molStart + i]; } if (i == vertexIdx) continue; rotateAtom(molStart + i, molStart + vertexIdx, rotX, rotY, rotZ, aCoords); translateAtom(molStart + i, deltaX, deltaY, deltaZ, aCoords); } #pragma acc parallel loop deviceptr(aCoords, molData, pIdxes, bSize) \ if (on_gpu) for (int i = 0; i < 1; i++) { aCoords[0][molStart + vertexIdx] += deltaX; aCoords[1][molStart + vertexIdx] += deltaY; aCoords[2][molStart + vertexIdx] += deltaZ; keepMoleculeInBox(molIdx, aCoords, molData, pIdxes, bSize); } }
real randomBinomial(real max) { return randomReal(max)-randomReal(max); }
int Box::chooseMolecule() { return (int) randomReal(0, environment->numOfMolecules); }
void ParticleEmitter::spawn(float delta, const AnimationTime& at, ParticleList& ps, const Matrix& m) { if (!mVisibility.getFrame(at.current)) { return; } //换算成秒 float timeFactor = delta / 1000.0f; mCurrentEmission += mEmitRate.getFrame(at) * timeFactor; while(mCurrentEmission >= 1.0f) { if (ps.size() >= mLimitNumber /*|| !ps.empty()*/) { return; } Particle p; p.mEmitter = this; float speed; float width; float length; float height; float latitude; float variation; p.mVertices[0].texture_.x = 0; p.mVertices[0].texture_.y = 0; p.mVertices[1].texture_.x = 0; p.mVertices[1].texture_.y = 1; p.mVertices[2].texture_.x = 1; p.mVertices[2].texture_.y = 1; p.mVertices[3].texture_.x = 1; p.mVertices[3].texture_.y = 0; p.mStopMove = false; p.mColorStart = mColorStart; p.mColorMiddle = mColorMiddle; p.mColorEnd = mColorEnd; p.mAlpha = mAlpha; speed = mSpeedKFs.getFrame(at); width = mWidth.getFrame(at); length = mLength.getFrame(at); height = mHeigth.getFrame(at); latitude = mLatitude.getFrame(at); variation = mVariationKFs.getFrame(at); speed *= (1.0f + randomReal(0.0f, variation)); p.mPosition = Vector3(randomReal(-width,width), randomReal(-height,height), randomReal(-length,length)); p.mPosition = m.applyVector(p.mPosition); p.mOriginalPosition = p.mPosition; p.mNodeOriginalPosition = m.applyToOrigin(); Matrix mtxX; { Quaternion q; q.fromAngleAxis(randomReal(0,latitude * TwoPI / 360.f), Vector3::AxisX); mtxX.make(Vector3::Zero, Vector3::One, q); } Matrix mtxY; { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisY); mtxY.make(Vector3::Zero, Vector3::One, q); } Matrix rot; rot.multiply(mtxX, mtxY); p.mVelocity = rot.applyVector(Vector3(0,1,0)); p.mVelocity.normalise(); p.mVelocity = m.applyVectorNormal(p.mVelocity); p.mVelocity *= speed; p.mAge = 0.0f; if(mLifeSpan < mLifeVar) p.mLife = mLifeSpan; else p.mLife= randomReal(mLifeSpan - mLifeVar, mLifeSpan + mLifeVar); p.mGravity = mGravity.getFrame(at); p.mExplosiveForce = mExplosiveForce.getFrame(at); //每个粒子的缩放比例都可能不同 p.mScale.x = randomReal(mScale.x - mScaleVar.x, mScale.x + mScaleVar.x); if(mFixedSize) { p.mScale.y = p.mScale.z = p.mScale.x; } else { p.mScale.y = randomReal(mScale.y - mScaleVar.y, mScale.y + mScaleVar.y); p.mScale.z = randomReal(mScale.z - mScaleVar.z, mScale.z + mScaleVar.z); } //粒子旋转的角度 p.mAngle = randomReal(mInitAngleBegin, mInitAngleEnd); p.mRotateSpeed = randomReal(mRotateSpeed - mRotateSpeedVar, mRotateSpeed + mRotateSpeedVar) * timeFactor * 15.0f; if(mHead) { p.mHeadFramesNum = ((mHeadLifeSpan.y - mHeadLifeSpan.x + 1.0f) * mHeadLifeSpan.z); p.mHeadDecalFramesNum = ((mHeadDecay.y - mHeadDecay.x + 1.0f) * mHeadDecay.z); } else { p.mHeadFramesNum = 0; p.mHeadDecalFramesNum = 0; } if(mTail) { p.mTailFramesNum = ((mTailLifeSpan.y - mTailLifeSpan.x + 1.0f) * mTailLifeSpan.z); p.mTailDecalFramesNum = ((mTailDecay.y - mTailDecay.x + 1.0f) * mTailDecay.z); } else { p.mTailFramesNum = 0; p.mTailDecalFramesNum = 0; } if(mWander) { p.mWanderRadius = mWanderRadius; p.mWanderSpeed = mWanderSpeed; p.mWander = true; p.mWanderS = 0.0f; Matrix m1,m2; for(int i = 0;i < 4;i++) { { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisX); m1.make(Vector3::Zero, Vector3::One, q); } { Quaternion q; q.fromAngleAxis(randomReal(0,TwoPI), Vector3::AxisY); m2.make(Vector3::Zero, Vector3::One, q); } Matrix mt; mt.multiply(m1, m2); p.mWanderCatmullRom[i] = mWanderRadius * (mt.applyVector(Vector3::AxisZ)); } } // ps.push_back(p); // mCurrentEmission -= 1.0f; } }
qreal RandomUtil::randomReal(qreal min, qreal max) { return min + (randomReal() * (max - min)); }
void SimCalcs::intramolecularMove(int molIdx) { // Save the molecule data for rolling back // TODO (blm): Put these in the GPU with GPUCopy saveBonds(molIdx); saveAngles(molIdx); // Max with one to avoid divide by zero if no intra moves int numMoveTypes = max(ENABLE_BOND + ENABLE_ANGLE + ENABLE_DIHEDRAL, 1); Real intraScaleFactor = 0.25 + (0.75 / (Real)(numMoveTypes)); Real scaleFactor; std::set<int> indexes; Real newEnergy = 0, currentEnergy = calcIntraMolecularEnergy(molIdx); // TODO (blm): allow max to be configurable int numBonds = sb->moleculeData[MOL_BOND_COUNT][molIdx]; int bondStart = sb->moleculeData[MOL_BOND_START][molIdx]; int numAngles = sb->moleculeData[MOL_ANGLE_COUNT][molIdx]; int angleStart = sb->moleculeData[MOL_ANGLE_START][molIdx]; Real bondDelta = sb->maxBondDelta, angleDelta = sb->maxAngleDelta; // Handle bond moves if (ENABLE_BOND && sb->hasFlexibleBonds) { int numBondsToMove = sb->moleculeData[MOL_BOND_COUNT][molIdx]; if (numBondsToMove > 3) { numBondsToMove = (int)randomReal(2, numBonds); numBondsToMove = min(numBondsToMove, sb->maxIntraMoves); } scaleFactor = 0.25 + (0.75 / (Real)numBondsToMove) * intraScaleFactor; sb->numBondMoves += numBondsToMove; // Select the indexes of the bonds to move while (indexes.size() < numBondsToMove) { indexes.insert((int)randomReal(0, numBonds)); } // Move each bond for (auto bondIdx = indexes.begin(); bondIdx != indexes.end(); bondIdx++) { Real stretchDist = scaleFactor * randomReal(-bondDelta, bondDelta); if (sb->bondData[BOND_VARIABLE][bondStart + *bondIdx]) { stretchBond(molIdx, *bondIdx, stretchDist); } } // Do an MC test for delta tuning // Note: Failing does NOT mean we rollback newEnergy = calcIntraMolecularEnergy(molIdx); if (SimCalcs::acceptMove(currentEnergy, newEnergy)) { sb->numAcceptedBondMoves += numBondsToMove; } currentEnergy = newEnergy; indexes.clear(); } // Handle angle movements if (ENABLE_ANGLE && sb->hasFlexibleAngles) { int numAnglesToMove = sb->moleculeData[MOL_ANGLE_COUNT][molIdx]; if (numAnglesToMove > 3) { numAnglesToMove = (int)randomReal(2, numAngles); numAnglesToMove = min(numAnglesToMove, sb->maxIntraMoves); } scaleFactor = 0.25 + (0.75 / (Real)numAnglesToMove) * intraScaleFactor; sb->numAngleMoves += numAnglesToMove; // Select the indexes of the bonds to move while (indexes.size() < numAnglesToMove) { indexes.insert((int)randomReal(0, numAngles)); } // Move each angle for (auto angle = indexes.begin(); angle != indexes.end(); angle++) { Real expandDist = scaleFactor * randomReal(-angleDelta, angleDelta); if (sb->angleData[ANGLE_VARIABLE][angleStart + *angle]) { expandAngle(molIdx, *angle, expandDist); } } // Do an MC test for delta tuning // Note: Failing does NOT mean we rollback newEnergy = calcIntraMolecularEnergy(molIdx); if (SimCalcs::acceptMove(currentEnergy, newEnergy)) { sb->numAcceptedAngleMoves += numAnglesToMove; } currentEnergy = newEnergy; indexes.clear(); } // TODO: Put dihedral movements here // Tune the deltas to acheive 40% intramolecular acceptance ratio // FIXME: Make interval configurable if (ENABLE_TUNING && sb->stepNum != 0 && (sb->stepNum % 1000) == 0) { Real bondRatio = (Real)sb->numAcceptedBondMoves / sb->numBondMoves; Real angleRatio = (Real)sb->numAcceptedAngleMoves / sb->numAngleMoves; Real diff; diff = bondRatio - TARGET_RATIO; if (fabs(diff) > RATIO_MARGIN) { sb->maxBondDelta += sb->maxBondDelta * diff; } diff = angleRatio - TARGET_RATIO; if (fabs(angleDelta) > RATIO_MARGIN) { sb->maxAngleDelta += sb->maxAngleDelta * diff; } // Reset the ratio values sb->numAcceptedBondMoves = 0; sb->numBondMoves = 0; sb->numAcceptedAngleMoves = 0; sb->numAngleMoves = 0; } }
/** Returns the index of a random molecule within the simulation box */ int SimulationStep::chooseMolecule(SimBox *box) { return (int) randomReal(0, box->numMolecules); }
bool randomChance(double p) { initRandomSeed(); return randomReal(0, 1) < p; }
/** * Returns a random position within the radius */ double randInSquare(int radius) { double r = randomReal() * radius * 2; return (r > radius ? r - radius : r); }