79 lines
2.5 KiB
C
79 lines
2.5 KiB
C
#ifndef INCLUDED_C_CPM_H
|
|
#define INCLUDED_C_CPM_H
|
|
|
|
#ifndef INCLUDED_C_EDGEWEIGHTEDDIGRAPH_H
|
|
#include <c_EdgeWeightedDigraph.h>
|
|
#endif /*INCLUDED_C_EDGEWEIGHTEDDIGRAPH_H*/
|
|
|
|
|
|
#ifndef INCLUDED_C_ACYCLICLP_H
|
|
#include <c_AcyclicLP.h>
|
|
#endif /*INCLUDED_C_ACYCLICLP_H*/
|
|
|
|
|
|
#ifndef INCLUDED_C_VERTEXIDLIST_H
|
|
#include <c_VertexIdList.h>
|
|
#endif /*INCLUDED_C_VERTEXIDLIST_H*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
typedef struct {
|
|
c_AcyclicLP_t lp_engine; /* Inner longest-path engine */
|
|
c_size_t num_tasks; /* Raw number of user tasks */
|
|
c_size_t source_node; /* Virtual source node index */
|
|
c_size_t sink_node; /* Virtual sink node index */
|
|
c_size_t V; /* Total inner nodes count (2 * num_tasks + 2) */
|
|
c_Allocator_t allocator; /* Deep copy of the user-provided allocator */
|
|
} c_CPM_t;
|
|
|
|
|
|
/**
|
|
* @brief Initializes and executes the Critical Path Method scheduler.
|
|
* @param task_durations Array of doubles containing durations for each task (size = num_tasks)
|
|
* @param allocator Explicit allocator context used to configure internal tracking state memory
|
|
*/
|
|
c_err_t c_CPM_Init(c_CPM_t* self, c_size_t num_tasks, const double* task_durations, c_Allocator_t* allocator);
|
|
|
|
/**
|
|
* @brief Releases internal tracking buffers safely.
|
|
*/
|
|
void c_CPM_Destroy(c_CPM_t* self);
|
|
|
|
/**
|
|
* @brief Adds a dependency constraint indicating that 'prereq_task' must finish before 'target_task' can start.
|
|
*/
|
|
c_err_t c_CPM_AddDependency(c_CPM_t* self, c_EdgeWeightedDigraph_t* working_graph, c_size_t prereq_task, c_size_t target_task);
|
|
|
|
/**
|
|
* @brief Finalizes the calculation after all dependencies are added.
|
|
*/
|
|
c_err_t c_CPM_Calculate(c_CPM_t* self, c_EdgeWeightedDigraph_t* working_graph);
|
|
|
|
/**
|
|
* @brief Returns the minimum total project duration.
|
|
*/
|
|
C_STATIC_FORCE_INLINE
|
|
double c_CPM_GetProjectDuration(c_CPM_t* self) {
|
|
if (!self) return 0.0;
|
|
return c_AcyclicLP_DistTo(&self->lp_engine, self->sink_node);
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the Early Start (ES) time for a given task.
|
|
*/
|
|
C_STATIC_FORCE_INLINE
|
|
double c_CPM_GetEarlyStart(c_CPM_t* self, c_size_t task_id) {
|
|
if (!self || task_id >= self->num_tasks) return 0.0;
|
|
return c_AcyclicLP_DistTo(&self->lp_engine, task_id);
|
|
}
|
|
|
|
/**
|
|
* @brief Extracts the sequence of global edge IDs that form the critical path.
|
|
*/
|
|
c_err_t c_CPM_GetCriticalPath(c_CPM_t* self, c_VertexIdList_t* out_critical_edges);
|
|
|
|
|
|
#endif /*INCLUDED_C_CPM_H*/
|