88from moorpy import helpers
99import yaml
1010from copy import deepcopy
11-
11+ import networkx as nx
1212
1313# Import select required helper functions
1414from famodel .helpers import (check_headings , head_adjust , getCableDD , getDynamicCables ,
1717 configureAdjuster , route_around_anchors )
1818
1919
20-
2120class Task ():
2221 '''
2322 A Task is a general representation of a set of marine operations
@@ -33,43 +32,36 @@ class Task():
3332
3433 '''
3534
36- def __init__ (self , taskType , name , ** kwargs ):
35+ def __init__ (self , actionList , name , ** kwargs ):
3736 '''Create an action object...
38- It must be given a name.
39- The remaining parameters should correspond to items in the actionType dict.. .
37+ It must be given a name and a list of actions .
38+ The action list should be by default coherent with actionTypes dictionary .
4039
4140 Parameters
4241 ----------
43- taskType : dict
44- Dictionary defining the action type (typically taken from a yaml) .
42+ actionList : list
43+ A list of all actions that are part of this task .
4544 name : string
4645 A name for the action. It may be appended with numbers if there
4746 are duplicate names.
4847 kwargs
49- Additional arguments may depend on the action type and typically
50- include a list of FAModel objects that are acted upon, or
51- a list of dependencies (other action names/objects).
48+ Additional arguments may depend on the task type.
5249
5350 '''
5451
55- # list of things that will be controlled during this action
56- self .vesselList = [] # all vessels required for the action
57- self .objectList = [] # all objects that are acted on
58- self .actionList = [] # all actions that are carried out in this task
59- self .dependencies = {} # list of other tasks this one depends on
60-
61- self .type = getFromDict (taskType , 'type' , dtype = str )
52+ self .actionList = actionList # all actions that are carried out in this task
6253 self .name = name
6354 self .status = 0 # 0, waiting; 1=running; 2=finished
6455
6556 self .duration = 0 # duration must be calculated based on lengths of actions
66-
57+ self .cost = 0 # cost must be calculated based on the cost of individual actions.
58+
6759 # what else do we need to initialize the task?
6860
69- # internal graph of the actions within this task?
61+ # internal graph of the actions within this task.
62+ self .G = self .getTaskGraph ()
7063
71-
72- def organizeActions (self , actions ):
64+ def organizeActions (self ):
7365 '''Organizes the actions to be done by this task into the proper order
7466 based on the strategy of this type of task...
7567 '''
@@ -85,4 +77,19 @@ def calcDuration(self):
8577 individual actions and their order of operation.'''
8678
8779 # Does Rudy have graph-based code that can do this?
88-
80+
81+ def getTaskGraph (self ):
82+ '''Generate a graph of the action dependencies.
83+ '''
84+
85+ # Create the graph
86+ G = nx .DiGraph ()
87+ for item , data in self .actionList .items ():
88+ for dep in data .dependencies :
89+ G .add_edge (dep , item , duration = data .duration ) # Store duration as edge attribute
90+
91+ # Compute longest path & total duration
92+ longest_path = nx .dag_longest_path (G , weight = 'duration' )
93+ longest_path_edges = list (zip (longest_path , longest_path [1 :])) # Convert path into edge pairs
94+ total_duration = sum (self .actionList [node ].duration for node in longest_path )
95+ return G
0 commit comments