/*! \param[in] pred The node preceding this node (in the path). \param[in] cargoLimit The cargo limit of the vehicle. */ void Vehicle_node::evaluate(const Vehicle_node &pred, double cargoLimit) { /* time */ m_travel_time = pred.travel_time_to(*this); m_arrival_time = pred.departure_time() + travel_time(); m_wait_time = is_early_arrival(arrival_time()) ? opens() - m_arrival_time : 0; m_departure_time = arrival_time() + wait_time() + service_time(); /* time aggregates */ m_tot_travel_time = pred.total_travel_time() + travel_time(); m_tot_wait_time = pred.total_wait_time() + wait_time(); m_tot_service_time = pred.total_service_time() + service_time(); /* cargo aggregates */ if (is_dump() && pred.cargo() >= 0) { m_demand = -pred.cargo(); } m_cargo = pred.cargo() + demand(); /* cargo aggregates */ m_twvTot = has_twv() ? pred.twvTot() + 1 : pred.twvTot(); m_cvTot = has_cv(cargoLimit) ? pred.cvTot() + 1 : pred.cvTot(); m_delta_time = departure_time() - pred.departure_time(); }
void Vehicle_pickDeliver::push_front(const Order &order) { invariant(); pgassert(!has_order(order)); orders_in_vehicle.insert(order.id()); m_path.insert(m_path.begin() + 1, order.delivery()); m_path.insert(m_path.begin() + 1, order.pickup()); evaluate(1); pgassert(has_order(order)); pgassert(!has_cv()); invariant(); }
void Vehicle_pickDeliver::push_back(const Order &order) { invariant(); pgassert(!has_order(order)); orders_in_vehicle.insert(order.id()); m_path.insert(m_path.end() - 1, order.pickup()); m_path.insert(m_path.end() - 1, order.delivery()); evaluate(m_path.size() - 3); pgassert(has_order(order)); pgassert(!has_cv()); invariant(); }
/*! * \param[in] cargoLimit of the vehicle */ void Vehicle_node::evaluate(double cargoLimit) { if (is_start()) { /* time */ m_travel_time = 0; m_arrival_time = opens(); m_wait_time = 0; m_departure_time = arrival_time() + service_time(); /* time aggregates */ m_tot_travel_time = 0; m_tot_wait_time = 0; m_tot_service_time = service_time(); /* cargo aggregates */ m_cargo = demand(); /* violation aggregates */ m_twvTot = m_cvTot = 0; m_cvTot = has_cv(cargoLimit) ? 1 : 0; m_delta_time = 0; } }
void Vehicle_pickDeliver::insert(const Order &order) { invariant(); pgassert(!has_order(order)); auto pick_pos(position_limits(order.pickup())); auto deliver_pos(position_limits(order.delivery())); #ifndef NDEBUG std::ostringstream err_log; err_log << "\n\tpickup limits (low, high) = (" << pick_pos.first << ", " << pick_pos.second << ") " << "\n\tdeliver limits (low, high) = (" << deliver_pos.first << ", " << deliver_pos.second << ") " << "\noriginal" << tau(); #endif if (pick_pos.second < pick_pos.first) { /* pickup generates twv evrywhere, * so put the order as last */ push_back(order); return; } if (deliver_pos.second < deliver_pos.first) { /* delivery generates twv evrywhere, * so put the order as last */ push_back(order); return; } /* * Because delivery positions were estimated without * the pickup: * - increase the upper limit position estimation */ ++deliver_pos.second; auto d_pos_backup(deliver_pos); auto best_pick_pos = m_path.size(); auto best_deliver_pos = m_path.size() + 1; auto current_duration(duration()); auto min_delta_duration = (std::numeric_limits<double>::max)(); auto found(false); pgassertwm(!has_order(order), err_log.str()); while (pick_pos.first <= pick_pos.second) { #ifndef NDEBUG err_log << "\n\tpickup cycle limits (low, high) = (" << pick_pos.first << ", " << pick_pos.second << ") "; #endif Vehicle::insert(pick_pos.first, order.pickup()); #ifndef NDEBUG err_log << "\npickup inserted: " << tau(); #endif while (deliver_pos.first <= deliver_pos.second) { Vehicle::insert(deliver_pos.first, order.delivery()); orders_in_vehicle.insert(order.id()); pgassertwm(has_order(order), err_log.str()); #ifndef NDEBUG err_log << "\ndelivery inserted: " << tau(); #endif if (is_feasable()) { pgassert(is_feasable()); auto delta_duration = duration()-current_duration; if (delta_duration < min_delta_duration) { #ifndef NDEBUG err_log << "\nsuccess" << tau(); #endif min_delta_duration = delta_duration; best_pick_pos = pick_pos.first; best_deliver_pos = deliver_pos.first; found = true; } } Vehicle::erase(deliver_pos.first); #ifndef NDEBUG err_log << "\ndelivery erased: " << tau(); #endif ++deliver_pos.first; } Vehicle::erase(pick_pos.first); #ifndef NDEBUG err_log << "\npickup erased: " << tau(); #endif orders_in_vehicle.erase(order.id()); pgassertwm(!has_order(order), err_log.str()); deliver_pos = d_pos_backup; #ifndef NDEBUG err_log << "\n\trestoring deliver limits (low, high) = (" << deliver_pos.first << ", " << deliver_pos.second << ") "; #endif ++pick_pos.first; } pgassertwm(!has_order(order), err_log.str()); if (!found) { /* order causes twv * so put the order as last */ push_back(order); return; } Vehicle::insert(best_pick_pos, order.pickup()); Vehicle::insert(best_deliver_pos, order.delivery()); orders_in_vehicle.insert(order.id()); pgassertwm(is_feasable(), err_log.str()); pgassertwm(has_order(order), err_log.str()); pgassertwm(!has_cv(), err_log.str()); invariant(); }