Graph
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#include <c_CPM.h>
|
||||
|
||||
|
||||
c_err_t c_CPM_Init(c_CPM_t* self, c_size_t num_tasks, const double* task_durations, c_Allocator_t* allocator) {
|
||||
if (!self || num_tasks == 0 || !task_durations) return C_ERR_PARAM;
|
||||
|
||||
self->allocator = allocator ? *allocator : c_DefaultAllocator;
|
||||
self->num_tasks = num_tasks;
|
||||
|
||||
/* Internal node architecture layout mapping:
|
||||
* - Task i start node: i
|
||||
* - Task i finish node: i + num_tasks
|
||||
* - Virtual source node: 2 * num_tasks
|
||||
* - Virtual sink node: 2 * num_tasks + 1
|
||||
*/
|
||||
self->source_node = 2 * num_tasks;
|
||||
self->sink_node = 2 * num_tasks + 1;
|
||||
self->V = 2 * num_tasks + 2;
|
||||
|
||||
return C_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
if (!self || !working_graph || prereq_task >= self->num_tasks || target_task >= self->num_tasks) return C_ERR_PARAM;
|
||||
|
||||
/* Connect the FINISH node of prereq to the START node of target */
|
||||
return c_EdgeWeightedDigraph_AddEdge(working_graph, prereq_task + self->num_tasks, target_task, 0.0);
|
||||
}
|
||||
|
||||
c_err_t c_CPM_Calculate(c_CPM_t* self, c_EdgeWeightedDigraph_t* working_graph) {
|
||||
if (!self || !working_graph) return C_ERR_PARAM;
|
||||
|
||||
/* Execute the linear Acyclic Longest Path pass from our virtual source anchor */
|
||||
return c_AcyclicLP_Init(&self->lp_engine, working_graph, self->source_node, &self->allocator);
|
||||
}
|
||||
|
||||
void c_CPM_Destroy(c_CPM_t* self) {
|
||||
if (!self) return;
|
||||
c_AcyclicLP_Destroy(&self->lp_engine);
|
||||
self->num_tasks = 0;
|
||||
self->source_node = 0;
|
||||
self->sink_node = 0;
|
||||
self->V = 0;
|
||||
}
|
||||
|
||||
c_err_t c_CPM_GetCriticalPath(c_CPM_t* self, c_VertexIdList_t* out_critical_edges) {
|
||||
if (!self || !out_critical_edges) return C_ERR_PARAM;
|
||||
return c_AcyclicLP_PathTo(&self->lp_engine, self->sink_node, out_critical_edges);
|
||||
}
|
||||
Reference in New Issue
Block a user