mikethecalamity / scheduleague

Scheduler for sports leagues provided various parameters
MIT License
1 stars 0 forks source link

Recommended Move Selector #3

Closed bjmyers closed 1 month ago

bjmyers commented 1 month ago

Looks like you're making the domain model such that the team assignment is your planning variable and the timeslot is associated to the entity (so timefold knows what all the timeslots are, it just swaps what teams are in that timeslot).

You know that you want each team to play the same number of games in total. So when you make a move, you want to swap a team from one entity to another (for example, TeamC was the away team in TimeSlot1 and TeamE was the home team in TimeSlot3, the swap move changes them so that TeamE is the away team in TimeSlot1 and TeamC is the home team in TimeSlot3).

If you just use a change move, then each move will affect the total number of games played (you would change TeamC to TeamE in a given game, and after that move you have TeamE playing too many games and TeamC playing too few). This would result in the majority of your moves hurting the overall solution score.

Check out the swap move documentation here: https://docs.timefold.ai/timefold-solver/0.8.x/move-and-neighborhood-selection/move-and-neighborhood-selection#swapMoveSelector

mikethecalamity commented 1 month ago

I add this to my solverConfig.xml:

    <localSearch>
        <swapMoveSelector>
            <entitySelector>
                <entityClass>org.scheduleague.domain.Match</entityClass>
            </entitySelector>
            <variableNameIncludes>
                <variableNameInclude>homeTeam</variableNameInclude>
                <variableNameInclude>awayTeam</variableNameInclude>
            </variableNameIncludes>
        </swapMoveSelector>
    </localSearch>

but that gives me an error:

Caused by: java.lang.IllegalStateException: Local Search phase (0) needs to start from an initialized solution, but there are (36) uninitialized entities.
Maybe there is no Construction Heuristic configured before this phase to initialize the solution.
Or maybe the getter/setters of your planning variables in your domain classes aren't implemented correctly.

What am I missing?

bjmyers commented 1 month ago

You'll need to configure the construction heuristic. When you define your phases in the XML, add this one in first:

  <constructionHeuristic>
    <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
  </constructionHeuristic>

Ref: https://docs.timefold.ai/timefold-solver/0.8.x/construction-heuristics/construction-heuristics

bjmyers commented 1 month ago

And within your Solver XML block you can have multiple phases, just do something like this

<solver>
  <constructionHeuristic>
    ...
  </constructionHeuristic>
  <localSearch>
    ...
  </localSearch>
</solver>
mikethecalamity commented 1 month ago

Done