Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gaelrenoux/gaston
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.5.0
Choose a base ref
...
head repository: gaelrenoux/gaston
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Aug 20, 2023

  1. Bumps version

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    faab5c4 View commit details
  2. Fix renderer

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    fa4e5cd View commit details
  3. Fix typo

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    4f75699 View commit details
  4. Adds TODO comment

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    e4e7b45 View commit details
  5. Adds some debug logs

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    23ece20 View commit details
  6. Adds base-score mechanism

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    2da6b53 View commit details
  7. Adds CI on Github Actions

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    b9f5caf View commit details
  8. Copy the full SHA
    50529b4 View commit details
  9. Copy the full SHA
    c621763 View commit details
  10. Copy the full SHA
    bd3a090 View commit details
  11. Fix erroneous comment

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    118ef98 View commit details
  12. Copy the full SHA
    6a18e06 View commit details
  13. Basic refactoring on test

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    ff912b2 View commit details
  14. Adds config for R3 2023

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    1a1c083 View commit details
  15. Upgrades ScalaTest version

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    1e27d17 View commit details
  16. Rename test configurations

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    e49be41 View commit details
  17. Clearer output

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    7a40a6a View commit details
  18. Copy the full SHA
    36c190c View commit details
  19. Copy the full SHA
    630eaf8 View commit details
  20. Adds failing test

    gaelrenoux committed Aug 20, 2023
    Copy the full SHA
    9093650 View commit details

Commits on Mar 30, 2024

  1. Cleanup tests

    gaelrenoux committed Mar 30, 2024
    Copy the full SHA
    533958d View commit details
  2. Copy the full SHA
    c37d7f7 View commit details

Commits on Mar 31, 2024

  1. Improves benchmark

    gaelrenoux committed Mar 31, 2024
    Copy the full SHA
    2e5f6b6 View commit details
  2. Copy the full SHA
    61a29bf View commit details
  3. Copy the full SHA
    5b8c1b3 View commit details
  4. Copy the full SHA
    8be7e9f View commit details
  5. Rename parameter

    gaelrenoux committed Mar 31, 2024
    Copy the full SHA
    b4082a1 View commit details

Commits on Apr 1, 2024

  1. Copy the full SHA
    c2c5443 View commit details
  2. Logs problem on startup

    gaelrenoux committed Apr 1, 2024
    Copy the full SHA
    130d7ed View commit details
  3. Copy the full SHA
    a314b2d View commit details
  4. Adds TODO

    gaelrenoux committed Apr 1, 2024
    Copy the full SHA
    766ae5a View commit details
  5. Copy the full SHA
    bbd3f83 View commit details
  6. Copy the full SHA
    b459c12 View commit details
  7. Copy the full SHA
    ead46e3 View commit details
  8. Better renderer

    gaelrenoux committed Apr 1, 2024
    Copy the full SHA
    60fd682 View commit details

Commits on Apr 7, 2024

  1. Adds comment

    gaelrenoux committed Apr 7, 2024
    Copy the full SHA
    890d3ca View commit details
  2. Copy the full SHA
    8470ea6 View commit details
  3. Copy the full SHA
    6129fee View commit details
  4. Adds IDEA file

    gaelrenoux committed Apr 7, 2024
    Copy the full SHA
    ba22f7a View commit details
  5. Fix documentation

    gaelrenoux committed Apr 7, 2024
    Copy the full SHA
    51043fc View commit details
  6. Copy the full SHA
    5126cd0 View commit details
  7. Drop multiple topics (not useful).

    Everything multiple topics does, can be done by just one big topic, or
    two simultaneous topics.
    gaelrenoux committed Apr 7, 2024
    Copy the full SHA
    c967bbf View commit details
  8. Adding topic duration

    gaelrenoux committed Apr 7, 2024
    Copy the full SHA
    7da33f5 View commit details

Commits on Apr 8, 2024

  1. Rename method for clarity

    gaelrenoux committed Apr 8, 2024
    Copy the full SHA
    ccefc24 View commit details
  2. Copy the full SHA
    e1735da View commit details

Commits on Apr 15, 2024

  1. No duration > 2

    gaelrenoux committed Apr 15, 2024
    Copy the full SHA
    5d64cba View commit details

Commits on Apr 20, 2024

  1. Copy the full SHA
    6da1731 View commit details
  2. Fix TopicsLinked

    gaelrenoux committed Apr 20, 2024
    Copy the full SHA
    275faac View commit details
  3. Copy the full SHA
    ddddbc0 View commit details
  4. Copy the full SHA
    4535e36 View commit details
Showing with 14,445 additions and 2,809 deletions.
  1. +38 −0 .github/workflows/ci.yml
  2. +9 −0 .gitignore
  3. +0 −19 .travis.yml
  4. +8 −0 IDEAS.md
  5. +59 −12 README.md
  6. +37 −57 build.sbt
  7. +1 −1 project/build.properties
  8. +1 −2 project/plugins.sbt
  9. +0 −152 scalastyle-config.xml
  10. +52 −0 src/main/resources/names/persons1.txt
  11. +52 −0 src/main/resources/names/persons2.txt
  12. +52 −0 src/main/resources/names/topics1.txt
  13. +26 −0 src/main/resources/names/topics2.txt
  14. +17 −10 src/main/scala/fr/renoux/gaston/command/CommandLine.scala
  15. +20 −18 src/main/scala/fr/renoux/gaston/command/Main.scala
  16. +62 −17 src/main/scala/fr/renoux/gaston/command/Output.scala
  17. +31 −21 src/main/scala/fr/renoux/gaston/command/Renderer.scala
  18. +0 −94 src/main/scala/fr/renoux/gaston/command/Runner.scala
  19. +5 −0 src/main/scala/fr/renoux/gaston/command/package.scala
  20. +134 −0 src/main/scala/fr/renoux/gaston/command/runner.scala
  21. +66 −18 src/main/scala/fr/renoux/gaston/engine/Engine.scala
  22. +72 −0 src/main/scala/fr/renoux/gaston/engine/GreedyEngine.scala
  23. +0 −52 src/main/scala/fr/renoux/gaston/engine/GreedySlotImprover.scala
  24. +0 −41 src/main/scala/fr/renoux/gaston/engine/Improver.scala
  25. +0 −20 src/main/scala/fr/renoux/gaston/engine/OptimParams.scala
  26. +177 −88 src/main/scala/fr/renoux/gaston/engine/PlanningSpaceNavigator.scala
  27. +48 −47 src/main/scala/fr/renoux/gaston/engine/{ScheduleGenerator.scala → RandomScheduleGenerator.scala}
  28. +29 −20 src/main/scala/fr/renoux/gaston/engine/{TabuSearchSlotImprover.scala → TabuSearchEngine.scala}
  29. +47 −0 src/main/scala/fr/renoux/gaston/engine/Termination.scala
  30. +34 −45 src/main/scala/fr/renoux/gaston/engine/assignment/AssignmentImprover.scala
  31. +122 −0 src/main/scala/fr/renoux/gaston/engine/assignment/RandomAssigner.scala
  32. +0 −145 src/main/scala/fr/renoux/gaston/engine/assignment/ScheduleAssigner.scala
  33. +106 −0 src/main/scala/fr/renoux/gaston/input/InputCleaner.scala
  34. +2 −1 src/main/scala/fr/renoux/gaston/input/InputError.scala
  35. +14 −32 src/main/scala/fr/renoux/gaston/input/InputLoader.scala
  36. +56 −0 src/main/scala/fr/renoux/gaston/input/InputRenderer.scala
  37. +241 −148 src/main/scala/fr/renoux/gaston/input/InputTranscription.scala
  38. +23 −26 src/main/scala/fr/renoux/gaston/input/TableReader.scala
  39. +14 −22 src/main/scala/fr/renoux/gaston/input/input.scala
  40. +184 −94 src/main/scala/fr/renoux/gaston/input/inputModel.scala
  41. +18 −7 src/main/scala/fr/renoux/gaston/model/Constraint.scala
  42. +24 −2 src/main/scala/fr/renoux/gaston/model/Counts.scala
  43. +15 −3 src/main/scala/fr/renoux/gaston/model/Person.scala
  44. +23 −9 src/main/scala/fr/renoux/gaston/model/Preference.scala
  45. +133 −43 src/main/scala/fr/renoux/gaston/model/Problem.scala
  46. +41 −25 src/main/scala/fr/renoux/gaston/model/Record.scala
  47. +189 −58 src/main/scala/fr/renoux/gaston/model/Schedule.scala
  48. +0 −87 src/main/scala/fr/renoux/gaston/model/Score.scala
  49. +15 −9 src/main/scala/fr/renoux/gaston/model/ScoreCalculator.scala
  50. +13 −1 src/main/scala/fr/renoux/gaston/model/Slot.scala
  51. +100 −36 src/main/scala/fr/renoux/gaston/model/SlotSchedule.scala
  52. +47 −6 src/main/scala/fr/renoux/gaston/model/Topic.scala
  53. +0 −47 src/main/scala/fr/renoux/gaston/model/Weight.scala
  54. +6 −2 src/main/scala/fr/renoux/gaston/model/constraints/TopicsNotSimultaneous.scala
  55. +7 −0 src/main/scala/fr/renoux/gaston/model/constraints/TopicsSimultaneous.scala
  56. +3 −3 src/main/scala/fr/renoux/gaston/model/constraints/package.scala
  57. +0 −79 src/main/scala/fr/renoux/gaston/model/impl/ProblemImpl.scala
  58. +17 −0 src/main/scala/fr/renoux/gaston/model/iterableToArrayCollectionExtensions.scala
  59. +2 −43 src/main/scala/fr/renoux/gaston/model/package.scala
  60. +28 −0 src/main/scala/fr/renoux/gaston/model/preferences/PersonFreeSlotPreference.scala
  61. +10 −7 src/main/scala/fr/renoux/gaston/model/preferences/PersonGroupAntiPreference.scala
  62. +20 −0 src/main/scala/fr/renoux/gaston/model/preferences/PersonPersonPreference.scala
  63. +6 −2 src/main/scala/fr/renoux/gaston/model/preferences/PersonTopicPreference.scala
  64. +9 −2 src/main/scala/fr/renoux/gaston/model/preferences/TopicDirectPreference.scala
  65. +14 −5 src/main/scala/fr/renoux/gaston/model/preferences/TopicsExclusive.scala
  66. +36 −0 src/main/scala/fr/renoux/gaston/model/preferences/TopicsExclusiveFor.scala
  67. +17 −7 src/main/scala/fr/renoux/gaston/model/preferences/TopicsLinked.scala
  68. +112 −0 src/main/scala/fr/renoux/gaston/model/score.scala
  69. +100 −0 src/main/scala/fr/renoux/gaston/tools/CombinerAnonymizer.scala
  70. +55 −0 src/main/scala/fr/renoux/gaston/tools/InputAnonymizer.scala
  71. +95 −0 src/main/scala/fr/renoux/gaston/tools/ScheduleParser.scala
  72. +6 −0 src/main/scala/fr/renoux/gaston/tools/package.scala
  73. +56 −0 src/main/scala/fr/renoux/gaston/util/ArrayMap.scala
  74. +68 −0 src/main/scala/fr/renoux/gaston/util/ArraySet.scala
  75. +0 −50 src/main/scala/fr/renoux/gaston/util/BitMap.scala
  76. +0 −55 src/main/scala/fr/renoux/gaston/util/BitSet.scala
  77. +17 −30 src/main/scala/fr/renoux/gaston/util/CanAddDuration.scala
  78. +32 −60 src/main/scala/fr/renoux/gaston/util/CanGroupToMap.scala
  79. +39 −49 src/main/scala/fr/renoux/gaston/util/CanTakeChunks.scala
  80. +23 −7 src/main/scala/fr/renoux/gaston/util/Chrono.scala
  81. +0 −56 src/main/scala/fr/renoux/gaston/util/CollectionImplicits.scala
  82. +4 −1 src/main/scala/fr/renoux/gaston/util/Context.scala
  83. +1 −1 src/main/scala/fr/renoux/gaston/util/Count.scala
  84. +36 −0 src/main/scala/fr/renoux/gaston/util/MutableArrayMap.scala
  85. +84 −0 src/main/scala/fr/renoux/gaston/util/MutableArraySet.scala
  86. +8 −4 src/main/scala/fr/renoux/gaston/util/Opt.scala
  87. +0 −15 src/main/scala/fr/renoux/gaston/util/OptionImplicits.scala
  88. +0 −20 src/main/scala/fr/renoux/gaston/util/RandomImplicits.scala
  89. +15 −0 src/main/scala/fr/renoux/gaston/util/Resources.scala
  90. +1 −0 src/main/scala/fr/renoux/gaston/util/Tools.scala
  91. +0 −12 src/main/scala/fr/renoux/gaston/util/TupleImplicits.scala
  92. +7 −0 src/main/scala/fr/renoux/gaston/util/annotations.scala
  93. +67 −0 src/main/scala/fr/renoux/gaston/util/collectionExtensions.scala
  94. +26 −0 src/main/scala/fr/renoux/gaston/util/mapExtension.scala
  95. +16 −0 src/main/scala/fr/renoux/gaston/util/randomExtension.scala
  96. +12 −0 src/main/scala/fr/renoux/gaston/util/stringExtension.scala
  97. +0 −5 src/main/scala/fr/renoux/gaston/util/testOnly.scala
  98. +6 −0 src/main/scala/fr/renoux/gaston/util/tupleExtensions.scala
  99. +48 −0 src/test-slow/resources/logback-test.xml
  100. +0 −3 src/{test → test-slow}/resources/r32019/r32019-table.conf
  101. 0 src/{test → test-slow}/resources/r32019/r32019-table.csv
  102. +7 −4 src/{test → test-slow}/resources/r32019/r32019.conf
  103. +1,226 −0 src/test-slow/resources/r32023/r32023-from-table.conf
  104. +54 −0 src/test-slow/resources/r32023/r32023-starting.conf
  105. +36 −0 src/test-slow/resources/r32023/r32023-table.csv
  106. +1,234 −0 src/test-slow/resources/r32023/r32023-tts2-modified-.conf
  107. +1,209 −0 src/test-slow/resources/r32023/r32023-tts2.conf
  108. +49 −0 src/test-slow/resources/r32024/base.conf
  109. +854 −0 src/test-slow/resources/r32024/full-modified-2.conf
  110. +830 −0 src/test-slow/resources/r32024/full-modified.conf
  111. +828 −0 src/test-slow/resources/r32024/full.conf
  112. +1,099 −0 src/test-slow/resources/r32024/table.conf
  113. +34 −0 src/test-slow/resources/r32024/table.csv
  114. +681 −0 src/test-slow/resources/udocon2017/uc17-from-table.conf
  115. +27 −0 src/test-slow/resources/udocon2017/uc17-table.csv
  116. 0 src/{test/resources/udocon2017/uc17-completed.conf → test-slow/resources/udocon2017/uc17.conf}
  117. src/{test/resources/udocon2019/uc19-full.conf → test-slow/resources/udocon2019/uc19.conf}
  118. +31 −0 src/test-slow/scala/fr/renoux/gaston/InputAnonymizerApp.scala
  119. +18 −18 src/{test-perf → test-slow}/scala/fr/renoux/gaston/benchmarks/PerformanceAnalysis.scala
  120. +27 −32 src/{test-perf → test-slow}/scala/fr/renoux/gaston/benchmarks/RegressionBenchmark.scala
  121. +113 −0 src/test-slow/scala/fr/renoux/gaston/itests/PastUsesSpec.scala
  122. +3 −3 src/{test/scala/fr/renoux/gaston → test-slow/scala/fr/renoux/gaston/itests}/RunLocal.scala
  123. +64 −0 src/test-slow/scala/fr/renoux/gaston/itests/SpecialCasesSpec.scala
  124. +144 −0 src/test/resources/rendering-test.conf
  125. +0 −92 src/test/resources/test-application.conf
  126. +25 −19 src/test/scala/fr/renoux/gaston/ComplexTestModel.scala
  127. +26 −23 src/test/scala/fr/renoux/gaston/MinimalTestModel.scala
  128. +124 −96 src/test/scala/fr/renoux/gaston/SimpleTestModel.scala
  129. +6 −28 src/test/scala/fr/renoux/gaston/TestUtils.scala
  130. +3 −4 src/test/scala/fr/renoux/gaston/command/CommandLineTest.scala
  131. +24 −0 src/test/scala/fr/renoux/gaston/command/RendererTest.scala
  132. +0 −60 src/test/scala/fr/renoux/gaston/engine/EngineSpec.scala
  133. +44 −0 src/test/scala/fr/renoux/gaston/engine/RandomScheduleGeneratorSpec.scala
  134. +3 −3 src/test/scala/fr/renoux/gaston/engine/ScoreCalculatorSpec.scala
  135. +77 −0 src/test/scala/fr/renoux/gaston/engine/SyncRunnerSpec.scala
  136. +73 −0 src/test/scala/fr/renoux/gaston/engine/assignment/RandomAssignerSpec.scala
  137. +87 −0 src/test/scala/fr/renoux/gaston/input/InputCleanerSpec.scala
  138. +7 −7 src/test/scala/fr/renoux/gaston/input/InputLoaderSpec.scala
  139. +22 −0 src/test/scala/fr/renoux/gaston/input/InputRendererSpec.scala
  140. +39 −31 src/test/scala/fr/renoux/gaston/input/InputSpec.scala
  141. +140 −96 src/test/scala/fr/renoux/gaston/input/InputTranscriptionSpec.scala
  142. +33 −32 src/test/scala/fr/renoux/gaston/input/TableReaderSpec.scala
  143. +0 −45 src/test/scala/fr/renoux/gaston/model/ConstraintsSpec.scala
  144. +0 −99 src/test/scala/fr/renoux/gaston/model/PreferencesSpec.scala
  145. +69 −17 src/test/scala/fr/renoux/gaston/model/ScheduleSpec.scala
  146. +11 −10 src/test/scala/fr/renoux/gaston/model/SlotScheduleSpec.scala
  147. +59 −0 src/test/scala/fr/renoux/gaston/model/constraints/TopicsNotSimultaneousSpec.scala
  148. +52 −0 src/test/scala/fr/renoux/gaston/model/constraints/TopicsSimultaneousSpec.scala
  149. +73 −0 src/test/scala/fr/renoux/gaston/model/preferences/PersonFreeSlotPreferenceSpec.scala
  150. +45 −0 src/test/scala/fr/renoux/gaston/model/preferences/PersonGroupAntiPreferenceSpec.scala
  151. +35 −0 src/test/scala/fr/renoux/gaston/model/preferences/PersonPersonPreferenceSpec.scala
  152. +35 −0 src/test/scala/fr/renoux/gaston/model/preferences/PersonTopicPreferenceSpec.scala
  153. +40 −0 src/test/scala/fr/renoux/gaston/model/preferences/TopicDirectPreferenceSpec.scala
  154. +64 −0 src/test/scala/fr/renoux/gaston/model/preferences/TopicsExclusiveForSpec.scala
  155. +64 −0 src/test/scala/fr/renoux/gaston/model/preferences/TopicsExclusiveSpec.scala
  156. +53 −0 src/test/scala/fr/renoux/gaston/model/preferences/TopicsLinkedSpec.scala
  157. +53 −0 src/test/scala/fr/renoux/gaston/tools/CombinerAnonymizerSpec.scala
  158. +22 −0 src/test/scala/fr/renoux/gaston/tools/InputAnonymizerSpec.scala
  159. +62 −0 src/test/scala/fr/renoux/gaston/tools/ScheduleParserSpec.scala
  160. +112 −0 src/test/scala/fr/renoux/gaston/util/ArrayMapSpec.scala
  161. +118 −0 src/test/scala/fr/renoux/gaston/util/ArraySetSpec.scala
  162. +37 −0 src/test/scala/fr/renoux/gaston/util/CanAddDurationSpec.scala
  163. +72 −0 src/test/scala/fr/renoux/gaston/util/CanGroupToMapSpec.scala
  164. +16 −16 src/test/scala/fr/renoux/gaston/util/CanTakeChunksSpec.scala
  165. +126 −0 src/test/scala/fr/renoux/gaston/util/CollectionExtensionsSpec.scala
  166. +0 −20 src/test/scala/fr/renoux/gaston/util/CollectionImplicitsSpec.scala
  167. +94 −0 src/test/scala/fr/renoux/gaston/util/MapExtensionsSpec.scala
  168. +50 −0 src/test/scala/fr/renoux/gaston/util/MutableArrayMapSpec.scala
  169. +109 −0 src/test/scala/fr/renoux/gaston/util/MutableArraySetSpec.scala
  170. +75 −0 src/test/scala/fr/renoux/gaston/util/RandomExtensionSpec.scala
  171. +14 −0 src/test/scala/fr/renoux/gaston/util/StringExtensionsSpec.scala
  172. +17 −0 src/test/scala/fr/renoux/gaston/util/TupleExtensionsSpec.scala
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI

on:
workflow_dispatch:
push:
pull_request:
release:

permissions:
contents: read


jobs:

build:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v4

- name: Setup JDK
uses: actions/setup-java@v4
with:
java-version: 21
distribution: temurin
cache: sbt

- name: Setup sbt
uses: sbt/setup-sbt@v1

- name: Clean compile
run: sbt clean

- name: Run fast tests
run: sbt test

- name: Run slow tests
run: sbt test-slow:test
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -12,13 +12,22 @@ lib_managed/
src_managed/
project/boot/
project/plugins/project/
project/**/target

# BSP
.bsp

# Metals
.metals
project/metals.sbt
project/**/metals.sbt

# Scala-IDE specific
.scala_dependencies
.worksheet

# IntelliJ specific
.idea

# VSCode specific
.vscode
19 changes: 0 additions & 19 deletions .travis.yml

This file was deleted.

8 changes: 8 additions & 0 deletions IDEAS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- Add unit test for forced topics
- When a schedule is a success (better than previous one), try to re-assign everyone a few times to see if you can improve it further
- Better handling of constraints
- Incompatibility reward should be in the preference (in the config), not in settings
- Create a max-unassigned or max-nothing, and use a topic-exclusive ? It's not a personal pref though, so it doesn't work that well
- Keep and display schedules that are close to the current one, to give some alternatives (or fix a target score and give all that are above the score)
- Simulated cooling
- Generate a better base configuration, depending on what the user asks for
71 changes: 59 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -30,35 +30,45 @@ The input file describes the problem to solve. It follows the HOCON format, and

- `gaston`: Root element of the configuration.
- `settings`: Global settings. All fields are optional and have a default value.
- `status-display-interval`: How often you want to display new good schedules. You can write any time unit, for example: `20 seconds` or `30 minutes`, or abbreviate it as `20s` or `30m`. Default is `20 seconds`.
- `incompatibility-anti-preference`: Negative score for a person forced to share a topic with someone it would rather not. Default is `-1000`.
- `default-max-topics-per-slot`: Max number of topics per slot (default is no limit.
- `default-min-persons-per-topic`: Minimum number of persons per topic, can be overriden on specific topics. Default is `1`.
- `default-max-persons-per-topic`: Maximum number of persons per topic, can be overriden on specific topics. Default is `10`.
- `max-persons-on-nothing`: On each slot, maximum number of persons who can have no topic scheduled. Default value is `0`, i.e. everyone must have a topic scheduled on each slot.
- `min-persons-on-nothing`: On each slot, minimum number of persons who can have no topic scheduled (the idea being that enough unoccupied persons can do something together). Default is `0`, i.e. no minimum.
- `person-on-nothing-anti-preference`: Negative score attached to a person doing nothing on a slot. Default value is `-100`.
- `backtrack-initial-schedule`: Technical stuff: should initial schedules be empty or backtracked ? Best answer depends on the schedule being highly constrained or note. Default is `true`.
- `default-min-persons-per-topic`: Minimum number of persons per topic, can be overridden on specific topics. Default is `1`.
- `default-max-persons-per-topic`: Maximum number of persons per topic, can be overridden on specific topics. Default is `10`.
- `unassigned`: A bunch of settings about how to handle unassigned persons (to be unassigned is to not be scheduled on any topic, on some slot). Default is no not allow it at all.
- `allowed`: If true, Gaston will allow for people staying unassigned. Default is `false`.
- `person-anti-preference`: Negative score attached to a person being unassigned. It's counted once for every slot when a person is unassigned. Default value is `-1000`.
- `person-multiple-anti-preference`: Additional negative score attached if unassigned on multiple slots (in addition to the basic anti-preference). Useful if you want to make one unassignment acceptable, but not two. Default value is `0`.
- `max`: On each slot, maximum number of persons who can be unassigned. Default is unlimited.
- `min`: On each slot, minimum number of persons who can be unassigned (the idea being that enough unassigned persons can do something together). Default is `0`, i.e. no minimum.
- `persons-anti-preference-scaling`: If present, this settings make the unassignment anti-preference scale with the number of forbidden entries of a person. The more topics are forbidden for them, the less impactful an unassignment will be. Default is none.
- `forbidden-ratio-for-maximum`: For a person, if their ratio of forbidden topics to total topics reach this value, the unassignment anti-preference will be set to its maximum value below.Default is `75%`.
- `maximum-anti-preference`: If a person has the maximum ratio of forbidden topics, their unassignment anti-preference. Default is `-1`.
- `absence-adjustment-factor`: If a person is absent, with a factor of 1, its score will be adjusted so that it will be the same as someone having the same % of their time on the same wish level. For example: if you're only present on 3 slots and have 3 wishes at 5, you'll have the same score than someone present on 5 slots and 3 wishes at 5. This factor lets you reduce that a bit. Putting a lower factor means that absence counts for less than 1, leading to slightly better schedules for people who are missing some slots. The reasoning: if they're not here as much, they should at least enjoy the slots they are here.
- `tableSettings`: Settings for importing a table. Optional (leave that field out if you are not importing a table). See the *Importing a table* section below for details.
- `slots`: The slots on which to schedule, as an array of arrays of slots. The inner arrays contain the slots following each other directly (such as one in the morning and the other in the afternoon of the same day), so that mult-slot topics may be handled (WIP). The following lines describe the structure of one slot.
- `slots`: The slots on which to schedule, as an array of arrays of slots. The inner arrays contain the slots following each other directly (such as one in the morning and the other in the afternoon of the same day), so that mult-slot topics may be handled. The following lines describe the structure of one slot.
- `name`: Name of the slot. Must be unique among slots.
- `max-topics`: Maximum number of topics to schedule on this slot (e.g. because space as limited at that time).
- `topics`: The topics to schedule. The following lines describe the structure of one topic.
- `name`: Name of the topic. Must be unique among topics.
- `min`: Minimum number of persons on a topic. Default is empty (will use the settings' value).
- `max`: Maximum number of persons on a topic. Default is empty (will use the settings' value).
- `occurrences`: How many sessions of the topic are possible. Default is `1`.
- `multiple`: How many parallel sessions this topic represents (all sessions are simultaneous). Note than min and max are for one session. Default is `1`.
- `duration`: How many consecutive slots the topic occupies. Default is `1`.
- `slots`: An array of slot names on which the topic can be scheduled. Default is empty (can be scheduled on any slot).
- `presence`: A score added for just having this topic present. Can be used to favor a topic, or to set a topic as to avoid if possible (with a negative score). Default is `0`.
- `forced`: If `true`, this topic *must* be scheduled. Default is `false`.
- `persons`: The persons to schedule. The following lines describe the structure of one person.
- `name`: Name of the person. Must be unique among persons.
- `weight`: A person with a higher weight counts more when calculating the global score. Specifically, that person's individual score will be divided by its weight, bringing them down and making the schedule optimizing more for them.. Default is `1`.
- `weight`: A person with a higher weight counts more when calculating the global score. Specifically, that person's individual score will be divided by its weight, bringing them down and making the schedule optimizing more for them. Default is `1`.
- `base-score`: You can add a starting value for this person's score. This is useful only in very specific situations. Default is `0`.
- `absences`: An array of slot names on which this person is missing, and therefore cannot be scheduled. Default is empty.
- `mandatory`: An array of topic names for which this person is mandatory: it must be present on those topics. Default is empty.
- `forbidden`: An array of topic names for which this person is forbidden: it cannot be scheduled on those topics. Default is empty.
- `incompatible`: An array of person names this person wish not to share a topic with. Default is empty.
- `wishes`: A mapping of topic names to scores. The higher the score, the more that persons wishes to be on that topic. The scores will be rebalanced so that everyone has a 1000 points total.
- `wishes`: A mapping of topic names to scores. The higher the score, the more that persons wishes to be on that topic. The scores will be rebalanced so that everyone has a 1000 points total (including person wishes, next line).
- `personWishes`: A mapping of person names to scores. The higher the score, the more that persons wishes to be on a topic with the target person. The scores will be rebalanced so that everyone has a 1000 points total (including topic wishes, previous line).
- `min-free-slots`: How many free slots (slots where the person's not assigned to anything) they want. Implies that `unassigned` persons are allowed in the settings. Note that free slots must be on different slots sub-list (different days).
- `constraints`: Global constraints on the schedule.
- `simultaneous`: An array of simultaneity constraints.
- `topics`: An array of topics. Those topics must all be scheduled on the same slot, or not at all.
@@ -236,8 +246,6 @@ gaston {
settings {
default-max-topics-per-slot = 3
minPersonsOnNothing = 3
maxPersonsOnNothing = 10
}
table-settings {
@@ -279,3 +287,42 @@ gaston {
]
}
```


# Developer's corner

## Brain dump

Some vocabulary:
- Planning is when we decide which topic is on which slot. It does NOT include assigning persons to those topics or checking score. It does however require we check that mandatory persons are availabe.
- Therefore, a planning is a schedule with no one assigned apart from the mandatory persons.
- Assignment is when we assign persons to an existing planning.
- Scheduling is doing both.
- An unfilled schedule is a schedule where only the planning is done, most persons are not assigned yet. Some persons may have been assigned, which is why we don't call it unassigned.

The Engine produces a lazy list of schedules, each new schedule being better than the next one. The list ends when no
further improvement can be found, which never happens on real-world examples. It starts with a seed for all random
operations.

The Engine is CPU-bound and monothreaded. Typically, you would run multiple Engines in parallel, one per CPU, with
different seeds.

An Engine run (in `Engine.lazySeq`) starts with an initial schedule respecting all constraints, but with probably a terrible score.
- If using backtracking, a schedule with topics and such will be generated. If there are enough topics to occupy everyone and not too many constraints, that is the recommended solution.
- This uses the ScheduleGenerator, which is only used for this.
- This schedule has been assignment-optimized (see below).
- If not using backtracking (backtrack-initial-schedule option is set to false), we start with an empty schedule. This is recommended if you expect some persons to be unassigned on some slots.
- This starts using `Schedule.startingUnassignedOrForced`.

Then, the Engine generates a lazy-list by improving the state step-by-step.
There are two Engines implemented, GreedyEngine and TabuSearchEngine. Only the first one is currently being used.

In GreedyEngine, a generation step starts from the latest generated schedule, and procedes with the following steps:
- Figure out all neighbours of the latest schedule in the planning spaces. Neighbours are plannings that we can get from that schedule by adding or dropping a topic, or swapping two topics.
- Eliminate neighbours that would be just a revert of the previous change (e.g. latest schedule was obtained by adding topic A, then dropping topic A is not a neighbour we need to consider).
- For each neighbour (lazily)
- Fills in the planning by assigning people to topics. We are respecting constraints (a person can't be on two topics in the same slot), but ignoring preferences (even strong ones).
- Improves the assignment as much as possible by swapping or moving persons around, stop when all moves make it worse.
- As soon as we find a schedule that's better than the latest schedule, we stop iterating over neighbours and output that schedule.


Loading