/* * s e t u p N e w A u x i l i a r y Q P */ returnValue SQProblem::setupNewAuxiliaryQP( const real_t* const H_new, const real_t* const A_new, const real_t *lb_new, const real_t *ub_new, const real_t *lbA_new, const real_t *ubA_new ) { int_t nV = getNV( ); int_t nC = getNC( ); DenseMatrix *dA = 0; SymDenseMat *sH = 0; if ( A_new != 0 ) { dA = new DenseMatrix(nC, nV, nV, (real_t*) A_new); } else { if ( nC > 0 ) return THROWERROR( RET_INVALID_ARGUMENTS ); } if ( H_new != 0 ) sH = new SymDenseMat(nV, nV, nV, (real_t*) H_new); returnValue returnvalue = setupNewAuxiliaryQP( sH,dA, lb_new,ub_new,lbA_new,ubA_new ); if ( H_new != 0 ) freeHessian = BT_TRUE; freeConstraintMatrix = BT_TRUE; return returnvalue; }
int32_t pkCU::movePriority_Bracket() { // SOURCE: http://www.smogon.com/dp/articles/move_priority /* action: * AT_MOVE_0-3: pokemon's move * AT_MOVE_STRUGGLE : struggle * AT_MOVE_NOTHING : do nothing * AT_SWITCH_0-5: pokemon switches out for pokemon n-6 * AT_ITEM_USE: pokemon uses an item (not implemented) */ // team: // 0 - a // 1 - b int32_t actionResult = 0; const environment_volatile& base = getBase().getEnv(); size_t iCAction = getICAction(); size_t iCTeam = getICTeam(); // if the pokemon is switching out, its move priority is +6 switch(iActions[0]) { case AT_SWITCH_0: case AT_SWITCH_1: case AT_SWITCH_2: case AT_SWITCH_3: case AT_SWITCH_4: case AT_SWITCH_5: actionResult = 6; break; case AT_MOVE_0: case AT_MOVE_1: case AT_MOVE_2: case AT_MOVE_3: { // if the pokemon is performing a move, find the move's priority actionResult = (int32_t) getNV().getTeam(iCTeam).getPKNV(base.getTeam(iCTeam)).getMove_base(iCAction).getSpeedPriority(); //script - modify movePriority - action int result = 0; CALLPLUGIN(result, PLUGIN_ON_SETSPEEDBRACKET, onModifyBracket_rawType, *this, getPKNV().getMove_base(iCAction), getPKNV(), getTMV(), getPKV(), actionResult); break; } case AT_MOVE_NOTHING: actionResult = -7; break; case AT_MOVE_STRUGGLE: case AT_ITEM_USE: default: actionResult = 0; break; } return actionResult; }
Vector DenseCP::getMergedDualSolution( ) const { Vector dualSolution( getNV()+getNC() ); uint i; for( i=0; i<getNV(); ++i ) { if ( acadoIsGreater( fabs( (*ylb)(i) ),1e-10 ) == BT_TRUE ) dualSolution(i) = (*ylb)(i); else dualSolution(i) = (*yub)(i); } for( i=0; i<getNC(); ++i ) { if ( acadoIsGreater( fabs( (*ylbA)(i) ),1e-10 ) == BT_TRUE ) dualSolution( getNV()+i ) = (*ylbA)(i); else dualSolution( getNV()+i ) = (*yubA)(i); } return dualSolution; }
size_t pkCU::insertPluginHandler(plugin_t& cPlugin, size_t pluginType, size_t iNTeammate) { size_t numAdded = 0; uint32_t target = cPlugin.target; size_t iNTeam = (iNTeammate>=6)?1:0; size_t iTeammate = iNTeammate - 6*iNTeam; for (size_t iNCTeammate = 0; iNCTeammate != pluginSets.size(); ++iNCTeammate) { size_t iCTeam = iNCTeammate >= 6; size_t iCTeammate = iNCTeammate - 6*iCTeam; // don't add to a teammate that doesn't exist: if ((iCTeammate) >= getNV().getTeam(iCTeam).getNumTeammates()) { continue; } if ((target==TEAM_A) && (iCTeam != iNTeam)) { continue; } else if ((target==TEAM_B) && (iCTeam == iNTeam)) { continue; } //if on team of adding team, only match to this teammate. Otherwise match to all teammates if ((iNTeammate != SIZE_MAX) && (iNTeam == iCTeam) && (iTeammate != iCTeammate)) { continue; } for (size_t iOTeammate = 0; iOTeammate != getNV().getOtherTeam(iCTeam).getNumTeammates(); ++iOTeammate) { // if on opposite team of adding team, and not add if ((iNTeammate != SIZE_MAX) && (iCTeam != iNTeam) && (iTeammate != iOTeammate)) { continue; } std::vector<plugin_t>& _cPluginSet = pluginSets[iNCTeammate][iOTeammate][pluginType]; // check for duplicate: if (std::find(_cPluginSet.begin(), _cPluginSet.end(), cPlugin) != _cPluginSet.end()) { continue; } // add: _cPluginSet.push_back(cPlugin); numAdded++; } } return numAdded; }
returnValue DenseCP::setQPsolution( const Vector &x_, const Vector &y_ ){ uint run1; clean(); ASSERT( x_.getDim() == getNV() ); ASSERT( y_.getDim() == getNV() + getNC() ); // SET THE PRIMAL SOLUTION: // ------------------------ x = new Vector(x_); // SET THE DUAL SOLUTION FOR THE BOUNDS: // ------------------------------------- ylb = new Vector( getNV() ); yub = new Vector( getNV() ); for( run1 = 0; run1 < getNV(); run1++ ){ if( fabs(x_(run1)-lb(run1)) <= BOUNDTOL ){ ylb->operator()(run1) = y_(run1); yub->operator()(run1) = 0.0 ; } else{ ylb->operator()(run1) = 0.0 ; yub->operator()(run1) = y_(run1); } } // SET THE DUAL SOLUTION FOR THE CONSTRAINTS: // ------------------------------------------ Vector tmp = A*x_; ylbA = new Vector( getNC() ); yubA = new Vector( getNC() ); for( run1 = 0; run1 < getNC(); run1++ ){ if( fabs(tmp(run1)-lbA(run1)) <= BOUNDTOL ){ ylbA->operator()(run1) = y_(getNV()+run1); yubA->operator()(run1) = 0.0 ; } else{ ylbA->operator()(run1) = 0.0 ; yubA->operator()(run1) = y_(getNV()+run1); } } return SUCCESSFUL_RETURN; }
/* * s e t u p A u x i l i a r y Q P */ returnValue SQProblem::setupAuxiliaryQP( const real_t* const H_new, const real_t* const A_new, const real_t *lb_new, const real_t *ub_new, const real_t *lbA_new, const real_t *ubA_new ) { int nV = getNV( ); int nC = getNC( ); DenseMatrix *dA = new DenseMatrix(nC, nV, nV, (real_t*) A_new); SymDenseMat *sH = new SymDenseMat(nV, nV, nV, (real_t*) H_new); returnValue returnvalue = setupAuxiliaryQP ( sH, dA, lb_new, ub_new, lbA_new, ubA_new ); if ( H_new != 0 ) freeHessian = BT_TRUE; freeConstraintMatrix = BT_TRUE; return returnvalue; }
/* * s e t u p A u x i l i a r y Q P */ returnValue SQProblem::setupAuxiliaryQP ( SymmetricMatrix *H_new, Matrix *A_new, const real_t *lb_new, const real_t *ub_new, const real_t *lbA_new, const real_t *ubA_new ) { int i; int nV = getNV( ); int nC = getNC( ); returnValue returnvalue; if ( ( getStatus( ) == QPS_NOTINITIALISED ) || ( getStatus( ) == QPS_PREPARINGAUXILIARYQP ) || ( getStatus( ) == QPS_PERFORMINGHOMOTOPY ) ) { return THROWERROR( RET_UPDATEMATRICES_FAILED_AS_QP_NOT_SOLVED ); } status = QPS_PREPARINGAUXILIARYQP; /* I) SETUP NEW QP MATRICES AND VECTORS: */ /* 1) Shift constraints' bounds vectors by (A_new - A)'*x_opt to ensure * that old optimal solution remains feasible for new QP data. */ /* Firstly, shift by -A'*x_opt and ... */ if ( nC > 0 ) { if ( A_new == 0 ) return THROWERROR( RET_INVALID_ARGUMENTS ); for ( i=0; i<nC; ++i ) { lbA[i] = -Ax_l[i]; ubA[i] = Ax_u[i]; } /* Set constraint matrix as well as ... */ setA( A_new ); /* ... secondly, shift by +A_new'*x_opt. */ for ( i=0; i<nC; ++i ) { lbA[i] += Ax[i]; ubA[i] += Ax[i]; } /* update constraint products. */ for ( i=0; i<nC; ++i ) { Ax_u[i] = ubA[i] - Ax[i]; Ax_l[i] = Ax[i] - lbA[i]; } } /* 2) Set new Hessian matrix, determine Hessian type and * regularise new Hessian matrix if necessary. */ /* a) Setup new Hessian matrix and determine its type. */ if ( H_new != 0 ) { setH( H_new ); hessianType = HST_UNKNOWN; if ( determineHessianType( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); /* b) Regularise new Hessian if necessary. */ if ( ( hessianType == HST_ZERO ) || ( hessianType == HST_SEMIDEF ) || ( usingRegularisation( ) == BT_TRUE ) ) { regVal = 0.0; /* reset previous regularisation */ if ( regulariseHessian( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); } } else { if ( H != 0 ) return THROWERROR( RET_NO_HESSIAN_SPECIFIED ); } /* 3) Setup QP gradient. */ if ( setupAuxiliaryQPgradient( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); /* II) SETUP WORKING SETS AND MATRIX FACTORISATIONS: */ /* 1) Make a copy of current bounds/constraints ... */ Bounds oldBounds = bounds; Constraints oldConstraints = constraints; /* we're trying to find an active set with positive definite null * space Hessian twice: * - first for the current active set including all equalities * - second after moving all inactive variables to a bound * (depending on Options). This creates an empty null space and * is guaranteed to succeed. Thus this loop will exit after n_try=1. */ int n_try; for (n_try = 0; n_try < 2; ++n_try) { if (n_try > 0) { // the current active set leaves an indefinite null space Hessian // move all inactive variables to a bound, creating an empty null space for (int ii = 0; ii < nV; ++ii) if (oldBounds.getStatus (ii) == ST_INACTIVE) oldBounds.setStatus (ii, options.initialStatusBounds); } /* ... reset them ... */ bounds.init( nV ); constraints.init( nC ); /* ... and set them up afresh. */ if ( setupSubjectToType(lb_new,ub_new,lbA_new,ubA_new ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); if ( bounds.setupAllFree( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); if ( constraints.setupAllInactive( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); /* 2) Setup TQ factorisation. */ if ( setupTQfactorisation( ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); // check for equalities that have become bounds ... for (int ii = 0; ii < nC; ++ii) { if (oldConstraints.getType (ii) == ST_EQUALITY && constraints.getType (ii) == ST_BOUNDED) { if (oldConstraints.getStatus (ii) == ST_LOWER && y[nV+ii] < 0.0) oldConstraints.setStatus (ii, ST_UPPER); else if (oldConstraints.getStatus (ii) == ST_UPPER && y[nV+ii] > 0.0) oldConstraints.setStatus (ii, ST_LOWER); } } // ... and do the same also for the bounds! for (int ii = 0; ii < nV; ++ii) { if (oldBounds.getType(ii) == ST_EQUALITY && bounds.getType(ii) == ST_BOUNDED) { if (oldBounds.getStatus(ii) == ST_LOWER && y[ii] < 0.0) oldBounds.setStatus(ii, ST_UPPER); else if (oldBounds.getStatus(ii) == ST_UPPER && y[ii] > 0.0) oldBounds.setStatus(ii, ST_LOWER); } } /* 3) Setup old working sets afresh (updating TQ factorisation). */ if ( setupAuxiliaryWorkingSet( &oldBounds,&oldConstraints,BT_TRUE ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_SETUP_AUXILIARYQP_FAILED ); /* Factorise projected Hessian * this now handles all special cases (no active bounds/constraints, no nullspace) */ returnvalue = computeProjectedCholesky( ); /* leave the loop if decomposition was successful, i.e. we have * found an active set with positive definite null space Hessian */ if ( returnvalue == SUCCESSFUL_RETURN ) break; } /* adjust lb/ub if we changed the old active set in the second try */ if (n_try > 0) { // as per setupAuxiliaryQPbounds assumptions ... oh the troubles for (int ii = 0; ii < nC; ++ii) Ax_l[ii] = Ax_u[ii] = Ax[ii]; setupAuxiliaryQPbounds (&bounds, &constraints, BT_FALSE); } status = QPS_AUXILIARYQPSOLVED; return SUCCESSFUL_RETURN; }
/* * h o t s t a r t */ returnValue SQProblem::hotstart( const char* const H_file, const char* const g_file, const char* const A_file, const char* const lb_file, const char* const ub_file, const char* const lbA_file, const char* const ubA_file, int& nWSR, real_t* const cputime ) { int nV = getNV( ); int nC = getNC( ); returnValue returnvalue; /* consistency checks */ if ( ( H_file == 0 ) || ( g_file == 0 ) ) return THROWERROR( RET_INVALID_ARGUMENTS ); if ( ( nC > 0 ) && ( A_file == 0 ) ) return THROWERROR( RET_INVALID_ARGUMENTS ); /* 1) Load new QP matrices from files. */ real_t* H_new = new real_t[nV*nV]; real_t* A_new = new real_t[nC*nV]; if ( readFromFile( H_new, nV,nV, H_file ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_UNABLE_TO_READ_FILE ); if ( readFromFile( A_new, nC,nV, A_file ) != SUCCESSFUL_RETURN ) return THROWERROR( RET_UNABLE_TO_READ_FILE ); /* 2) Load new QP vectors from files. */ real_t* g_new = new real_t[nV]; real_t* lb_new = 0; real_t* ub_new = 0; real_t* lbA_new = 0; real_t* ubA_new = 0; if ( lb_file != 0 ) lb_new = new real_t[nV]; if ( ub_file != 0 ) ub_new = new real_t[nV]; if ( lbA_file != 0 ) lbA_new = new real_t[nC]; if ( ubA_file != 0 ) ubA_new = new real_t[nC]; returnvalue = loadQPvectorsFromFile( g_file,lb_file,ub_file,lbA_file,ubA_file, g_new,lb_new,ub_new,lbA_new,ubA_new ); if ( returnvalue != SUCCESSFUL_RETURN ) { if ( ubA_file != 0 ) delete[] ubA_new; if ( lbA_file != 0 ) delete[] lbA_new; if ( ub_file != 0 ) delete[] ub_new; if ( lb_file != 0 ) delete[] lb_new; delete[] g_new; delete[] A_new; delete[] H_new; return THROWERROR( RET_UNABLE_TO_READ_FILE ); } /* 3) Actually perform hotstart. */ returnvalue = hotstart( H_new,g_new,A_new,lb_new,ub_new,lbA_new,ubA_new, nWSR,cputime ); if ( ubA_file != 0 ) delete[] ubA_new; if ( lbA_file != 0 ) delete[] lbA_new; if ( ub_file != 0 ) delete[] ub_new; if ( lb_file != 0 ) delete[] lb_new; delete[] g_new; delete[] A_new; delete[] H_new; return returnvalue; }
void DenseCP::copy( const DenseCP& rhs ){ uint run1, run2; nS = rhs.nS; H = rhs.H; g = rhs.g; lb = rhs.lb; ub = rhs.ub; A = rhs.A; lbA = rhs.lbA; ubA = rhs.ubA; if( rhs.B != 0 ){ B = (Matrix**)calloc(nS,sizeof(Matrix*)); for( run1 = 0; run1 < nS; run1++ ){ B[run1] = new Matrix[ getNV() ]; for( run2 = 0; run2 < getNV(); run2++ ) B[run1][run2] = rhs.B[run1][run2]; } } else B = 0; if( rhs.lbB != 0 ){ lbB = (Vector*)calloc(nS,sizeof(Vector)); for( run1 = 0; run1 < nS; run1++ ) lbB[run1] = rhs.lbB[run1]; } else lbB = 0; if( rhs.ubB != 0 ){ ubB = (Vector*)calloc(nS,sizeof(Vector)); for( run1 = 0; run1 < nS; run1++ ) ubB[run1] = rhs.ubB[run1]; } else ubB = 0; if( rhs.x != 0 ) x = new Vector(*rhs.x); else x = 0 ; if( rhs.ylb != 0 ) ylb = new Vector(*rhs.ylb); else ylb = 0 ; if( rhs.yub != 0 ) yub = new Vector(*rhs.yub); else yub = 0 ; if( rhs.ylbA != 0 ) ylbA = new Vector(*rhs.ylbA); else ylbA = 0 ; if( rhs.yubA != 0 ) yubA = new Vector(*rhs.yubA); else yubA = 0 ; if( nS > 0 ){ ylbB = (Vector**)calloc(nS,sizeof(Vector*)); yubB = (Vector**)calloc(nS,sizeof(Vector*)); for( run1 = 0; run1 < nS; run1++ ){ if( rhs.ylbB[run1] != 0 ) ylbB[run1] = new Vector(*rhs.ylbB[run1]); else ylbB[run1] = 0 ; if( rhs.yubB[run1] != 0 ) yubB[run1] = new Vector(*rhs.yubB[run1]); else yubB[run1] = 0 ; } } else{ ylbB = 0; yubB = 0; } }
const pokemon_nonvolatile& pkCU::getTPKNV() { return getNV().getTeam(getIOTeam()).getPKNV(getBase().getEnv().getTeam(getIOTeam())); }
bool pkCU::isValidAction(const environment_volatile& envV, size_t action, size_t iTeam) { const team_volatile& cTV = envV.getTeam(iTeam); const team_volatile& oTV = envV.getOtherTeam(iTeam); const team_nonvolatile& cTNV = getNV().getTeam(iTeam); const pokemon_nonvolatile& cPokemon = cTNV.getPKNV(cTV); switch(action) { case AT_MOVE_0: case AT_MOVE_1: case AT_MOVE_2: case AT_MOVE_3: { /* is this a valid move? */ if ((action - AT_MOVE_0) >= cPokemon.getNumMoves()) { return false; } // is the other pokemon alive? if (!(oTV.getPKV().isAlive())) { return false; } // is the pokemon we're currently using alive? if (!cTV.getPKV().isAlive()) { return false; } // does the move we're using have any PP left? if ( cTV.getPKV().getMV(action - AT_MOVE_0).hasPP() != true ) { return false; } //TODO: are we locked out of the current move? return true; // by default, allow moves } case AT_SWITCH_0: case AT_SWITCH_1: case AT_SWITCH_2: case AT_SWITCH_3: case AT_SWITCH_4: case AT_SWITCH_5: { // is the pokemon we're switching to a valid teammate? if ( ((action - AT_SWITCH_0) < cTNV.getNumTeammates()) != true) { return false; } // are we trying to switch to ourself? if ((action - AT_SWITCH_0) == cTV.getICPKV()) { return false; } // is the pokemon we're switching to even alive? if ( cTV.teammate(action - AT_SWITCH_0).isAlive() != true) { return false; } // are we trying to move during the other team's free move? if ( !(oTV.getPKV().isAlive()) && cTV.getPKV().isAlive() ) { return false; } // TODO: are we locked out of switching? return true; // by default, allow switches } case AT_MOVE_NOTHING: // are we waiting for the other team to take its free move? if ( !(oTV.getPKV().isAlive()) && cTV.getPKV().isAlive() ) { return true; } // in most cases, do not allow not moving return false; case AT_MOVE_STRUGGLE: // is the other pokemon alive? if (!(oTV.getPKV().isAlive())) { return false; } // is the pokemon we're currently using alive? if (!cTV.getPKV().isAlive()) { return false; } // can the pokemon struggle? if (!cTV.cHasPP()) { return true; } // cannot struggle by default return false; // disabled action types: case AT_ITEM_USE: case AT_MOVE_CONFUSED: return false; default: // what the hell happened here? No, this isn't a valid move. Shut up. return false; } } // endOf is valid action
bool pkCU::initialize() { size_t numPlugins = 0; // clear plugin arrays: for (size_t iNCTeammate = 0; iNCTeammate != pluginSets.size(); ++iNCTeammate) { for (size_t iOTeammate = 0; iOTeammate != pluginSets[iNCTeammate].size(); ++iOTeammate) { boost::array<std::vector<plugin_t>, PLUGIN_MAXSIZE>& _cPluginSet = pluginSets[iNCTeammate][iOTeammate]; for (size_t iPlugin = 0; iPlugin != _cPluginSet.size(); ++iPlugin) { _cPluginSet[iPlugin].clear(); } } } // add individual plugins: (for each possible current pokemon, 12 total) for (size_t iNCTeammate = 0; iNCTeammate != pluginSets.size(); ++iNCTeammate) { size_t iCTeam = iNCTeammate >= 6; size_t iCTeammate = iNCTeammate - 6*iCTeam; // don't add to a teammate that doesn't exist: if ((iCTeammate) >= getNV().getTeam(iCTeam).getNumTeammates()) { continue; } // current nonvolatile teammate: const pokemon_nonvolatile& cPKNV = getNV().getTeam(iCTeam).teammate(iCTeammate); // plugins for moves: for (size_t iCMove = 0; iCMove != cPKNV.getNumMoves(); ++iCMove) { const pluggable& cPluggable = cPKNV.getMove_base(iCMove); for (size_t iPlugin = 0; iPlugin != PLUGIN_MAXSIZE; ++iPlugin) { plugin_t cPlugin = cPluggable.getPlugin(iPlugin); if (cPlugin.pFunction == NULL) { continue; } insertPluginHandler(cPlugin, iPlugin, iNCTeammate); numPlugins++; } } // plugins for abilities: if (cPKNV.abilityExists()) { const pluggable& cPluggable = cPKNV.getAbility(); for (size_t iPlugin = 0; iPlugin != PLUGIN_MAXSIZE; ++iPlugin) { plugin_t cPlugin = cPluggable.getPlugin(iPlugin); if (cPlugin.pFunction == NULL) { continue; } insertPluginHandler(cPlugin, iPlugin, iNCTeammate); numPlugins++; } } // plugins for items: TODO: what if the items switch teammates? if (cPKNV.hasInitialItem()) { const pluggable& cPluggable = cPKNV.getInitialItem(); for (size_t iPlugin = 0; iPlugin != PLUGIN_MAXSIZE; ++iPlugin) { plugin_t cPlugin = cPluggable.getPlugin(iPlugin); if (cPlugin.pFunction == NULL) { continue; } insertPluginHandler(cPlugin, iPlugin, iNCTeammate); numPlugins++; } } } // endOf cTeammate // TODO: add plugins that affect the other pokemon: // add global (and engine) plugins second: for (size_t iPluginType = 0; iPluginType != PLUGIN_MAXSIZE; ++iPluginType) { for (size_t iPlugin = 0; iPlugin != pkdex->getExtensions().getNumPlugins(iPluginType); ++iPlugin) { plugin_t cPlugin = pkdex->getExtensions().getPlugin(iPluginType, iPlugin); numPlugins++; insertPluginHandler(cPlugin, iPluginType); } } // SORT plugins by priority: for (size_t iNCTeammate = 0; iNCTeammate != pluginSets.size(); ++iNCTeammate) { for (size_t iOTeammate = 0; iOTeammate != pluginSets[iNCTeammate].size(); ++iOTeammate) { boost::array<std::vector<plugin_t>, PLUGIN_MAXSIZE>& _cPluginSet = pluginSets[iNCTeammate][iOTeammate]; for (size_t iPlugin = 0; iPlugin != _cPluginSet.size(); ++iPlugin) { std::sort(_cPluginSet[iPlugin].begin(), _cPluginSet[iPlugin].end()); } } } assert(numPlugins <= MAXPLUGINS); return true; }