/* amodeus - Copyright (c) 2018, ETH Zurich, Institute for Dynamic Systems and Control */ package amodeus.amodeus.prep; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Random; import org.matsim.amodeus.config.AmodeusModeConfig; import org.matsim.api.core.v01.population.Person; import org.matsim.api.core.v01.population.Population; import amodeus.amodeus.util.math.GlobalAssert; public final class TheRequestApocalypse { /** the seed is deliberately public */ public static final long DEFAULT_SEED = 7582456789L; public static TheRequestApocalypse reducesThe(Population population) { return new TheRequestApocalypse(population); } // --- private final Population population; private TheRequestApocalypse(Population population) { this.population = population; } public TheRequestApocalypse toNoMoreThan(int maxRequests) { return toNoMoreThan(maxRequests, DEFAULT_SEED); } public TheRequestApocalypse toNoMoreThan(int maxRequests, long seed) { final long legCount = LegCount.of(population, AmodeusModeConfig.DEFAULT_MODE); GlobalAssert.that(maxRequests <= legCount); if (legCount == maxRequests) return this; /** shuffle list of {@link Person}s */ List<Person> list = new ArrayList<>(population.getPersons().values()); Collections.shuffle(list, new Random(seed)); Iterator<Person> iterator = list.iterator(); // skip all persons that should completely remain in the population Person person = iterator.next(); int totReq = 0; long req = LegCount.of(person, AmodeusModeConfig.DEFAULT_MODE); while (totReq + req <= maxRequests) { totReq += req; person = iterator.next(); req = LegCount.of(person, AmodeusModeConfig.DEFAULT_MODE); } // create new person if needed to fill requests int split = maxRequests - totReq; if (split != 0) { Person splitPerson = SplitUp.of(population, person, split, AmodeusModeConfig.DEFAULT_MODE); req = LegCount.of(splitPerson, AmodeusModeConfig.DEFAULT_MODE); totReq += req; GlobalAssert.that(totReq == maxRequests); population.addPerson(splitPerson); } // remove all remaining persons iterator.forEachRemaining(p -> population.removePerson(p.getId())); population.removePerson(person.getId()); GlobalAssert.that(LegCount.of(population, AmodeusModeConfig.DEFAULT_MODE) == maxRequests); return this; } public final void requests() { System.out.println("Population size: " + population.getPersons().values().size()); } }