Esempio n. 1
0
NearestSpotList SpotSearch::findNearestSpots(const Instance& tour, int tournode, unsigned int k, bool skipUsed)
{
    unsigned spot = tour.getSpotIndex(tournode);

    std::vector<unsigned>* nearest = nearestSpots[spot+1];

    // return a vector containing the first k entries
    if (k > nearest->size()) k = nearest->size();

    NearestSpotList pairs;

    if (skipUsed) {
        pairs.reserve(k);
        for (unsigned nearestspot : *nearest) {
            if (tour.containsSpot(nearestspot)) continue;

            pairs.push_back( std::make_pair(tournode, nearestspot) );

            if (pairs.size() >= k) break;
        }
    } else {
        pairs.resize(k);
        std::transform(nearest->begin(), nearest->begin() + k, pairs.begin(),
        [tournode](unsigned ns) {
            return std::make_pair(tournode, ns);
        } );
    }

    return pairs;
}
Esempio n. 2
0
NearestSpotList SpotSearch::findNearestTourSpots(const Instance& tour, unsigned int k, bool uniqueSpots, bool skipUsed)
{
    NearestSpotList nearest;
    nearest.reserve(k);

    std::vector<double> dist;
    dist.reserve(k);

    std::set<unsigned> foundSpots;

    // initialize with nearest spots to hotel
    nearest = findNearestSpots(tour, -1, k, skipUsed);
    for (const auto& spot : nearest) {
        if (uniqueSpots) foundSpots.insert(spot.second);
        dist.push_back(problem.getDistance(problem.getStartAsSpot(), problem.getSpot(spot.second)));
    }

    // keep track of the maximum distance of the k neighbors found so far
    double maxDist = dist.back();

    int tourIndex = 0;
    for(const auto& node : tour.getTour()) {
        // get k nearest spots for every node in the tour, compare with current nearest spots
        std::vector<unsigned>* spots = nearestSpots[node.spot+1];

        for (unsigned spotIndex : *spots) {
            if (skipUsed && tour.containsSpot(spotIndex)) continue;
            if (uniqueSpots && !foundSpots.insert(spotIndex).second) continue;

            double spotDist = problem.getDistance(problem.getSpot(node.spot), problem.getSpot(spotIndex));

            // check if the list is already at size k. we can assume that if !skipUsed
            bool listFull = !skipUsed || dist.size() >= k;

            // All other spots will actually be further out, so we can stop looking
            // This will implicitly stop after at most k iterations, dist(spots[k]) will always be > maxDist!
            // (otherwise we would have added all k nearer spots to our list already)
            if (listFull && spotDist >= maxDist) break;

            // need to insert new spot into list.
            if (listFull) {
                nearest.pop_back();
                dist.pop_back();
            }

            auto distIt = std::upper_bound(dist.begin(), dist.end(), spotDist);

            dist.insert(distIt, spotDist);
            nearest.insert(nearest.begin() + (distIt - dist.begin()), std::make_pair(tourIndex, spotIndex));

            maxDist = dist.back();
        }

        tourIndex++;
    }

    return nearest;
}
Esempio n. 3
0
NearestSpot SpotSearch::findNearestSpot(const Instance& instance, int tournode, bool skipUsed)
{
    unsigned spot = instance.getSpotIndex(tournode);

    std::vector<unsigned>* nearest = nearestSpots[spot+1];

    for (unsigned nearestspot : *nearest) {
        if (skipUsed && instance.containsSpot(nearestspot)) continue;

        return std::make_pair(tournode,nearestspot);
    }
    // Should never be reached
    assert(false && "Trying to find nearest spot, but all spots are used");
    return std::make_pair(tournode,-1);
}
Esempio n. 4
0
NearestNodesList SpotSearch::findNearestTourNodes(const Instance& tour, unsigned int k)
{
    NearestNodesList nearest;
    nearest.reserve(k);

    std::vector<double> dist;
    dist.reserve(k);

    double maxDist = 0.0;

    int tourIndex = 0;
    for (const auto& node : tour.getTour()) {
        std::vector<unsigned>* spots = nearestSpots[node.spot+1];

        for (unsigned spotIndex : *spots) {
            // To avoid adding duplicate entries, only add pairs where first.spot < second.spot.
            if (node.spot > spotIndex) continue;

            // skip all spots that are not on the tour
            if (!tour.containsSpot(spotIndex)) continue;

            double spotDist = problem.getDistance(problem.getSpot(node.spot), problem.getSpot(spotIndex));

            if (dist.size() >= k && spotDist >= maxDist) break;

            // We need to get the index of the node in the tour for the nearest spot
            unsigned nearestnode = tour.getNodeIndex(spotIndex);

            if (dist.size() >= k) {
                nearest.pop_back();
                dist.pop_back();
            }

            auto distIt = std::upper_bound(dist.begin(), dist.end(), spotDist);

            dist.insert(distIt, spotDist);
            nearest.insert(nearest.begin() + (distIt - dist.begin()), std::make_pair(tourIndex, nearestnode));

            maxDist = dist.back();
        }

        tourIndex++;
    }

    return nearest;
}