Skip to content

Commit e8af5f2

Browse files
committed
Initial commit
0 parents  commit e8af5f2

37 files changed

+4070
-0
lines changed

.gitignore

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
data/
2+
build/
3+
.cache/
4+
results/
5+
# Cmake
6+
.compile_commands
7+
CMakeLists.txt.user
8+
CMakeCache.txt
9+
CMakeFiles
10+
CMakeScripts
11+
Testing
12+
Makefile
13+
cmake_install.cmake
14+
install_manifest.txt
15+
compile_commands.json
16+
CTestTestfile.cmake
17+
_deps
18+
__pycache

CMakeLists.txt

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
cmake_minimum_required(VERSION 3.14)
2+
3+
project(PracticalMPC)
4+
5+
set(CMAKE_CXX_STANDARD 17)
6+
set(CMAKE_CXX_FLAGS "-Wall -Wextra -g")
7+
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g -DNDEBUG")
8+
set(CMAKE_CXX_FLAGS_RELEASE2 "-O3 -march=native -g -DNDEBUG")
9+
#-DCMAKE_BUILD_TYPE=Release
10+
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ")
11+
set(CMAKE_CXX_FLAGS_DEBUG2 "-O0 -g -fsanitize=address")
12+
13+
# Lemon and Eigen conflict
14+
set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1)
15+
16+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
17+
18+
include(FetchContent)
19+
FetchContent_Declare(
20+
googletest
21+
URL https://github.com/google/googletest/archive/15460959cbbfa20e66ef0b5ab497367e47fc0a04.zip
22+
)
23+
FetchContent_MakeAvailable(googletest)
24+
25+
FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.10.5/json.tar.xz)
26+
FetchContent_MakeAvailable(json)
27+
28+
FetchContent_Declare(
29+
cli11
30+
GIT_REPOSITORY https://github.com/CLIUtils/CLI11
31+
GIT_TAG 291c58789c031208f08f4f261a858b5b7083e8e2
32+
)
33+
FetchContent_MakeAvailable(cli11)
34+
35+
FetchContent_Declare(
36+
Eigen
37+
GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
38+
GIT_TAG 3.4.0
39+
)
40+
FetchContent_MakeAvailable(Eigen)
41+
42+
include(FetchContent)
43+
FetchContent_Declare(
44+
lemon
45+
URL file://${CMAKE_SOURCE_DIR}/ext/lemon-1.3.1.tar.gz
46+
)
47+
FetchContent_MakeAvailable(lemon)
48+
49+
include_directories(src)
50+
include_directories(${LEMON_SOURCE_DIR})
51+
include_directories(${LEMON_BINARY_DIR})
52+
53+
54+
add_subdirectory("src")
55+
add_subdirectory("test")
56+
add_subdirectory("prog")

LICENSE

+674
Large diffs are not rendered by default.

README.md

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Description
2+
3+
This repository contains **C++ implementations** of different fast algorithms for **Minimum Path Cover** (MPC).
4+
5+
> **Definition (MPC, MA and Dilworth's theorem)**
6+
>
7+
> Given a Directed Acyclic Graph (DAG) $G = (V, E)$, a *minimum path cover* (MPC) $\mathcal{P}$ of $G$ is a minimum-sized set of paths of $G$ such that every vertex of $V$ is contained in at least one path of $\mathcal{P}$. A *maxium antichain* (MA) $A$ of $G$ is a maximum-sized set of pairwise non-reachable vertices of $G$. Dilworth's theorem states that the number of paths in an MPC equals the number of vertices in an MA, this number $k$ is known as the *width*.
8+
9+
<p align="center">
10+
<img src="https://github.com/elarielcl/PracticalMPC/assets/2347684/b7d1ce33-ee83-4b6e-8d38-c2f6c0e38290" alt="MPC and MA of DAG" width="50%"/>
11+
</p>
12+
13+
## Algorithms
14+
15+
All algorithms implemented are based on a simple folklore reduction to **minimum flow**. The reduction builds a flow network $\mathcal{G}$ with a global source $s$ and a global sink $t$, and where every vertex $v$ of $V$ is **split** into an edge $(v^{in}, v^{out})$ with **demand** equal to $d(v^{in}, v^{out}) = 1$.
16+
17+
<p align="center">
18+
<img src="https://github.com/elarielcl/PracticalMPC/assets/2347684/27983a97-d92e-4bcb-a66d-9ccfe7b1c8b4" alt="Minimum Flow Reduction"width="50%"/>
19+
</p>
20+
21+
A **decomposition** of a minimum flow $f^*$ of $\mathcal{G}$ corresponds to an MPC of $G$.
22+
23+
### Initial solution
24+
25+
The corresponding minimum flow problem is reduced to a **maximum flow** instance by also providing a feasible flow $f$ of $\mathcal{G}$, equivalently a path cover in $G$, not necessarily an MPC. We implemented the following initial solutions:
26+
27+
- Naive: A path cover of $|V|$ paths, each path covers exactly one vertex. `naive` in program options.
28+
- Greedy: $O(\log{|V|})$-approximation based on greedy set cover [[1]](#references). `greedy` in program options.
29+
- Greedy Sparsified: Same as Greedy, but transitive edges are removed while obtaining new greedy paths. `greedy_sparsified` in program options.
30+
31+
### Solvers
32+
33+
We divide the flow solvers included into four categories.
34+
35+
#### MaxFlow-based own implementations
36+
37+
- `naive_minflow_solve`: Implements a simple DFS-based Ford-Fulkerson approach [[2]](#references)
38+
- `maxflow_solve_edmonds_karp`: Implements Edmonds-Karp algorithm [[3]](#references)
39+
- `maxflow_solve_edmonds_karp_DMOD`: Implements Dinitz's algorithm [[4]](#references)
40+
41+
#### MaxFlow-based LEMON [[5]](#references)
42+
43+
- `lemon_preflow`: LEMON solver using Goldberg-Tarjan algorithm [[6]](#references)
44+
45+
#### MinCostFlow-based LEMON [[5]](#references)
46+
47+
These solvers ignore the initial solution.
48+
49+
- `lemon_ns[_minlen]`: LEMON solver using Network Simplex [[7]](#references)
50+
- `lemon_caps[_minlen]`: LEMON solver using Capacity Scaling [[8]](#references)
51+
- `lemon_cc[_minlen]`: LEMON solver using Cycle Canceling [[9]](#references)
52+
- `lemon_cs[_minlen]`: LEMON solver using Cost Scaling [[10]](#references)
53+
54+
For these solvers, if used with suffix `_minlen` it outputs an MPC of minimum total length (sets cost one to edges).
55+
56+
#### Parameterized algorithms (own implementations)
57+
58+
These solvers ignore the initial solution.
59+
60+
- `pflowk3`: The first parameterized linear time solution running in time $O(k^3|V|+|E|)$ [[11]](#references).
61+
- `pflowk2`: Later improvement over `pflowk3` running in time $O(k^2|V|+|E|)$ [[12]](#references).
62+
63+
### Decomposition
64+
65+
All implementations use the same fast decomposition algorithm to obtain the MPC $\mathcal{P}$ from the minimum flow $f^*$.
66+
67+
## Pre-processing
68+
69+
There are also two heuristics for pre-processing $G$ before computing the MPC.
70+
71+
- `sparsify_dfs`: Removes transitive edges based on a DFS-traversal of $G$
72+
- `contract_graph`: Contracts root-to-leaf paths (in trees induced subgraphs) into vertices
73+
74+
## Compiling
75+
76+
```
77+
mkdir build
78+
cd build
79+
cmake ..
80+
make
81+
```
82+
Run cmake with `-DCMAKE_BUILD_TYPE=RELEASE` to disable debugs enable `O3` flag and `-DCMAKE_BUILD_TYPE=RELEASE2` to also enable `-march=native`.
83+
84+
## Running Experiments
85+
86+
`build/prog/exp` can be used to run experiments, for more information use `-h` argument.
87+
`ulimit -s unlimited` should be used if stack size is limited.
88+
```Usage: ./exp [OPTIONS]
89+
90+
Some options:
91+
-f TEXT REQUIRED Either a path to a file, which is of format
92+
<# of nodes> <# of edges>
93+
a line for each edge a->b of the form <a b>
94+
OR
95+
random_dag (N and M must be provided)
96+
OR
97+
random_x_chain (N, M, K must be provided)
98+
99+
-r TEXT:{naive,greedy,greedy_sparsified}
100+
initial solution to use
101+
-s TEXT:{pflowk2,pflowk3,lemon_ns[_minlen],lemon_cs[_minlen],lemon_cc[_minlen],lemon_caps[_minlen],naive_minflow_solve,lemon_preflow,maxflow_solve_edmonds_karp,maxflow_solve_edmonds_karp_DMOD} REQUIRED
102+
solver to use
103+
104+
--contract_graph BOOLEAN [0]
105+
contract graph in out tree
106+
--sparsify_dfs BOOLEAN [0] sparsify graph beforehand using the dfs sparsification
107+
108+
--seed INT [1337] seed to use when generating graphs
109+
--transitive_reduction BOOLEAN [0]
110+
Use transitive reduction of the graph instead
111+
--transitive_closure BOOLEAN [0]
112+
Use transitive closure of the graph instead
113+
-N INT N parameter for the graph generation (number of vertices)
114+
-M INT M parameter for the graph generation (number of edges)
115+
-K INT K parameter for the graph generation (initial width)
116+
```
117+
118+
119+
## Additional Features
120+
121+
Even though the main objective of the repo. is to be used to *conduct performance experiments* and *compare different algorithms* for MPC, at the moment it is also possible to:
122+
123+
> :warning: These features are not clearly exposed to a final user as they are still work in progress.
124+
125+
- Compute an MA (see [`./src/mpc/antichain.cpp`](src/mpc/antichain.cpp))
126+
- Compute a *weigthed* MA (see [`./prog/wac/`](prog/wac))
127+
- Compute a *minimum chain cover* (MCC) (see [`./src/mpc/cc.cpp`](src/mpc/cc.cpp))
128+
- Compute MPC-based reachability index (see [`./src/mpc/reach.cpp`](src/mpc/reach.cpp))
129+
- Compute transitive closure/reduction (see [`src/mpc/transitive.cpp`](src/mpc/transitive.cpp))
130+
- MPC heuristic preprocessing (*transitive edge sparsification* and *graph contraction*, see [`./src/mpc/preprocessing.cpp`](src/mpc/preprocessing.cpp))
131+
- DAG generators (see [`./src/mpc/graph.cpp`](src/mpc/graph.cpp))
132+
133+
## References
134+
135+
- [1] Mäkinen, V., Tomescu, A. I., Kuosmanen, A., Paavilainen, T., Gagie, T., & Chikhi, R. (2019). Sparse dynamic programming on DAGs with small width. ACM Transactions on Algorithms (TALG), 15(2), 1-21.
136+
- [2] Ford, L. R., & Fulkerson, D. R. (1956). Maximal flow through a network. Canadian journal of Mathematics, 8, 399-404.
137+
- [3] Edmonds, J., & Karp, R. M. (1972). Theoretical improvements in algorithmic efficiency for network flow problems. Journal of the ACM (JACM), 19(2), 248-264.
138+
- [4] Dinitz, Y. (2006). Dinitz’algorithm: The original version and Even’s version. In Theoretical Computer Science: Essays in Memory of Shimon Even (pp. 218-240). Berlin, Heidelberg: Springer Berlin Heidelberg.
139+
- [5] Dezső, B., Jüttner, A., & Kovács, P. (2011). LEMON–an open source C++ graph template library. Electronic notes in theoretical computer science, 264(5), 23-45.
140+
- [6] Goldberg, A. V., & Tarjan, R. E. (1988). A new approach to the maximum-flow problem. Journal of the ACM (JACM), 35(4), 921-940.
141+
- [7] Dantzig, G. (1963). Linear programming and extensions. Princeton university press.
142+
- [8] Edmonds, J., & Karp, R. M. (1972). Theoretical improvements in algorithmic efficiency for network flow problems. Journal of the ACM (JACM), 19(2), 248-264.
143+
- [9] Goldberg, A. V., & Tarjan, R. E. (1989). Finding minimum-cost circulations by canceling negative cycles. Journal of the ACM (JACM), 36(4), 873-886.
144+
- [10] Goldberg, A. V., & Tarjan, R. E. (1990). Finding minimum-cost circulations by successive approximation. Mathematics of Operations Research, 15(3), 430-466.
145+
- [11] Cáceres, M., Cairo, M., Mumey, B., Rizzi, R., & Tomescu, A. I. (2022). Sparsifying, shrinking and splicing for minimum path cover in parameterized linear time. In Proceedings of the 2022 Annual ACM-SIAM Symposium on Discrete Algorithms (SODA) (pp. 359-376). Society for Industrial and Applied Mathematics.
146+
- [12] Caceres, M., Cairo, M., Mumey, B., Rizzi, R., & Tomescu, A. I. (2022). Minimum path cover in parameterized linear time. arXiv preprint arXiv:2211.09659.
147+
148+
# Contact
149+
Any error, improvement or suggestion please contact the authors or create an issue in the repo.

ext/lemon-1.3.1.tar.gz

4.9 MB
Binary file not shown.

prog/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
add_subdirectory(wac)
2+
3+
add_executable(exp exp.cpp)
4+
target_link_libraries(exp mpc_lib nlohmann_json::nlohmann_json CLI11::CLI11 Eigen3::Eigen)
5+

0 commit comments

Comments
 (0)