Files

79 lines
2.5 KiB
C
Raw Permalink Normal View History

2026-09-07 18:48:16 +08:00
#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*/