void Individual::splitExtractWithoutVehicleLimit(vector<int>& P) {

    int n = this->getGene().size();

    int p = 0, t = 0, j = n, i, k, id = 0;

    // Depot
    //--trip.push_back(ROUTE_DELIM);
    p++;

    // Repeat
    do {

        t++;
        i = P.at(j);

        Route route = Route(this->getProblem(), this->getConfig(), this->getDepot(), id);
        id++;

        for (k = i; k < j; ++k) {
            //--trip.push_back(route.at(k));
            route.getTour().push_back(this->getGene().at(k));
        }

        route.calculateCost();
        this->getRoutes().push_back(route);

        // Depot
        //--trip.push_back(ROUTE_DELIM);
        j = i;

    } while (i > 0);

}
bool LocalSearch::processMoveDepotRoute(Route& ru, Route& rv, int move, bool equal) {

    Route newRu = ru;
    Route newRv = rv;

    bool result = operateMoveDepotRouteFacade(newRu, newRv, move, equal);

    //--float costU = newRu.getTotalCost();
    //--float costV = newRv.getTotalCost();

    //--Route oldRu = newRu;
    //--Route oldRv = newRv;

    //    if (result) {
    newRu.calculateCost();
    if (!equal) newRv.calculateCost();
    //    }

    //--float diffU = fabsf(Util::calculateGAP(Util::scaledFloat(costU), Util::scaledFloat(newRu.getTotalCost())));
    //--float diffV = fabsf(Util::calculateGAP(Util::scaledFloat(costV), Util::scaledFloat(newRv.getTotalCost())));

    //--
    /*if ((diffU > 1.00 || diffV > 1.00)) {
            std::cout << "MOVE: " << move << " -> Cost Old != New -> Equal: " << equal << 
                    " - Diff U: " << diffU << " - Diff V: " << diffV << std::endl;
    }*/
    // --

    if (Util::isBetterSolution(newRu.getTotalCost() + newRv.getTotalCost(), ru.getTotalCost() + rv.getTotalCost())) {
        ru = newRu;
        if (!equal) rv = newRv;
        result = true;
    } else
        result = false;

    return result;
}
void Individual::splitExtractVehicleLimited(vector<int>& P) {

    int n = this->getGene().size();

    int p = 0, t = 0, j = n, i, k, id = 0;

    // Depot
    //--trip.push_back(ROUTE_DELIM);
    p++;

    // Repeat
    do {

        t++;
        i = P.at(j);

        // If the number of routes is less than the number of vehicles
        if (id < this->getProblem()->getVehicles()) {

            Route route = Route(this->getProblem(), this->getConfig(), this->getDepot(), id);
            id++;

            for (k = i; k < j; ++k) {
                //--trip.push_back(route.at(k));
                route.getTour().push_back(this->getGene().at(k));
            }

            route.calculateCost();
            this->getRoutes().push_back(route);

        } else {
            // Put in the last route
            for (k = i; k < j; ++k)
                this->getRoutes().at(this->getProblem()->getVehicles() - 1).addAtBack(this->getGene().at(k));
        }

        // Depot
        //--trip.push_back(ROUTE_DELIM);
        j = i;

    } while (i > 0);
}
bool LocalSearch::operateMoveDepotRouteM4(Route& ru, Route& rv, bool equal) {

    bool result = false;
    float costBefore, costAfter, b, a;
    int demand;

    if (equal) {

        for (auto iterRU = ru.getTour().begin(); iterRU != ru.getTour().end(); ++iterRU) {
            for (auto iterRV = ru.getTour().begin(); iterRV != ru.getTour().end(); ++iterRV) {

                if ((*iterRU) == (*iterRV))
                    continue;

                //ru.printSolution();
                if (next(iterRV) == ru.getTour().end() || ru.getProblem()->getGranularNeighborhood().at((*iterRU) - 1).at((*next(iterRV)) - 1) == 1) {

                    costBefore = ru.calculateCost(iterRU, next(iterRU), demand);
                    costBefore += ru.calculateCost(iterRV, next(iterRV), demand);
                    //b = ru.getTotalCost();
                    std::swap((*iterRU), (*iterRV));

                    costAfter = ru.calculateCost(iterRU, next(iterRU), demand);
                    costAfter += ru.calculateCost(iterRV, next(iterRV), demand);

                    //printf("Change: \t%d\t%d\n", (*iterRU), (*iterRV));
                    //ru.printSolution();

                    //ru.calculateCost();
                    //a = ru.getTotalCost();

                    if (Util::isBetterSolution(costAfter, costBefore)) {
                        //if (Util::isBetterSolution(a, b)) {
                        //ru.calculateCost();
                        result = true;
                        //cout << "Improved \n";
                        break;
                    }
                    else {
                        std::swap((*iterRU), (*iterRV));
                        //newRU.printSolution();
                        //cout << endl;
                    }
                }

                if (ru.getProblem()->getMonitor().isTerminated())
                    break;

            }

            //cout << "END\n";

            if (result)
                break;

            if (ru.getProblem()->getMonitor().isTerminated())
                break;

        }

    } else {

        for (auto iterRU = ru.getTour().begin(); iterRU != ru.getTour().end(); ++iterRU) {
            for (auto iterRV = rv.getTour().begin(); iterRV != rv.getTour().end(); ++iterRV) {

                demand = rv.getDemand() - rv.getProblem()->getDemand().at((*iterRV) - 1) + rv.getProblem()->getDemand().at((*iterRU) - 1);
                if (demand > rv.getProblem()->getCapacity())
                    continue;

                demand = ru.getDemand() - ru.getProblem()->getDemand().at((*iterRU) - 1) + ru.getProblem()->getDemand().at((*iterRV) - 1);
                if (demand > rv.getProblem()->getCapacity())
                    continue;

                //ru.printSolution();

                if (next(iterRV) == rv.getTour().end() || ru.getProblem()->getGranularNeighborhood().at((*iterRU) - 1).at((*next(iterRV)) - 1) == 1) {

                    costBefore = ru.calculateCost(iterRU, next(iterRU), demand);
                    costBefore += rv.calculateCost(iterRV, next(iterRV), demand);
                    b = ru.getTotalCost() + rv.getTotalCost();
                    std::swap((*iterRU), (*iterRV));

                    costAfter = ru.calculateCost(iterRU, next(iterRU), demand);
                    costAfter += rv.calculateCost(iterRV, next(iterRV), demand);

                    ru.calculateCost();
                    rv.calculateCost();
                    a = ru.getTotalCost() + rv.getTotalCost();

                    //ru.printSolution();

                    //if (Util::isBetterSolution(costAfter, costBefore)) {
                    if (Util::isBetterSolution(a, b)) {
                        //ru.calculateCost();
                        //rv.calculateCost();
                        result = true;
                        //cout << "Improved \n";
                        break;
                    }
                    else {
                        std::swap((*iterRU), (*iterRV));
                        ru.calculateCost();
                        rv.calculateCost();

                        //newRU.printSolution();
                        //cout << endl;
                    }
                }

                if (ru.getProblem()->getMonitor().isTerminated())
                    break;

            }

            if (result)
                break;

            if (ru.getProblem()->getMonitor().isTerminated())
                break;

        }
    }

    return result;
}