@Author: Raul Hernandez Lopez.
Important notice: This is a simulator based on the developer's personal experience running half marathons. It is not recommended to follow any plan generated by this software without first seeking medical clearance or professional coaching.
Overview:
This program has been created in Python using math, numpy, matplotlib.pyplot, and random, without the help of auxiliary libraries. For the genetic algorithm, research and testing were conducted by checking resources such as Amberle McKee's link.
Program execution mode:
python ./main.py
Quick setup with Makefile:
make setup
make run
Environment configuration:
cp .env.example .env
You can edit .env to override defaults such as MAIN_SCRIPT and VENV_DIR.
Main available commands:
make help # show all commands
make check # validate dependencies and compile Python files
make freeze # create requirements.lock.txt with exact installed versions
make clean # remove .venv and Python cache files
To configure parameters for testing, you can modify main.py:
For a single runner profile:
runner_times = ["1:45"] # representing each runner level
To get results for all profiles:
runner_times = ["2:00", "1:45", "1:20", "1:10"]
# full set of times to test ["2:00", "1:45", "1:20", "1:10"]
The same for weeks:
number_weeks_test = [12] # problem size tests
# full set of weeks for testing all [96, 48, 24, 12]
running-plan-generator/
├── core/ # Domain models and shared constants
│ ├── __init__.py
│ ├── constants.py # Shared constants (distances, time conversions, defaults)
│ └── models.py # Data classes: Config, TrainingSession, TrainingWeek, TrainingPlan
├── algorithms/ # Optimization strategies
│ ├── __init__.py
│ ├── genetic.py # Genetic Algorithm (GA) implementation
│ └── annealing.py # Simulated Annealing (SA) implementation
├── planning/ # Training plan creation and evaluation
│ ├── __init__.py
│ ├── fitness.py # FitnessCalculator: Running Index and penalty system
│ └── generator.py # TrainingPlanGenerator: random plan design
├── runner/ # Runner profiling, orchestration, and output
│ ├── __init__.py
│ ├── calibrator.py # RunnerCalibrator: level detection from half marathon time
│ ├── optimizer.py # TrainingOptimizer: coordinates strategy, evaluator, and generator
│ └── output.py # save_plan_to_file: writes plan results to text files
├── main.py # Entry point: configuration, test loops, execution
├── Makefile # Build/run helpers
├── requirements.txt
├── .env.example
├── LICENSE
└── README.md
The program is structured as follows:
main.pyis the entry point where tests are launched and modules are coordinated.runner/calibrator.pycontains theRunnerCalibratorclass (runner time calibrator).runner/optimizer.pycontains theTrainingOptimizer, which coordinates theFitnessCalculator(handling fitness and penalties) and theTrainingPlanGenerator(random plan generator). When the.optimize(...)method ofTrainingOptimizeris executed, the optimization strategy is introduced as a parameter:SimulatedAnnealingorGeneticAlgorithm. Within each of these classes, the following function signature is included:
This is the case for SA (Simulated Annealing):
optimises by using simulated annealing
# Args:
# evaluator: fitness calculator
# generator: plans creator
# config: main config from algorithm
# initial_solution: initial solution, may be GA result
def optimize(self, evaluator, generator, config: Config, initial_solution=None):
core/models.pycontains all employed data structures:Config,TrainingSession,TrainingWeekandTrainingPlan.- The program generates both graphs for each test and files with the optimal candidate plan to be selected.
This repository is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0).
See the LICENSE file for the full legal text and details.