void TraineeWalker::computeWalkerPath() { _maxNeed = 0; // need of this trainee in buildings Propagator pathPropagator; pathPropagator.init( *_originBuilding.object() ); pathPropagator.propagate(_maxDistance); for (std::list<BuildingType>::iterator itType = _buildingNeed.begin(); itType != _buildingNeed.end(); ++itType) { BuildingType buildingType = *itType; checkDestination(buildingType, pathPropagator); } if( _destinationBuilding != NULL ) { // some building needs that trainee! // std::cout << "trainee sent!" << std::endl; PathWay pathWay; pathPropagator.getPath( _destinationBuilding, pathWay); setPathWay( pathWay ); setIJ( _pathWay.getOrigin().getIJ() ); } else { // nobody needs him... // std::cout << "trainee suicide!" << std::endl; deleteLater(); } }
void TraineeWalker::computeWalkerPath() { _maxNeed = 0; // need of this trainee in buildings Propagator pathPropagator; pathPropagator.init(*_originBuilding); pathPropagator.propagate(_maxDistance); for (std::list<BuildingType>::iterator itType = _buildingNeed.begin(); itType != _buildingNeed.end(); ++itType) { BuildingType buildingType = *itType; checkDestination(buildingType, pathPropagator); } if (_destinationBuilding != NULL) { // some building needs that trainee! // std::cout << "trainee sent!" << std::endl; PathWay pathWay; pathPropagator.getPath(*_destinationBuilding, pathWay); setPathWay(pathWay); setIJ(_pathWay.getOrigin().getI(), _pathWay.getOrigin().getJ()); Scenario::instance().getCity().getWalkerList().push_back(this); _destinationBuilding->reserveTrainee(_traineeType); } else { // nobody needs him... // std::cout << "trainee suicide!" << std::endl; _isDeleted = true; } }
bool Engine::propagate() { if (async_fail) { async_fail = false; assert(!so.lazy || sat.confl); return false; } last_prop = NULL; WakeUp: if (!sat.consistent() && !sat.propagate()) return false; for (int i = 0; i < v_queue.size(); i++) { v_queue[i]->wakePropagators(); } v_queue.clear(); if (sat.confl) return false; last_prop = NULL; for (int i = 0; i < num_queues; i++) { if (p_queue[i].size()) { Propagator *p = p_queue[i].last(); p_queue[i].pop(); propagations++; bool ok = p->propagate(); p->clearPropState(); if (!ok) return false; goto WakeUp; } } return true; }
void CartPusher::computeWalkerDestination() { // get the list of buildings within reach PathWay pathWay; Propagator pathPropagator; _d->consumerBuilding = 0; pathPropagator.init( *_d->producerBuilding.object() ); pathPropagator.propagate(_d->maxDistance); BuildingPtr destBuilding; if (destBuilding == NULL) { // try send that good to a factory destBuilding = getWalkerDestination_factory(pathPropagator, pathWay); } if (destBuilding == NULL) { // try send that good to a granary destBuilding = getWalkerDestination_granary(pathPropagator, pathWay); } if (destBuilding == NULL) { // try send that good to a warehouse destBuilding = getWalkerDestination_warehouse( pathPropagator, pathWay ); } if( destBuilding != NULL) { //_isDeleted = true; // no destination! setConsumerBuilding( destBuilding ); setPathWay( pathWay ); setIJ( _pathWay.getOrigin().getIJ() ); setSpeed( 1 ); } else { _action._direction = D_NORTH; setSpeed( 0 ); setIJ( _d->producerBuilding->getAccessRoads().front()->getIJ() ); walk(); } }
SpaceStatus Space::status(StatusStatistics& stat) { SpaceStatus s = SS_FAILED; // Check whether space is failed if (failed()) { s = SS_FAILED; goto exit; } assert(pc.p.active <= &pc.p.queue[PropCost::AC_MAX+1]); // Check whether space is stable but not failed if (pc.p.active >= &pc.p.queue[0]) { Propagator* p; ModEventDelta med_o; goto unstable; execute: stat.propagate++; // Keep old modification event delta med_o = p->u.med; // Clear med but leave propagator in queue p->u.med = 0; switch (p->propagate(*this,med_o)) { case ES_FAILED: // Count failure if (afc_enabled()) gafc.fail(p->gafc); // Mark as failed fail(); s = SS_FAILED; goto exit; case ES_NOFIX: // Find next, if possible if (p->u.med != 0) { unstable: // There is at least one propagator in a queue do { assert(pc.p.active >= &pc.p.queue[0]); // First propagator or link back to queue ActorLink* fst = pc.p.active->next(); if (pc.p.active != fst) { p = Propagator::cast(fst); goto execute; } pc.p.active--; } while (true); GECODE_NEVER; } // Fall through case ES_FIX: // Clear med and put into idle queue p->u.med = 0; p->unlink(); pl.head(p); stable_or_unstable: // There might be a propagator in the queue do { assert(pc.p.active >= &pc.p.queue[0]); // First propagator or link back to queue ActorLink* fst = pc.p.active->next(); if (pc.p.active != fst) { p = Propagator::cast(fst); goto execute; } } while (--pc.p.active >= &pc.p.queue[0]); assert(pc.p.active < &pc.p.queue[0]); goto stable; case __ES_SUBSUMED: p->unlink(); rfree(p,p->u.size); goto stable_or_unstable; case __ES_PARTIAL: // Schedule propagator with specified propagator events assert(p->u.med != 0); enqueue(p); goto unstable; default: GECODE_NEVER; } } stable: /* * Find the next brancher that has still alternatives left * * It is important to note that branchers reporting to have no more * alternatives left cannot be deleted. They cannot be deleted * as there might be choices to be used in commit * that refer to one of these branchers. This e.g. happens when * we combine branch-and-bound search with adaptive recomputation: during * recomputation, a copy is constrained to be better than the currently * best solution, then the first half of the choices are posted, * and a fixpoint computed (for storing in the middle of the path). Then * the remaining choices are posted, and because of the additional * constraints that the space must be better than the previous solution, * the corresponding Branchers may already have no alternatives left. * * The same situation may arise due to weakly monotonic propagators. * * A brancher reporting that no more alternatives exist is exhausted. * All exhausted branchers will be left of the current pointer b_status. * Only when it is known that no more choices * can be used for commit an exhausted brancher can actually be deleted. * This becomes known when choice is called. */ while (b_status != Brancher::cast(&bl)) if (b_status->status(*this)) { // Brancher still has choices to generate s = SS_BRANCH; goto exit; } else { // Brancher is exhausted b_status = Brancher::cast(b_status->next()); } // No brancher with alternatives left, space is solved s = SS_SOLVED; exit: stat.wmp = (wmp() > 0U); if (wmp() == 1U) wmp(0U); return s; }