public void changeWorkingSolution()

in use-cases/vaccination-scheduling/src/main/java/org/acme/vaccinationscheduler/solver/optional/VaccinationCustomConstructionHeuristic.java [29:79]


    public void changeWorkingSolution(ScoreDirector<VaccinationSolution> scoreDirector) {
        VaccinationSolution schedule = scoreDirector.getWorkingSolution();

        // Index the VaccinationSlot instances by vaccinationCenter, vaccineType and date
        Map<VaccinationCenter, Map<VaccineType, Map<LocalDate, Map<VaccinationSlot, Integer>>>> vaccinationCenterToSlotMap
                = schedule.getVaccinationSlotList().stream()
                .sorted(Comparator
                        .comparing((VaccinationSlot vaccinationSlot) -> vaccinationSlot.getVaccineType().getName())
                        .thenComparing(VaccinationSlot::getDate)
                        .thenComparing(VaccinationSlot::getStartTime))
                .collect(groupingBy(VaccinationSlot::getVaccinationCenter, LinkedHashMap::new,
                        groupingBy(VaccinationSlot::getVaccineType, LinkedHashMap::new,
                                groupingBy(VaccinationSlot::getDate,
                                        LinkedHashMap::new, Collectors.toMap(
                                                vaccinationSlot -> vaccinationSlot, VaccinationSlot::getCapacity,
                                                (key, value) -> {
                                                    throw new IllegalStateException("Duplicate key (" + key + ").");
                                                },
                                                LinkedHashMap::new)))));
        schedule.getPersonAssignmentList().stream()
                .filter(person -> person.getVaccinationSlot() != null)
                .forEach(person ->  {
            VaccinationSlot vaccinationSlot = person.getVaccinationSlot();
            VaccinationCenter vaccinationCenter = vaccinationSlot.getVaccinationCenter();
            Map<VaccineType, Map<LocalDate, Map<VaccinationSlot, Integer>>> vaccineTypeToSlotMap
                    = vaccinationCenterToSlotMap.get(vaccinationCenter);
            VaccineType vaccineType = vaccinationSlot.getVaccineType();
            Map<LocalDate, Map<VaccinationSlot, Integer>> dateToSlotMap = vaccineTypeToSlotMap.get(vaccineType);
            LocalDate date = vaccinationSlot.getDate();
            Map<VaccinationSlot, Integer> slotToAvailabilityMap = dateToSlotMap.get(date);
            int availability = slotToAvailabilityMap.get(vaccinationSlot);
            reduceAvailability(vaccinationCenterToSlotMap, vaccinationCenter,
                    vaccineTypeToSlotMap, vaccineType,
                    dateToSlotMap, date,
                    slotToAvailabilityMap, vaccinationSlot,
                    availability);
        });
        List<PersonAssignment> personList = schedule.getPersonAssignmentList().stream()
                .filter(person -> !person.isPinned() && person.getVaccinationSlot() == null)
                .sorted(new PersonAssignmentDifficultyComparator().reversed())
                .collect(Collectors.toList());
        for (PersonAssignment person : personList) {
            VaccinationSlot vaccinationSlot = findAvailableVaccinationSlot(scoreDirector, vaccinationCenterToSlotMap, person);
            if (vaccinationSlot != null) {
                scoreDirector.beforeVariableChanged(person, "vaccinationSlot");
                person.setVaccinationSlot(vaccinationSlot);
                scoreDirector.afterVariableChanged(person, "vaccinationSlot");
                scoreDirector.triggerVariableListeners();
            }
        }
    }