You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add plan for #301: [Model] MinimumDummyActivitiesPert
* Implement #301: [Model] MinimumDummyActivitiesPert
* chore: remove plan file after implementation
* Fix formatting after merge with main
* Fix dummy arc overcount on transitive arcs, add regression test, fix paper solve command
- Subtract task-arc intersections from dummy count: when a non-merged
arc's dummy coincides with a task arc, it doesn't add a new arc to the
event network and shouldn't be counted.
- Add regression test for DAG 0→1, 1→2, 0→2 (optimal = 0 dummies).
- Fix paper's pred solve command to include --solver brute-force.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix formatting after merge with main
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Given a precedence DAG $G = (V, A)$, find an activity-on-arc PERT event network with one real activity arc for each task $v in V$, minimizing the number of dummy activity arcs, such that for every ordered pair of tasks $(u, v)$ there is a path from the finish event of $u$ to the start event of $v$ if and only if $v$ is reachable from $u$ in $G$.
2143
+
][
2144
+
The decision version of minimum dummy activities appears as ND44 in Garey and Johnson's compendium @garey1979. It arises when an activity-on-node precedence DAG must be converted into an activity-on-arc PERT chart: merging compatible finish/start events removes dummy activities, but an over-aggressive merge creates spurious precedence relations between unrelated tasks. The implementation here enumerates, for each direct precedence arc, whether it is realized as an event merge or left as a dummy activity, so brute-force over the $m = #ne$ direct precedences yields a worst-case bound of $O^*(2^m)$. #footnote[No exact algorithm improving on the direct-precedence merge encoding implemented in the codebase is claimed here.]
2145
+
2146
+
*Example.* Consider the canonical precedence DAG on $n = #nv$ tasks with direct precedences #arcs.map(a => $(v_#(a.at(0)), v_#(a.at(1)))$).join(", "). The optimal encoding merges the predecessor-finish/successor-start pairs #merged.map(a => $(v_#(a.at(0)), v_#(a.at(1)))$).join(", "), so those handoffs need no dummy activity at all. The remaining direct precedences #dummy.map(a => $(v_#(a.at(0)), v_#(a.at(1)))$).join(" and ") still require dummy activities, so the optimum is $#opt$. Both unresolved precedences enter $v_3$, and merging either of them would identify unrelated task completions, creating spurious reachability between the two source tasks.
caption: [Canonical Minimum Dummy Activities in PERT Networks instance. Blue precedence arcs are encoded by merging the predecessor finish event with the successor start event; dashed gray arcs still require dummy activities. The optimal encoding leaves exactly #opt dummy activities.],
2177
+
) <fig:minimum-dummy-activities-pert>
2178
+
]
2179
+
]
2180
+
}
2181
+
2129
2182
#{
2130
2183
let x = load-model-example("MinimumFeedbackVertexSet")
0 commit comments