DynamicActivity::DynamicActivity(const uint32_t& aid, StaticActivity* fromActivity, StaticActivity* toActivity, const ProjectParameters& par) : Activity(aid, MOVEMENT) { vector<pair<uint32_t,uint32_t> > movements; size_t s1 = fromActivity->locations().size(); size_t s2 = toActivity->locations().size(); for (uint32_t i = 0; i < s1; ++i) for (uint32_t j = 0; j < s2; ++j) movements.emplace_back(i,j); shuffle(movements.begin(), movements.end(), generator); vector<bool> fromCovered(s1, false), toCovered(s2, false); for (const auto& c : movements) { Movement *mv = new Movement(fromActivity->locations()[c.first]->point(), toActivity->locations()[c.second]->point(), par); mMinAbsDuration = min(mMinAbsDuration, mv->minDuration()); mMaxAbsDuration = max(mMaxAbsDuration, mv->maxDuration()); mMovements.push_back(mv); fromCovered[c.first] = true; toCovered[c.second] = true; if (count(fromCovered.cbegin(), fromCovered.cend(), false) + count(toCovered.cbegin(), toCovered.cend(), false) == 0) break; } fromActivity->addSuccessor(this); toActivity->addPredecessor(this); addSuccessor(toActivity); addPredecessor(fromActivity); }
DynamicActivity* XmlReader::processDynamicActivityNode(const Node *node) { const Element *activityElement = castToElement(node); DynamicActivity *dynamicActivity = new DynamicActivity(stoul(getAttribute(activityElement, "aid"))); dynamicActivity->name(getTextFromElement(activityElement, "name", false)); dynamicActivity->description(getTextFromElement(activityElement, "desc", false)); double minDuration = F64_MAX, maxDuration = F64_MIN; const Element *movements = castToElement(activityElement->get_first_child("movements")); string a1 = getAttribute(movements, "from_aid", false), a2 = getAttribute(movements, "to_aid", false); int64_t fromActivity = (a1.empty() ? -1 : stol(a1)), toActivity = (a2.empty() ? -1 : stol(a2)); const NodeSet movementSet = movements->find("movement"); for (const Node *movementNode : movementSet) { const Element *movementElement = castToElement(movementNode); Movement *mv = new Movement(stoul(getAttribute(movementElement, "mid"))); mv->minDuration(stod(getTextFromElement(movementElement, "min-duration"))); mv->maxDuration(stod(getTextFromElement(movementElement, "max-duration"))); if (mv->minDuration() < TIME_ERR) { string mid = to_string(mv->mid()); delete dynamicActivity; delete mv; throw InvalidDatasetFile(caller(), "Dynamic activity's movement "+mid+" must have positive duration!", movementNode->get_line()); } // Workaround the incapability of ILP solvers to solve the problem with the fixed variables. if (abs(mv->maxDuration()-mv->minDuration()) < TIME_ERR) mv->maxDuration(mv->minDuration()+TIME_ERR); const NodeSet monomials = movementElement->find("energy-function/monomial"); for (const Node *monomialNode : monomials) { const Element *monomialElement = castToElement(monomialNode); int32_t degree = stoi(getAttribute(monomialElement, "degree")); double coeff = stod(getAttribute(monomialElement, "coeff")); mv->addMonomial({degree, coeff}); } uint32_t fromPoint = stoul(getTextFromElement(movementElement, "from-point")); uint32_t toPoint = stoul(getTextFromElement(movementElement, "to-point")); Location *locFrom = nullptr, *locTo = nullptr; StaticActivity *actFrom = nullptr, *actTo = nullptr; auto fSit = mPointToLocation.find(fromPoint), tSit = mPointToLocation.find(toPoint); if (fSit == mPointToLocation.cend() || tSit == mPointToLocation.cend()) { delete dynamicActivity; delete mv; throw InvalidDatasetFile(caller(), "Dynamic activity's point is not linked with any static activity!", movementNode->get_line()); } else { locFrom = fSit->second; locTo = tSit->second; assert(locFrom != nullptr && locTo != nullptr && "Unexpected null pointers!"); actFrom = locFrom->parent(); actTo = locTo->parent(); assert(actFrom != nullptr && actTo != nullptr && "Should not be nullptr as it has been set in processRobotNode method!"); } if ((actFrom->aid() != fromActivity && fromActivity != -1) || (actTo->aid() != toActivity && toActivity != -1)) { delete dynamicActivity; delete mv; throw InvalidDatasetFile(caller(), "Optional attributes 'from_aid' and/or 'to_aid' are invalid!", movementNode->get_line()); } minDuration = min(minDuration, mv->minDuration()); maxDuration = max(maxDuration, mv->maxDuration()); setValue(mMovementToPoints, mv, {fromPoint, toPoint}, caller()); dynamicActivity->addMovement(mv); } dynamicActivity->minAbsDuration(minDuration); dynamicActivity->maxAbsDuration(maxDuration); return dynamicActivity; }