Training Plan Generation Algorithm
This document describes the HIGH-LEVEL architecture of the training plan generation system. Input parameters, calculation formulas, optimization methods, variable weights, and scoring algorithms are proprietary and not disclosed publicly.
Overview
The SmartRunning platform generates personalized training plans using an optimization algorithm that creates training progressions based on athlete data and race preparation requirements.
For high-level architecture context, see Architecture.
Algorithm Flow
The training plan generation follows this high-level flow:
User Request (via Flask API)
↓
TrainingPlanGenerator spawns subprocess
↓
[SUBPROCESS: generate_training_plan.py]
├─ 1. Load runner parameters from MongoDB
├─ 2. Load training schema template
├─ 3. Calculate preparation start date
├─ 4. Build training calendar
├─ 5. Run optimization process
├─ 6. Simulate training load progression
├─ 7. Assign workout sessions
├─ 8. Save plan to database (one document per day)
└─ 9. Return plan ID
↓
Background job completes
↓
User views generated plan
Key Files:
app/generate_training_plan.py- Core optimization engineapp/training_plan_generator.py- API wrapper and subprocess management
Data Sources
The algorithm retrieves data from:
-
MongoDB Collections:
runner- Athlete parameters and configurationtrainingplanschema- Workout templates and training blockstrainingplan- Output storage (one document per day)
-
Input from User:
- Target race date
- Training schema selection
Specific parameter names, default values, and data structures are proprietary.
Calendar Construction
The algorithm builds a training calendar working backwards from the race date:
- Calculate total preparation duration
- Determine start date (aligned to Monday)
- Create daily schedule with training/rest days
- Assign training blocks and phases
- Mark recovery weeks and taper period
Optimization Process
The system uses optimization techniques to determine training stress distribution across all training days.
The optimization algorithm, objective functions, constraint definitions, and convergence parameters are proprietary.
High-Level Approach
The optimization process:
- Explores the solution space to find optimal progressions
- Balances multiple competing objectives
- Respects physiological and scheduling constraints
- Handles high-dimensional problems (100+ training days)
Training Load Simulation
After optimization, the system simulates the training plan to verify physiological responses.
Simulation Process
For each day in plan:
1. Get assigned training stress value
2. Calculate fitness response
3. Calculate fatigue response
4. Update training load metrics
5. Verify constraints are satisfied
Tracked Metrics
The system tracks fitness and fatigue metrics throughout the plan:
- Long-term fitness levels
- Short-term fatigue levels
- Training stress balance
- Recovery status
Specific formulas and physiological models are proprietary.
Workout Assignment
After determining training stress distribution, workouts are assigned from the schema template.
Assignment Process
For each training day:
1. Identify the training block and week
2. Get available workouts from schema
3. Select workout matching training stress target
4. Assign workout session code to that day
Workout Selection Criteria
Workouts are matched based on:
- Training block/phase
- Week progression
- Day of week
- Training stress target
Output Structure
The generated training plan is stored in MongoDB with one document per day.
Daily Plan Document Structure
{
"_id": ObjectId,
"runner_id": ObjectId,
"date": ISODate,
"week_number": Number,
"day_of_week": Number,
"session_code": String,
"session_type": String,
"session_definition": String,
"is_training_day": Boolean,
"is_recovery_week": Boolean,
"phase": String,
"created_at": ISODate
}
For complete database schema, see Database Schema.
Technical Implementation
Asynchronous Processing
Training plan generation runs as a background job:
- API Request: User requests plan generation via Flask API
- Job Creation: System creates background job record
- Subprocess Spawn: Main process spawns subprocess for optimization
- Progress Updates: Job progress tracked in
background_jobscollection - Completion: Plan saved to database, job marked complete
Why subprocess?
- CPU-intensive optimization doesn't block web server
- Isolated memory space
- Crash-safe
For details, see Data Flow.
Performance Characteristics
Typical generation times:
- Short plans (8-12 weeks): 5-10 seconds
- Standard marathon plans (16-20 weeks): 15-30 seconds
- Long ultra plans (24+ weeks): 30-60 seconds
Dependencies
Key Python libraries:
- scipy: Optimization algorithms
- numpy: Numerical computations
- pandas: Data structure manipulation
- pymongo: Database operations
Integration Points
API Endpoints
-
POST /runners/<id>/training-plans/generate- Initiate plan generation- Input:
schema_id,marathon_date - Output:
job_idfor tracking progress
- Input:
-
GET /runners/<id>/training-plans- Retrieve generated plans -
GET /training-plans/<plan_id>- Get specific plan details
Database Collections
Plan generation interacts with:
- runner: Reads athlete configuration
- trainingplanschema: Reads workout templates
- trainingplan: Writes daily plan documents
- background_jobs: Tracks generation progress
Related Documentation
- System Overview - Architecture and components
- Data Flow - Asynchronous processing flow
- Database Schema - Data structures
Document Version: 2.0 (Public - Sanitized)
Note: This document intentionally omits all proprietary information including input parameters, specific formulas, model coefficients, optimization methods, constraint definitions, and scoring algorithms that constitute SmartRunning's competitive advantage.