# CpmAnalyst Class

The algorithm here is that we start at the beginning, traversing each path, and advancing elapsed time by the duration of the edge as we cross each edge. We record the earliest time we reach each vertex - that is the earliest possible start for the principal edge if it is a pre-vertex, and the earlies possible completion if it is a postVertex. For the second pass, we take the "earliest" time that the finish vertex was reached, which is the earliest that the whole recipe can be completed. Using that as the overall duration, we traverse back- wards, subtracting the duration of each edge and assigning the time of arrival at each vertex as the "latest possible" start or finish. This works great until you start constraining vertices, with the Vertex Synchronizer. In this case, the synchronizer delineates a set of synchronized vertices, none of which can fire until all are ready to be fired. So the earliest a set of synchronized vertices can fire is the LATEST 'earliest' time that any of the member vertices can fire. So, we have a SynchronizerData object that tracks how many vertices in its member set have been visited, and does not allow traversal beyond that set of vertices until all of them have been visited and their 'earliest' settings set to the latest time that any of them were visited. Then, 'elapsedTime' is set to that 'latest' time, and all member vertices are used, in turn, as roots from which to probe forward.

**Namespace:**
Highpoint.Sage.Graphs.Analysis

**Assembly:**
Sage4 (in Sage4.dll)