System Requirements
- CMake >= 3.15
- A C++17 compiler (GCC >= 9, Clang >= 10, MSVC >= 19.20)
- Python development headers (for the Python bindings)
sudo apt-get install -y python3-dev
Installing OR-Tools (optional)
OR-Tools is enabled by default. Download the prebuilt C++ binary for your platform from the OR-Tools releases page, then install it:
sudo mkdir -p /opt/ortools
sudo tar -xzf /path/to/ortools.tar.gz -C /opt/ortools --strip-components=1
To build without OR-Tools, pass -DUSE_OR_TOOLS=OFF to CMake (see below).
Building
cmake -B build -S .
cmake --build build -j$(nproc)
CMake finds OR-Tools automatically if it is installed to /opt/ortools. To disable it:
cmake -B build -S . -DUSE_OR_TOOLS=OFF
cmake --build build -j$(nproc)
Running the Tests
./build/alpha_expansion_tests
First Example: C++
int main() {
model.set_unary_cost_fn([](int node, int label) -> int {
if (node == 0) return label == 0 ? 0 : 10;
if (node == 3) return label == 1 ? 0 : 10;
return 0;
});
model.add_neighbor(0, 1);
model.add_neighbor(1, 2);
model.add_neighbor(2, 3);
model.set_pairwise_cost_fn([](int, int, int l1, int l2) -> int {
return l1 == l2 ? 0 : 5;
});
auto factory = [](int v, int e) {
return std::make_unique<BKSolver<int>>(v, e);
};
int cycles = strategy.execute(optimizer, model);
for (int i = 0; i < 4; ++i)
printf("node %d -> label %d\n", i, model.get_label(i));
printf("converged in %d cycles, energy = %d\n", cycles, model.evaluate_total_energy());
return 0;
}
Performs alpha-expansion moves on an EnergyModel using a pluggable max-flow solver.
Definition AlphaExpansion.hpp:20
Stores the graph and energy costs for the Alpha-Expansion algorithm.
Definition EnergyModel.hpp:17
Expansion strategy that cycles through labels in fixed order 0, 1, …, K-1.
Definition SequentialStrategy.hpp:14
First Example: Python
import sys
sys.path.append('build')
import alpha_expansion_py as ae
model = ae.EnergyModel(4, 2, dtype='int32')
model.set_unary_cost_fn(lambda node, label:
(0 if label == 0 else 10) if node == 0 else
(0 if label == 1 else 10) if node == 3 else 0
)
model.add_neighbor(0, 1)
model.add_neighbor(1, 2)
model.add_neighbor(2, 3)
model.set_pairwise_cost_fn(lambda n1, n2, l1, l2: 0 if l1 == l2 else 5)
optimizer = ae.AlphaExpansionInt(model, 'bk')
strategy = ae.SequentialStrategyInt(max_cycles=100)
cycles = strategy.execute(optimizer, model)
print(model.get_labels())
print(f"energy: {model.evaluate_total_energy()}, cycles: {cycles}")