bool IntSet::isSubsetOf(const IntSet& otherIntSet) const { int foundCount = 0; if( this->isEmpty() ) return true; else if( this->size() > otherIntSet.size() ) { return false; } else { for( int thisI = 0; thisI < this->size(); thisI ++ ) { for( int otherI = 0 ; otherI < otherIntSet.size(); otherI ++ ) { if( this->data[thisI] == otherIntSet.data[otherI] ) foundCount ++; } } if( foundCount == this->size() ) return true; else return false; } }
bool equal(const IntSet& is1, const IntSet& is2) { if( is1.size() == is2.size() && // check if sets are same length is1.isSubsetOf(is2) && // check if sets are subsets of each other is2.isSubsetOf(is1) ) return true; // if both conditions hold, return true else return false; // else return false }
bool operator==(const IntSet& is1, const IntSet& is2) // this function checks to see if is1 == is2 by confirming if: // * each object's elements are subsets of one another // * each object's data[] array contains the same # elements { if ( is1.size() == is2.size() && is1.isSubsetOf(is2) && is2.isSubsetOf(is1) ) return true; else return false; }
IntSet IntSet::subtract(const IntSet& otherIntSet) const { // create temporary array object to hold values unique to this intSet IntSet tempArray; int tempIndex = 0; bool tempFlag = false; // the tempFlag marks dupes for( int i = 0; i < this->size(); i ++ ) { for( int i2 = 0; i2 < otherIntSet.size(); i2 ++ ) { if( this->data[i] == otherIntSet.data[i2] ) { tempFlag = true; // if flag data matches, then true } } if( !tempFlag ) // if tempFlag == false, then there's no dupes, so { tempArray.data[tempIndex] = this->data[i]; // save the unique data tempArray.used ++; // increment the used variable tempIndex ++; // increment the element index } tempFlag = false; // reset the tempFlag for next iteration } return tempArray; // return the IntSet obj }
IntVar::IntVar(Space& home, const IntSet& ds) : VarImpVar<Int::IntVarImp>(new (home) Int::IntVarImp(home,ds)) { Int::Limits::check(ds.min(),"IntVar::IntVar"); Int::Limits::check(ds.max(),"IntVar::IntVar"); if (ds.size() == 0) throw Int::VariableEmptyDomain("IntVar::IntVar"); }
/** * Accessor to indices. * @return pointer to indices collection. */ IntSet* getIndices() { IntSet * newIndices = new IntSet(); for(unsigned i = 0; i < indices.size(); i++) newIndices->push_back(indices[i]); return newIndices; }
inline void Limits::check(const IntSet& s, const char* l) { if ((s.size() > 0) && ((s.min() < min) || (s.max() > max) || (s.min() > max) || (s.max() < min))) throw OutOfLimits(l); }
IntSet IntSet::intersect(const IntSet& otherIntSet) const { IntSet tempArray; // create a temp IntSet object // to hold the intersection values int tempIndex = 0; int strikeCount = 0; // var to count # times that // a value in IntSet does not // match a value in otherIntSet bool removeSuccess; // flag handle to call remove() // copy this IntSet into tempArray for( int i = 0; i < this->size(); i ++ ) { tempArray.data[tempIndex] = this->data[i]; tempArray.used ++; tempIndex ++; } // remove the contents of tempArray if they're not contained // in the intersection of thisIntSet and otherIntSet for( int i = 0; i < this->size(); i ++ ) { for( int i2 = 0; i2 < otherIntSet.size(); i2 ++ ) { if( this->data[i] != otherIntSet.data[i2] ) strikeCount ++; } if( strikeCount == otherIntSet.size() ) { // strikeCount == otherIntSet.size(), then the // IntSet value was not found in otherIntSet, so // it's not part of the intersection and should be // removed. . . removeSuccess = ( tempArray.remove(this->data[i]) ); // remove the value } if( removeSuccess ) // here, i'm just using var f in a statement // in order to get rid of a compiler warning; strikeCount = 0; // reset the strike count for the next iteration else strikeCount = 0; } return tempArray; // return intersection values }
IntVarArgs::IntVarArgs(Space& home, int n, const IntSet& s) : VarArgArray<IntVar>(n) { Int::Limits::check(s.min(),"IntVarArgs::IntVarArgs"); Int::Limits::check(s.max(),"IntVarArgs::IntVarArgs"); if (s.size() == 0) throw Int::VariableEmptyDomain("IntVarArgs::IntVarArgs"); for (int i = size(); i--; ) a[i]._init(home,s); }
/** allocates memory for handling the specified number * of variables */ void setup(size_t numVars) { size_t size = (1 + numVars) * 2; if (reasonLits.size() < size) { DBG(1, "reason allocated for " << size); reasonLits.setup(size); } varNodeMap.resize(numVars+1); }
void CachedView<View>::initCache(Space& home, const IntSet& s) { _firstRange = NULL; for (int i=s.ranges(); i--;) { _firstRange = new (home) RangeList(s.min(i),s.max(i),_firstRange); if (i==s.ranges()-1) _lastRange = _firstRange; } _size = s.size(); }
bool count(int s, int mod) { IntSet set; for (int i = 0; i < N; i++) { const char *p = keyTbl[i]; int h = hash(p, strlen(p), s, mod); set.insert(h); } return set.size() == N; }
//copy constructor IntSet::IntSet(const IntSet& obj) { maxSize = obj.maxSize; //copy the capacity of the argument's set set = new int[maxSize]; //allocate space for a set of integers numElements = 0; //initialize the number of elements for (int i = 0; i < obj.size(); i++) //copy all element from the argument's set into a new set { add(obj.set[i]); } }
/********************************************************************************************************* ** Description: Calculates the union of two or more sets, returning the set that represents that union. **********************************************************************************************************/ IntSet IntSet::getUnion(const IntSet& obj) const { IntSet unionSet = *this; //initialize a new set with the elements of the calling set for (int i = 0; i < obj.size(); i++) //loop through the set given as an argument { if (!unionSet.contains(obj.set[i])) //if the current element is not already in the union set... { unionSet.add(obj.set[i]); //add that element to the union set } } return unionSet; //return the union }
/********************************************************************************************************* ** Description: Calculates the intersection of two or more sets, returning the set that represents ** that intersection. **********************************************************************************************************/ IntSet IntSet::getIntersection(const IntSet& obj) const { IntSet interSet; for (int i = 0; i < obj.size(); i++) //loop through the set given as an argument { if (this->contains(obj.set[i])) //if the calling set contains the argument's current element... { interSet.add(obj.set[i]); //add that element to the intersection set } } return interSet; //return the intersection }
/********************************************************************************************************* ** Description: Calculates the difference of two or more sets, returning the set that represents ** that difference. **********************************************************************************************************/ IntSet IntSet::getDifference(const IntSet& obj) const { IntSet diffSet = *this; //initialize a new set with the elements of the calling set for (int i = 0; i < obj.size(); i++) //loop through the set given as an argument { if (diffSet.contains(obj.set[i])) //if the current element is in the difference set... { diffSet.remove(obj.set[i]); //then remove that element from the difference set } } return diffSet; //return the difference set }
void getSmallK(const vector<int>& data, IntSet& s, int k) { if (data.size() < k || k < 1) return; for (int i = 0; i < data.size(); ++i) { if (s.size() < k) s.insert(data[k]); else if (data[k] < s.begin()) { s.erase(s.begin()); s.insert(data[k]); } } }
int maxCities(int n, vector <int> a, vector <int> b, vector <int> len) { if (n <= 2) { return n; } int d[50][50]; memset(d, 0x3f, sizeof(d)); for (int i = 0; i < (int)a.size(); ++i) { d[a[i]-1][b[i]-1] = len[i]; d[b[i]-1][a[i]-1] = len[i]; } for (int k = 0; k < n; ++k) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } } int ans = 2; for (int i = 0; i < n; ++i) { for (int j = i+1; j < n; ++j) { int r = d[i][j]; if (r < 1e6) { IntSet s; s.insert(i); s.insert(j); for (int k = 0; k < n; ++k) { if (i != k && j != k) { IntSet::const_iterator it; for (it = s.begin(); it != s.end(); ++it) { if (d[k][*it] != r) { break; } } if (it == s.end()) { s.insert(k); } } } ans = max(ans, (int)s.size()); } } } return ans; }
IntSet IntSet::intersect(const IntSet& otherIntSet) const // this function creates a temporary IntSet object to collect // the intersection of relevant values from IntSet and otherIntSet; // any values not in the intersection are removed before // returning the intersection to the calling function { IntSet tempArray(capacity); // create a temp IntSet object // to hold the intersection vals int strikeCount = 0; // this var counts # times that // a value in IntSet does not // match a value in otherIntSet for( int i = 0; i < used; i ++ ) // copy IntSet into tempArray { tempArray.data[i] = data[i]; tempArray.used ++; } // now, remove the contents of tempArray if they're not contained // in the intersection of thisIntSet and otherIntSet: for( int i = 0; i < used; i ++ ) { for( int i2 = 0; i2 < otherIntSet.used; i2 ++ ) { if( data[i] != otherIntSet.data[i2] ) strikeCount ++; } if( strikeCount == otherIntSet.size() ) { // if strikeCount == otherIntSet.size(), then the // IntSet value was not found in otherIntSet, so // it's not part of the intersection and should be // removed. . . assert ( tempArray.remove(data[i]) == true ); strikeCount = 0; // reset count for the next loop } } return tempArray; // return the intersection values }
void init( const ObjModel* model, const IntSet& vidxs) { _kddata = new kdtree::KDTreeArray; const int n = (int)vidxs.size(); _kddata->resize( boost::extents[n][3]); _vmap = new std::vector<int>(n); int i = 0; for ( int vidx : vidxs) { const cv::Vec3f& v = model->vtx(vidx); (*_kddata)[i][0] = v[0]; (*_kddata)[i][1] = v[1]; (*_kddata)[i][2] = v[2]; _vmap->at(i++) = vidx; } // end foreach _kdtree = new kdtree::KDTree( *_kddata); } // end init
IntSet IntSet::unionWith(const IntSet& otherIntSet) const { assert( ( this->size() + (otherIntSet.subtract(*this)).size() ) <= MAX_SIZE ); IntSet tempArray; int tempIndex = 0; bool tempFlag = false; // copy this IntSet into tempArray for( int i = 0; i < this->size(); i ++ ) { tempArray.data[tempIndex] = this->data[i]; tempArray.used ++; tempIndex ++; } // add contents of otherIntSet to tempArray, ignoring dupes for( int i2 = 0; i2 < otherIntSet.size(); i2 ++ ) { for( int i = 0; i < this->size(); i ++ ) { if( otherIntSet.data[i2] == this->data[i] ) { tempFlag = true; // flag data matches (we don't want dupes) } } if( !tempFlag ) { tempArray.data[tempIndex] = otherIntSet.data[i2]; // save the unique data tempArray.used ++; // increment used tempIndex ++; // increment index } tempFlag = false; // reset tempFlag for next iteration } return tempArray; }
void sequence(Home home, const IntVarArgs& x, const IntSet &s, int q, int l, int u, IntConLevel) { Limits::check(s.min(),"Int::sequence"); Limits::check(s.max(),"Int::sequence"); if (x.size() == 0) throw TooFewArguments("Int::sequence"); Limits::check(q,"Int::sequence"); Limits::check(l,"Int::sequence"); Limits::check(u,"Int::sequence"); if (x.same(home)) throw ArgumentSame("Int::sequence"); if ((q < 1) || (q > x.size())) throw OutOfLimits("Int::sequence"); if (home.failed()) return; // Normalize l and u l=std::max(0,l); u=std::min(q,u); // Lower bound of values taken can never exceed upper bound if (u < l) { home.fail(); return; } // Already subsumed as any number of values taken is okay if ((0 == l) && (q == u)) return; // All variables must take a value in s if (l == q) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.inter_r(home,ris,false)); } return; } // No variable can take a value in s if (0 == u) { for (int i=x.size(); i--; ) { IntView xv(x[i]); IntSetRanges ris(s); GECODE_ME_FAIL(xv.minus_r(home,ris,false)); } return; } ViewArray<IntView> xv(home,x); if (s.size() == 1) { GECODE_ES_FAIL( (Sequence::Sequence<IntView,int>::post (home,xv,s.min(),q,l,u))); } else { GECODE_ES_FAIL( (Sequence::Sequence<IntView,IntSet>::post (home,xv,s,q,l,u))); } }
IntSet IntSet::unionWith(const IntSet& otherIntSet) const // this function creates a temporary IntSet object to collect the union of // relevant data values from IntSet and otherIntSet; the sequence // of values is maintained while duplicates are removed; if the union // requires more capacity, resize() is called; { int totUnionVals = 0; // var to count # vals in union IntSet tempArray(capacity); // create tempIntSet object int tempIndex = 0; // var to mark the index where // the union values from // otherIntSet should begin // to be inserted bool tempFlag = false; // this flag used to mark dupes // use an outer loop to copy IntSet values into tempArray; // use an inner loop to count up dupe values so that afterward // we can compute # values needed in final union: for( int i = 0; i < used; i ++ ) { tempArray.data[i] = data[i]; tempArray.used ++; tempIndex ++; for( int i2 = 0; i2 < otherIntSet.used; i2 ++ ) { if( data[i] == otherIntSet.data[i2] ) totUnionVals ++; } } // compute total # of vals needed in final union and resize if needed: totUnionVals = ( used + otherIntSet.used ) - totUnionVals; if( tempArray.capacity < totUnionVals ) tempArray.resize(totUnionVals); // now insert the content from otherIntSet into tempArray, w/o dupes: int otherUsed = otherIntSet.size(); // sentinel for outer loop for( int i2 = 0; i2 < otherUsed; i2 ++ ) { for( int i = 0; i < tempArray.used; i ++ ) { if( otherIntSet.data[i2] == tempArray.data[i] ) { tempFlag = true; // flag the dupes } } if( !tempFlag ) // save non-dupes to tempArray { tempArray.data[tempIndex] = otherIntSet.data[i2]; tempArray.used ++; tempIndex ++; } tempFlag = false; // reset tempFlag for next pass } return tempArray; }
void NoisyCnaEnumerate::collapse(const StlIntVector& mapNewCharToOldChar, const StlIntVector& mapOldCharToNewChar, RootedCladisticNoisyAncestryGraph& G) { typedef std::set<IntPair> IntPairSet; int k = _M.k(); const auto& intervals = _M.intervals(); for (const IntSet& interval : intervals) { IntSet remappedInterval; for (int c : interval) { int cc = mapOldCharToNewChar[c]; if (cc != -1) remappedInterval.insert(cc); } if (remappedInterval.size() > 1) { // get the copy states IntPairSet XY; const StateTree& S = G.S(*remappedInterval.begin()); for (int i = 0; i < k; ++i) { if (S.isPresent(i)) { const auto& xyz = _M.stateToTriple(i); // skip state 1,1 if (xyz._x != 1 || xyz._y != 1) { XY.insert(IntPair(xyz._x, xyz._y)); } } } for (const IntPair& xy : XY) { assert(xy.first != 1 || xy.second != 1); // collect all char-state pairs correspond to CNAs IntPairSet toCollapse; for (int c : remappedInterval) { const StateTree& S_c = G.S(c); for (int i = 0; i < k; ++i) { if (S_c.isPresent(i) && _M.stateToTriple(i)._x == xy.first && _M.stateToTriple(i)._y == xy.second) { int pi_i = S_c.parent(i); assert(0 <= pi_i && pi_i < k); if (_M.stateToTriple(pi_i)._x != xy.first || _M.stateToTriple(pi_i)._y != xy.second) { // we got a CNA state toCollapse.insert(IntPair(c, i)); } } } } G.collapse(toCollapse); } } } }
void GameArbiter::process_command(Message *command) { switch (command->type) { case UnitMove: { auto cmd = dynamic_cast<UnitMoveMessage *>(command); int stack_id = cmd->data1; IntSet units = cmd->data2; Path& path = cmd->data3; int target_id = cmd->data4; UnitStack::pointer stack = game->stacks.get(stack_id); if (units.empty() || !stack->has_units(units) || path.empty()) { throw DataError() << "Invalid UnitMove message"; } /* Check that the move is allowed; shorten it if necessary */ Point end_pos = path.back(); UnitStack::pointer end_stack = game->level.tiles[end_pos].stack; int end_stack_id = end_stack ? end_stack->id : 0; if (end_stack_id != target_id) { path.pop_back(); target_id = 0; } MovementModel movement(game); UnitStack::pointer selected_stack = stack->copy_subset(units); unsigned int allowed_steps = movement.check_path(*selected_stack, path); bool truncated = allowed_steps < path.size(); int attack_target_id = target_id; if (truncated) target_id = 0; path.resize(allowed_steps); if (!path.empty()) { end_pos = path.back(); /* Generate updates. */ Faction::pointer faction = stack->owner; bool move = units.size() == stack->units.size() && target_id == 0; bool split = units.size() < stack->units.size() && target_id == 0; bool merge = units.size() == stack->units.size() && target_id != 0; UnitStack::pointer target = game->stacks.find(target_id); if (move) target_id = stack_id; if (split) target_id = game->get_free_stack_id(); // Send the moves for (auto iter = path.begin(); iter != path.end(); iter++) { emit(create_message(MoveUnits, stack_id, units, *iter)); } // If the stack is splitting to a new empty position, create a stack there if (split) { emit(create_message(CreateStack, target_id, end_pos, faction->id)); } emit(create_message(TransferUnits, stack_id, units, path, target_id)); // If the whole stack merged with an existing one, destroy it if (merge) { emit(create_message(DestroyStack, stack_id)); } } else { end_pos = stack->position; } UnitStack::pointer attack_target = game->stacks.find(attack_target_id); bool attack = attack_target && (attack_target->owner != stack->owner); if (attack) { BOOST_LOG_TRIVIAL(debug) << "Attack!"; Point target_point = attack_target->position; Point attacking_point = end_pos; Battle battle(game, target_point, attacking_point); battle.run(); emit(create_message(DoBattle, end_stack_id, target_point, battle.moves)); } } break; case FactionReady: { auto cmd = dynamic_cast<FactionReadyMessage *>(command); int faction_id = cmd->data1; bool ready = cmd->data2; if (game->mark_faction_ready(faction_id, ready)) { emit(create_message(FactionReady, faction_id, ready)); } if (game->all_factions_ready()) { emit(create_message(TurnEnd)); // process turn end spawn_units(); game->turn_number++; emit(create_message(TurnBegin, game->turn_number)); } } break; case Chat: { auto chat_msg = dynamic_cast<ChatMessage *>(command); emit(create_message(Chat, chat_msg->data)); } break; case SetLevelData: case CreateStructure: case DestroyStructure: { emit(command->shared_from_this()); } break; default: break; } }