FAQ Page for Assignment 4
NOTE: Most recent postings are at the top of this page; we will
update this as often as we can.
Dec 06:
- Here is a project graph analysis example that will surely make things a bit
less abstract and show you how concrete the whole concept can be. It's
worth reading, even if you have already finished A4.
Dec 05:
- There is an update at the end of the file on the
sample calculation
posted yesterday. It is a hint for a pure dynamic programming way of finding
the CP.
Dec 04:
- Q: Can we get a concrete example for calculating cp's on the fly?
I'm very confused on how one calculates the critical path WITHOUT calculating
LCT's first. There is no example of this in the handout.
A: See
sample calculation here.
- Here is a
sample A4 output
for A4 following the guidelines given below.
- Qs:
1. Do we really need to construct the CP within the ECT function without
callling LCT function? Maybe that's what u call constructing the CP when
calculating the g[i] on the fly. But after reading the FAQ on 29th, u said
that CP can also be constructed using ECT and LCT also. please verify this.
2. If yes, I really don't get an idea how to compute CP on the fly when we
calculate g[i]. Is that something we have to find the g[i] first, and then
using that result to find CP? Can u explained it a bit, I think many people
don't know how to do this.
3. Then u said we might need to construct the CP again use slack time from the
result get from calling the ECT and LCT function which is the g[i] and
h[i]. Ok, now if u said we have to find two CP one from ECT fucntion, one
from CPA function ( using sl[i]), which one will be the final for output,
and what is the rest one used for?
4. Do we lose mark if we calculate the g[i] and the call the LCT function, and
then construct the CP by h[i]-g[i] within the ECT function. and then in the
CPA fucntion, I just solve the sl[i]? I know this is something wierd, I have
no choice for now.
As:
1. If you read the FAQ carrefully, I recommend to compute CP on the fly
while computing the ECTs, because, this guarrantees you a correct answer.
2. Computing CP on the fly when we calculate g[i] means that, when you are at
vertex i and have computed the g[j] for all the j such that there is an
edge i->j, you look for the vertex j that is such that g[j]-g[i]=t_{i,j} and
you put it as next vetex on the critical path. You initialize this
computation of CP by putting 0 (the source) at the beginning of the CP.
3. You have to compute the CP only once. My suggestion is to do it while
computing the ECTs.
4. This is doable, but you seem to have missed the point of the important
remark posted yesterday: This method does not always guarrantee a correct
CP. So you'll loose some marks if you do so.
Dec 03:
- Since we're often referring to the solution to A2,
here is the
link to a
solution of A2.
- Output: Your program (that is the function printresults)
should output the project graph in a readable form (see A2), as a matrix.
Below the project graph, output g[], h[], sl[], and
the CP, each on a separate line; start each line by the name of the
vector, e.g., in a 4 vertices graph, you may have: g[] = 0, 6, 3, 2.
- Q:I think that for CP we have to find
if 0 = LateCom - earlycom - tij if this holds then
that is the route for the CP. Please correct me if I
am wrong.
A: You're wrong. Why? See the answer below.
Do the following instead: While computing the ECTs, record on the fly
those vertices i that are such that
earlycom(i) - earlycom(j) = t_{ij}.
- Q: What is Slack sl[j]? I don't understand what are you
really asking for?
A:
The value of sl[j] indicates the maximum amount of time that attaining
stage j can be delayed and still complete the entire project within the
shortest time possible.
We're asking you to compute the slack for each stage using the given
definition/recurrence.
- Q:
In the assignment, I've wrote all the functions using dynamic programming
techniques. However, in computing CP in the earlycompletion function, it
seems to me that a recursive function would work, and I can't think of a
dynamic programming technique that would do the job there.
My question:
is the CP computation intended to be using dynamic programming
techniques as well?
A: Good question! ONLY g[] and h[] are computed using
dynamic programming. The CP is computed on the fly while
computing the ECTs as I hinted below. Finally, computing the slacks is done
in an obvious way.
- Q: (1.) The last announcement under Novemeber 29 implies that
critical path must be calculated twice. So I assume
a) that what calculating the critical path after computing ECT, we must
use the definition on pg 2 of the handout and
b) when calculating the critical path for the cpa(...) function we are
free to use the definition on pg.1 of the handout (i.e. cp = path from 0
to n-1 such that, for every vertex in the path, sl(vertex) = 0.)
It seems to me that implementing the critical path using the def from
pg.2 is harder that computing it using the def from pg1.
(2.) In our report , are we to compute just 'one' complexity for the
entire CP algorithm?
(3.) Also, when determining the complexity for ECT, do we taken into
account that in our program we use earlycompletion(..) to calcuate a CP
and include this in analyzing complexity? Or is this ECT cp a program
requirement only and ignore it when doing algorithm complexity? Should
this cp and the one calculated in cpa(...) play a part in determining
the complexity of a CP?
(4.)Should the output of the printresults(...) contain both the critical
path calculated after earlycompletion(...) and the one calculated after
the cpa() ? (even if both cp's are the same?)
A: (1.) Use the definition on p. 2 of the handout (see also
the hint below); "cpa" has just to call the function where the ECT and the CP
are computed. (2.) -- (4.) Clear.
- Q: If my understanding is correct, I want to know what is
the meaning of each one of g[],h[], and sl[] , and
of the structures cpnode and graph:
g is used to calculate the Early completion time
h is used to calculate the Late completion time
Sl is used to calculate the sl[j]
CP is used to calulate the Critical path
However, what does the graph represent?
Are all the inputs in your test case in
vertex-order which means i->j then i
A: The understanding of the vectors g[],h[], and
sl[] is:
g[i] is used to store the early completion time for vertex i
h[i] is used to store the late completion time for vertex i
Sl[i] is used to store the slack for vertex i
CP is implemented as the structure cpnode which is used to
build nodes of a linked list representing the critical path.
The graph structure represent a very special adjacency matrix
where the value stored is the time duration attached to
the edge i -> j; = -1 in case there is no edge.
Finally, assume that all the inputs in test cases are such that
whenever i->j then i < j.
- (11:55 AM): Important Hint:
There is a theorem saying the following:
There is no slack at any vertex on a critical path
which can better be formulated as
Suppose CP is a critical path. Then CP has no slack
at any of its vertices.
The converse is not guarranteed to hold (as counterexamples exist). This
theorem says that, for any path, not having slacks at any of
one's vertices is a necessary condition, but not a sufficient one for
being a critical path. This is why an algorithm for finding critical paths
based on zero slacks does not guarantee that the
answer is indeed a critical path. So one should instead use the following
algorithm: while you are computing the ECT, you just keep track of which
vertex you've assigned as leading to this one in the 'max' selection, and
then that's the critical path you must output.
Nov 29:
Notice:
The #defines about the numbers of stages and jobs has been
moved to driver.cpp. That way, the sizes of a project graph would
not be hard-coded into projectgraph.*.
- Q: What's the difference between the two "addedges" and
"addedge" funcitons? I treat them as the same function, is that ok?
A: The difference is the same as between "addAdjacencies" and
"addAdjecency" in A2. The former calls the later to add an edge into
the graph after doing all the necessary checks (e.g. check whether
the edge already is there).
- Q:
I'm a little confused about ECT and LCT. If ECT is the earliest
completion time, shouldn't its value be the shortest time from g[1] to g[x].
How come in the example part, you've used the max? Shouldn't it be min?
(the question is reversed for LCT). Or have I misunderstood something?
A: The early completion times are really computed using "max", and
the late completion times are computed using "min". It's a matter of
definition. By working out a little example, you'll see why it is like
that.
- Q: Should we assume that the number of the source starts at 1?
If so, I will need to include some extra calculations to make it line up
with the way arrays are initialized.
A: In the C programming language, whenever you have n
vertices, assume that the indices start at 0 and end at n-1.
- Q:
What information do you want printed out with the printmatrix function.
I figure adjacencies and time values for pertinent edges.
A: Yes. Just the adjacencies and the recorded times.
- Q:
Could I make "graph" a 2D array such that if i-->j has a time = 3 then
graph[i][j] = 3?
A: Remember that in the starter code for A2, we told you that
C complains when you treat a pointer as a 2D array. So
use that kind of array that you used in A2. That is, a one-dimensional array
whose indices are computed manually: In the case of your example, you'll
have the assignment graph[i*size+j] = 3.
- Q: How does one track the weights of the various
edges in the program? I
have a feeling it has something to do with the variable "graph", which I
assume is a pointer to an array of integers. This would work if every
node had only ONE outgoing edge, but we need to be able to have nodes,
such as the source, to have many edges, each with their own weight.
A: The answer to this is somewhat very similar to the answer to the
question above. Using the method described in that answer, you can
record weights for multiple outgoing edges.
- Q:
Does NUMSTAGES represent the edges and NUMJOBS represent the nodes?
A: No. The opposite is true: NUMSTAGES represent the nodes and
NUMJOBS represent the edges?
- Q:
void earlycompletion(PROJECTGRAPH g, int size);
/* Compute the ECTs and the CP */
Is the comment a typo? How can we compute the CP without the LCT and
especially since we have a function that computes the CP for us:
void cpa(PROJECTGRAPH g, int size);
A: Though, according to the definition, you can compute the
the CP using both the ECTs and the LCTs, you may also do it on the fly while
computing the EXCTs alone. This is precisely what you should do. So this is
not a typo. Also, the name "cpa" given to the last function just means:
"Critical Path Analysis".
Nov 27:
- (2:00 PM): Oversight:
The handout says that the sample input has 43 jobs. There are in fact 41
jobs, not 43. So take care of this fact when using the sample input.
- Q: I'm looking at the sample graph in the handout and I see a
direct path from node#1 to node#7, with a time of 4.
Why can't cp be 1 --> 7? It's not as though we must visit every stage
in the project, i.e. every node in the graph, to complete it?
A: You may have many CPs in a project graph. They all must of course
satisfy the definiton of a CP. Also try to look for the CPs that are not
trivial! Going from vertex 1 directly to vertex 7 does not help you
in analysing a project graph.
- Q: Should we assume that the edges entered into
our program constitute a valid project graph, or should we (a) make sure
that the edges could in theory be arranged into a project graph and (b)
order the edges so that 0 is the starting point and n is the sink
A: You must assume that the input constitutes a valid project graph
as is. So make sure to have an input that is such that if there is an
edge i -> j then i < j.
Nov 26:
- (2:10 PM): Please recheck from time to time this page for oversights in
the handout. Also recheck the handout itself for corrections. two small
corrections this time are:
-- There is an error near the top of page 2 when it is talking
about the time, and says "For all i in S_j, vertex j
cannot be attained until at least a time t_{ij} after vertex
i has been attained". You should read this as
"For all j in S_i ..."
-- The definiton of "critical path" should start with
"This is a path ..." and not "This is the path ...".
- (2:08 PM): Hint: Hello all, the project graph really is directed.
Unlike in
A2 where you always added edges both ways. Here you do NOT always add
edges both ways. That is a technique for representing an undirected
graph using what is fundamentally a directed-graph-oriented data structure.
In A4 we have a directed graph.
printresults should display its values in matrix format. (The use
of seemingly one-dimensional arrays is to make it easier to make them
runtime-sized, just like in a2.) Keep the output very short in format
because it will already be a few pages of output.
- Q: If there are multiple critical paths, should we print them
all out, or just the first one we find?
A: Any one of them.
- (12:47 PM): Hint: most functions for graph operations are just a
slight modification of the one you got or wrote in A2!.
- (12:40 PM): A correction to the handout: you don't need to submit your
project graph. So you only submit projectgraph.cpp and the
report.