<?xml version="1.0" encoding="UTF-8"?>
<plannerBenchmark xmlns="https://timefold.ai/xsd/benchmark" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="https://timefold.ai/xsd/benchmark https://timefold.ai/xsd/benchmark/benchmark.xsd">
  <benchmarkDirectory>local/data/general</benchmarkDirectory>
  <parallelBenchmarkCount>6</parallelBenchmarkCount>
  <warmUpMinutesSpentLimit>1</warmUpMinutesSpentLimit>

  <inheritedSolverBenchmark>
    <solver>
      <environmentMode>REPRODUCIBLE</environmentMode>
      <termination>
        <minutesSpentLimit>5</minutesSpentLimit>
      </termination>
    </solver>
  </inheritedSolverBenchmark>

  <solverBenchmark>
    <name>Machine Reassignment</name>
    <solver>
      <solutionClass>ai.timefold.solver.examples.machinereassignment.domain.MachineReassignment</solutionClass>
      <entityClass>ai.timefold.solver.examples.machinereassignment.domain.MrProcessAssignment</entityClass>
      <scoreDirectorFactory>
        <constraintProviderClass>ai.timefold.solver.examples.machinereassignment.score.MachineReassignmentConstraintProvider</constraintProviderClass>
      </scoreDirectorFactory>
      <customPhase>
        <customPhaseCommandClass>ai.timefold.solver.examples.machinereassignment.solver.solution.initializer.ToOriginalMachineSolutionInitializer</customPhaseCommandClass>
      </customPhase>
      <localSearch>
        <unionMoveSelector>
          <changeMoveSelector/>
          <swapMoveSelector/>
        </unionMoveSelector>
        <acceptor>
          <entityTabuSize>7</entityTabuSize>
        </acceptor>
        <forager>
          <acceptedCountLimit>2000</acceptedCountLimit>
        </forager>
      </localSearch>
    </solver>
    <problemBenchmarks>
      <solutionFileIOClass>ai.timefold.solver.examples.machinereassignment.persistence.MachineReassignmentFileIO</solutionFileIOClass>
      <inputSolutionFile>data/machinereassignment/import/model_a2_3.txt</inputSolutionFile>
    </problemBenchmarks>
  </solverBenchmark>
  <solverBenchmark>
    <name>Conference Scheduling</name>
    <solver>
      <solutionClass>ai.timefold.solver.examples.conferencescheduling.domain.ConferenceSolution</solutionClass>
      <entityClass>ai.timefold.solver.examples.conferencescheduling.domain.Talk</entityClass>
      <scoreDirectorFactory>
        <constraintProviderClass>ai.timefold.solver.examples.conferencescheduling.score.ConferenceSchedulingConstraintProvider</constraintProviderClass>
      </scoreDirectorFactory>
      <constructionHeuristic/>
      <localSearch>
        <localSearchType>TABU_SEARCH</localSearchType>
      </localSearch>
    </solver>
    <problemBenchmarks>
      <solutionFileIOClass>ai.timefold.solver.examples.conferencescheduling.persistence.ConferenceSchedulingXlsxFileIO</solutionFileIOClass>
      <inputSolutionFile>data/conferencescheduling/unsolved/216talks-18timeslots-20rooms.xlsx</inputSolutionFile>
    </problemBenchmarks>
  </solverBenchmark>
  <solverBenchmark>
    <name>Nurse Rostering</name>
    <solver>
      <solutionClass>ai.timefold.solver.examples.nurserostering.domain.NurseRoster</solutionClass>
      <entityClass>ai.timefold.solver.examples.nurserostering.domain.ShiftAssignment</entityClass>
      <scoreDirectorFactory>
        <constraintProviderClass>ai.timefold.solver.examples.nurserostering.score.NurseRosteringConstraintProvider</constraintProviderClass>
      </scoreDirectorFactory>
      <constructionHeuristic>
        <constructionHeuristicType>WEAKEST_FIT</constructionHeuristicType>
      </constructionHeuristic>
      <localSearch>
        <unionMoveSelector>
          <moveListFactory>
            <cacheType>STEP</cacheType>
            <moveListFactoryClass>ai.timefold.solver.examples.nurserostering.solver.move.factory.ShiftAssignmentPillarPartSwapMoveFactory</moveListFactoryClass>
          </moveListFactory>
          <changeMoveSelector>
            <entitySelector>
              <filterClass>ai.timefold.solver.examples.nurserostering.domain.solver.MovableShiftAssignmentSelectionFilter</filterClass>
            </entitySelector>
          </changeMoveSelector>
          <swapMoveSelector>
            <entitySelector>
              <filterClass>ai.timefold.solver.examples.nurserostering.domain.solver.MovableShiftAssignmentSelectionFilter</filterClass>
            </entitySelector>
          </swapMoveSelector>
          <pillarChangeMoveSelector>
            <subPillarType>SEQUENCE</subPillarType>
            <pillarSelector>
              <entitySelector>
                <filterClass>ai.timefold.solver.examples.nurserostering.domain.solver.MovableShiftAssignmentSelectionFilter</filterClass>
              </entitySelector>
            </pillarSelector>
          </pillarChangeMoveSelector>
          <pillarSwapMoveSelector>
            <subPillarType>SEQUENCE</subPillarType>
            <pillarSelector>
              <entitySelector>
                <filterClass>ai.timefold.solver.examples.nurserostering.domain.solver.MovableShiftAssignmentSelectionFilter</filterClass>
              </entitySelector>
            </pillarSelector>
          </pillarSwapMoveSelector>
        </unionMoveSelector>
        <acceptor>
          <entityTabuSize>7</entityTabuSize>
        </acceptor>
        <forager>
          <acceptedCountLimit>800</acceptedCountLimit>
        </forager>
      </localSearch>
    </solver>
    <problemBenchmarks>
      <solutionFileIOClass>ai.timefold.solver.examples.nurserostering.persistence.NurseRosterSolutionFileIO</solutionFileIOClass>
      <inputSolutionFile>data/nurserostering/unsolved/medium_late01.json</inputSolutionFile>
    </problemBenchmarks>
  </solverBenchmark>
  <solverBenchmark>
    <name>TSP</name>
    <solver>
      <solutionClass>ai.timefold.solver.examples.tsp.domain.TspSolution</solutionClass>
      <entityClass>ai.timefold.solver.examples.tsp.domain.Visit</entityClass>
      <scoreDirectorFactory>
        <constraintProviderClass>ai.timefold.solver.examples.tsp.score.TspConstraintProvider</constraintProviderClass>
        <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
      </scoreDirectorFactory>
      <constructionHeuristic>
        <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
      </constructionHeuristic>
      <localSearch>
        <unionMoveSelector>
          <changeMoveSelector/>
          <swapMoveSelector />
          <subChainChangeMoveSelector>
            <subChainSelector>
              <maximumSubChainSize>40</maximumSubChainSize>
            </subChainSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
          </subChainChangeMoveSelector>
        </unionMoveSelector>
      </localSearch>
    </solver>
    <problemBenchmarks>
      <solutionFileIOClass>ai.timefold.solver.examples.tsp.persistence.TspSolutionFileIO</solutionFileIOClass>
      <inputSolutionFile>data/tsp/unsolved/lu980.json</inputSolutionFile>
    </problemBenchmarks>
  </solverBenchmark>
  <solverBenchmark>
    <name>Vehicle Routing</name>
    <solver>
      <solutionClass>ai.timefold.solver.examples.vehiclerouting.domain.VehicleRoutingSolution</solutionClass>
      <entityClass>ai.timefold.solver.examples.vehiclerouting.domain.Vehicle</entityClass>
      <entityClass>ai.timefold.solver.examples.vehiclerouting.domain.Customer</entityClass>
      <entityClass>ai.timefold.solver.examples.vehiclerouting.domain.timewindowed.TimeWindowedCustomer</entityClass>
      <scoreDirectorFactory>
        <constraintProviderClass>ai.timefold.solver.examples.vehiclerouting.score.VehicleRoutingConstraintProvider</constraintProviderClass>
        <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
      </scoreDirectorFactory>
      <constructionHeuristic />
      <localSearch>
        <unionMoveSelector>
          <listChangeMoveSelector />
          <listSwapMoveSelector />
          <subListChangeMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
          </subListChangeMoveSelector>
          <subListSwapMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
          </subListSwapMoveSelector>
          <kOptListMoveSelector />
          <listChangeMoveSelector>
            <valueSelector id="1"/>
            <destinationSelector>
              <nearbySelection>
                <originValueSelector mimicSelectorRef="1"/>
                <nearbyDistanceMeterClass>ai.timefold.solver.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                <nearbySelectionDistributionType>PARABOLIC_DISTRIBUTION</nearbySelectionDistributionType>
                <parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
              </nearbySelection>
            </destinationSelector>
          </listChangeMoveSelector>
          <listSwapMoveSelector>
            <valueSelector id="2"/>
            <secondaryValueSelector>
              <nearbySelection>
                <originValueSelector mimicSelectorRef="2"/>
                <nearbyDistanceMeterClass>ai.timefold.solver.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                <nearbySelectionDistributionType>PARABOLIC_DISTRIBUTION</nearbySelectionDistributionType>
                <parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
              </nearbySelection>
            </secondaryValueSelector>
          </listSwapMoveSelector>
          <subListChangeMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
            <subListSelector id="3"/>
            <destinationSelector>
              <nearbySelection>
                <originSubListSelector mimicSelectorRef="3"/>
                <nearbyDistanceMeterClass>ai.timefold.solver.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                <nearbySelectionDistributionType>PARABOLIC_DISTRIBUTION</nearbySelectionDistributionType>
                <parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
              </nearbySelection>
            </destinationSelector>
          </subListChangeMoveSelector>
          <subListSwapMoveSelector>
            <selectReversingMoveToo>true</selectReversingMoveToo>
            <subListSelector id="4"/>
            <secondarySubListSelector>
              <nearbySelection>
                <originSubListSelector mimicSelectorRef="4"/>
                <nearbyDistanceMeterClass>ai.timefold.solver.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                <nearbySelectionDistributionType>PARABOLIC_DISTRIBUTION</nearbySelectionDistributionType>
                <parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
              </nearbySelection>
            </secondarySubListSelector>
          </subListSwapMoveSelector>
          <kOptListMoveSelector>
            <originSelector id="5"/>
            <valueSelector>
              <nearbySelection>
                <originValueSelector mimicSelectorRef="5"/>
                <nearbyDistanceMeterClass>ai.timefold.solver.examples.vehiclerouting.domain.solver.nearby.CustomerNearbyDistanceMeter</nearbyDistanceMeterClass>
                <nearbySelectionDistributionType>PARABOLIC_DISTRIBUTION</nearbySelectionDistributionType>
                <parabolicDistributionSizeMaximum>40</parabolicDistributionSizeMaximum>
              </nearbySelection>
            </valueSelector>
          </kOptListMoveSelector>
        </unionMoveSelector>
      </localSearch>
    </solver>
    <problemBenchmarks>
      <solutionFileIOClass>ai.timefold.solver.examples.vehiclerouting.persistence.VehicleRoutingSolutionFileIO</solutionFileIOClass>
      <inputSolutionFile>data/vehiclerouting/unsolved/belgium-tw-n2750-k55.json</inputSolutionFile>
    </problemBenchmarks>
  </solverBenchmark>
</plannerBenchmark>
