|
OptiPy
|
Implements the classical flow shop scheduling problem. More...
#include <FlowShop.h>
Public Member Functions | |
Constructors | |
| FlowShop () | |
| Constructs a FlowShop problem with zero dimensions. | |
| FlowShop (size_t num_jobs, size_t num_machines) | |
| Constructs a FlowShop problem with specified dimensions. | |
| FlowShop (size_t num_jobs, size_t num_machines, std::vector< uint64_t > &&data) | |
| Internal constructor used by pybind11 bindings. | |
Data Access | |
| size_t | num_jobs () const |
| Returns the number of jobs in this problem. | |
| size_t | num_machines () const |
| Returns the number of machines in this problem. | |
| uint64_t * | data () |
| Returns mutable pointer to flattened processing times matrix. | |
| const uint64_t * | data () const |
| Returns const pointer to flattened processing times matrix. | |
| uint64_t * | due_dates_data () |
| Returns mutable pointer to due dates vector. | |
| const uint64_t * | due_dates_data () const |
| Returns const pointer to due dates vector. | |
Problem Configuration | |
| void | set_jobs (size_t num_jobs, size_t num_machines, std::vector< uint64_t > &&new_data) |
| Replaces the entire processing times matrix and dimensions. | |
| void | set_due_dates (std::vector< uint64_t > &&new_data) |
| Replaces the due dates vector. | |
Optimization Methods | |
| FlowShopResult | runNEH (bool blocking=false, bool optimizeTardiness=false) |
| Optimizes the flow shop schedule using the NEH heuristic. | |
| FlowShopResult | runDE (bool blocking, bool optimizeTardiness, size_t popSize, double f, double cr, size_t maxGenerations, unsigned long seed, std::string &mutationStrategy, std::string &crossoverStrategy) |
| Optimizes the flow shop schedule using Differential Evolution. | |
Evaluable Concept Implementation | |
| void | getInitialSolutions (std::vector< std::vector< double > > &population) |
| Generates an initial population of candidate solutions. | |
| constexpr double | getLowerBounds () const |
| Returns the lower bound for the optimization domain. | |
| constexpr double | getUpperBounds () const |
| Returns the upper bound for the optimization domain. | |
| double | evaluateSolution (const std::vector< double > &solution) |
| Evaluates the objective function for a given solution. | |
Implements the classical flow shop scheduling problem.
The FlowShop class models a manufacturing environment where jobs must be processed sequentially through a series of machines in a fixed order. The goal is to find an optimal job scheduling order that minimizes either makespan (total completion time) or total tardiness (sum of lateness over all jobs).
Problem Definition:
Given:
Find: A permutation of jobs that minimizes the chosen objective.
Key Features:
Problem Data:
Evaluable Concept:
FlowShop satisfies the Evaluable concept, allowing it to be optimized directly by DifferentialEvolution:
|
inline |
Constructs a FlowShop problem with zero dimensions.
Creates an empty problem instance. Data must be populated via set_jobs() before optimization.
|
inline |
Constructs a FlowShop problem with specified dimensions.
Allocates storage for a problem with num_jobs jobs and num_machines machines. All processing times initialize to zero; call set_jobs() to populate actual data.
| num_jobs | Number of jobs in the scheduling problem |
| num_machines | Number of machines in sequence |
| std::runtime_error | if num_jobs or num_machines is zero |
|
inline |
Internal constructor used by pybind11 bindings.
Constructs a FlowShop with pre-allocated data moved from caller. Validates that data size matches the dimensions (num_jobs × num_machines).
| num_jobs | Number of jobs |
| num_machines | Number of machines |
| data | Rvalue reference to flattened m×n matrix (row-major) |
| std::runtime_error | if data.size() != num_jobs * num_machines |
|
inline |
Returns mutable pointer to flattened processing times matrix.
The matrix is stored in row-major order: jobs_times[i * num_machines + j] contains the processing time of job i on machine j.
|
inline |
Returns const pointer to flattened processing times matrix.
|
inline |
Returns mutable pointer to due dates vector.
The vector has size num_jobs; due_dates_[i] is the due date for job i. Used for tardiness calculation: tardiness = max(0, completion_time - due_date).
|
inline |
Returns const pointer to due dates vector.
| double FlowShop::evaluateSolution | ( | const std::vector< double > & | solution | ) |
Evaluates the objective function for a given solution.
Converts an SPV-encoded vector to a job permutation, evaluates the resulting schedule, and returns the objective value (makespan or tardiness).
Algorithm:
Complexity: O(nm) for completion time calculation + O(n log n) for SPV conversion.
| [in] | solution | SPV-encoded solution vector (size = num_jobs, values in [-1, 1]) |
Thread Safety: This method is thread-safe for concurrent evaluation when blocking and optimizeTardiness fields are constant. Must not be called concurrently with runDE() or field modifications.
Requirements: blocking and optimizeTardiness must be set before calling (typically by runDE() prior to optimizer invocation).
| void FlowShop::getInitialSolutions | ( | std::vector< std::vector< double > > & | population | ) |
Generates an initial population of candidate solutions.
Creates population.size() SPV-encoded solutions using three strategies:
This initialization biases the population toward high-quality regions (NEH solutions) while maintaining diversity for exploration.
| [out] | population | Pre-allocated vector of population.size() solution vectors. Each solution is filled with SPV values in [-1, 1]. |
Thread Safety: Uses OpenMP parallelization to generate initial solutions quickly.
|
inlineconstexpr |
Returns the lower bound for the optimization domain.
For SPV encoding, all dimensions share a uniform lower bound of -1.0.
|
inlineconstexpr |
Returns the upper bound for the optimization domain.
For SPV encoding, all dimensions share a uniform upper bound of 1.0.
|
inline |
Returns the number of jobs in this problem.
|
inline |
Returns the number of machines in this problem.
| FlowShopResult FlowShop::runDE | ( | bool | blocking, |
| bool | optimizeTardiness, | ||
| size_t | popSize, | ||
| double | f, | ||
| double | cr, | ||
| size_t | maxGenerations, | ||
| unsigned long | seed, | ||
| std::string & | mutationStrategy, | ||
| std::string & | crossoverStrategy ) |
Optimizes the flow shop schedule using Differential Evolution.
Applies the DE metaheuristic to find high-quality solutions. The algorithm:
Solution Encoding: SPV (Smallest Position Value)
Population Initialization:
| blocking | If true, enforces job blocking constraints |
| optimizeTardiness | If true, minimizes tardiness; if false, minimizes makespan |
| popSize | Population size; typically 20-50 for small problems |
| f | Differential weight (mutation scale factor); typical range (0, 2], e.g., 0.8 |
| cr | Crossover rate; range [0, 1], e.g., 0.9 (higher = more diversity) |
| maxGenerations | Maximum iterations; termination criterion |
| seed | Random seed for reproducible results |
| mutationStrategy | Name of mutation operator; one of: "rand1", "rand2", "best1", "best2", "randToBest1" Defaults to "rand1" if empty |
| crossoverStrategy | Name of crossover operator; one of: "bin" (binomial, default), "exp" (exponential) Defaults to "bin" if empty |
Thread Safety: Evaluation is parallelized with OpenMP. Concurrent solution evaluations are safe; problem state (blocking, optimizeTardiness) is read-only during optimization.
Example:
| FlowShopResult FlowShop::runNEH | ( | bool | blocking = false, |
| bool | optimizeTardiness = false ) |
Optimizes the flow shop schedule using the NEH heuristic.
The Nawaz-Enscore-Ham (NEH) algorithm is a polynomial-time approximation algorithm that produces high-quality solutions quickly:
Complexity: O(n² m) for makespan; O(n² m) for tardiness with due dates.
| blocking | If true, enforces job blocking: a job cannot leave machine i until machine i+1 is free (models buffer constraints) |
| optimizeTardiness | If true, minimizes total tardiness (sum of max(0, completion - due_date)); if false, minimizes makespan (final completion time) |
Example:
|
inline |
Replaces the due dates vector.
Sets new due dates for tardiness-based optimization. Must have exactly num_jobs elements.
| new_data | Rvalue reference to due dates vector (size = num_jobs) |
| std::runtime_error | if new_data.size() != num_jobs_ |
|
inline |
Replaces the entire processing times matrix and dimensions.
Sets new problem dimensions and processing time data. Validates that the data size matches dimensions. Resets due_dates to zero for all jobs.
| num_jobs | New number of jobs |
| num_machines | New number of machines |
| new_data | Rvalue reference to flattened m×n matrix (row-major, size = num_jobs × num_machines) |
| std::runtime_error | if new_data.size() != num_jobs * num_machines |