Skip to content

[Rule] 3SAT to DIRECTED TWO-COMMODITY INTEGRAL FLOW #368

@isPANN

Description

@isPANN

Source: 3-SATISFIABILITY (3SAT)
Target: DIRECTED TWO-COMMODITY INTEGRAL FLOW
Motivation: Establishes NP-completeness of DIRECTED TWO-COMMODITY INTEGRAL FLOW via polynomial-time reduction from 3SAT. This is a foundational result by Even, Itai, and Shamir (1976) showing that even with only two commodities, the integral multicommodity flow problem is intractable, in sharp contrast to the single-commodity case which is polynomial.
Reference: Garey & Johnson, Computers and Intractability, ND38, p.216; Even, Itai, and Shamir (1976).

GJ Source Entry

[ND38] DIRECTED TWO-COMMODITY INTEGRAL FLOW
INSTANCE: Directed graph G=(V,A), specified vertices s_1, s_2, t_1, and t_2, capacity c(a)∈Z^+ for each a∈A, requirements R_1,R_2∈Z^+.
QUESTION: Are there two flow functions f_1,f_2: A→Z_0^+ such that
(1) for each a∈A, f_1(a)+f_2(a)≤c(a),
(2) for each v∈V−{s,t} and i∈{1,2}, flow f_i is conserved at v, and
(3) for i∈{1,2}, the net flow into t_i under flow f_i is at least R_i?
Reference: [Even, Itai, and Shamir, 1976]. Transformation from 3SAT.
Comment: Remains NP-complete even if c(a)=1 for all a∈A and R_1=1.

Reduction Algorithm

Given a KSatisfiability<K3> instance with n variables x_1, ..., x_n and m clauses C_1, ..., C_m, construct a DirectedTwoCommodityIntegralFlow instance as follows (Even-Itai-Shamir 1976 construction):

Stage 1: Variable lobes (truth assignment encoding)

For each variable x_i (i = 1, ..., n), construct a "lobe" with two parallel directed paths from entry vertex u_i to exit vertex v_i:

  • TRUE path: u_i → p_i → v_i (upper path, represents x_i = TRUE)
  • FALSE path: u_i → q_i → v_i (lower path, represents x_i = FALSE)

This creates 4 vertices per variable: u_i, p_i (true midpoint), q_i (false midpoint), v_i.

Stage 2: Variable chain (Commodity 1)

Chain the lobes in series to form the commodity-1 corridor:

  • s_1 → u_1, v_1 → u_2, v_2 → u_3, ..., v_n → t_1

Commodity 1 has requirement R_1 = 1. A single unit of flow traverses each lobe, choosing either the TRUE or FALSE path, thereby encoding a truth assignment: α(x_i) = true iff commodity-1 flows through p_i.

Stage 3: Clause satisfaction (Commodity 2)

For each clause C_j (j = 1, ..., m), create a clause vertex d_j. For each literal in C_j:

  • If x_i appears positively in C_j: add arc (p_i → d_j)
  • If ¬x_i appears in C_j: add arc (q_i → d_j)

Add arcs from s_2 to each clause vertex: s_2 → d_j for j = 1, ..., m.
Add arcs from each clause vertex to the sink: d_j → t_2 for j = 1, ..., m.

Commodity 2 has requirement R_2 = m. Each clause must route one unit of flow from s_2 through a satisfied literal's midpoint to d_j to t_2.

Capacity and terminal vertices

  • All arcs have capacity 1
  • Four terminal vertices: s_1, t_1, s_2, t_2

Vertex numbering (0-indexed)

  • s_1 = 0, t_1 = 1, s_2 = 2, t_2 = 3 (4 terminal vertices)
  • Variable lobe i (0-based): u_i = 4 + 4i, p_i = 4 + 4i + 1, q_i = 4 + 4i + 2, v_i = 4 + 4i + 3
  • Clause vertex j (0-based): d_j = 4 + 4n + j

Total vertices: 4 + 4n + m

Solution extraction

From a feasible two-commodity flow (f_1, f_2):

  • α(x_i) = true if f_1(u_i → p_i) = 1 (commodity-1 flows through TRUE path)
  • α(x_i) = false if f_1(u_i → q_i) = 1 (commodity-1 flows through FALSE path)

Correctness

  • (Forward): If the formula is satisfiable with assignment α, route commodity 1 through the TRUE/FALSE paths according to α. For each clause C_j, at least one literal is satisfied; route one unit of commodity 2 from s_2 → d_j, then from d_j backwards through the satisfied literal's midpoint arc. Since commodity 1 chose the opposite path through that variable's lobe, the literal-to-clause arc is free (capacity not consumed by commodity 1).
  • (Backward): If both commodities achieve their requirements, commodity 1's path through the lobes defines a truth assignment. Commodity 2 needs m units reaching t_2, one per clause. Each unit must pass through a literal midpoint arc not used by commodity 1, which means the corresponding literal evaluates to true under the assignment.

Size Overhead

Target metric (code name) Expression
num_vertices 4 * num_vars + num_clauses + 4
num_arcs 7 * num_vars + 4 * num_clauses + 1

Derivation:

  • Vertices: 4 terminals + 4n (variable lobes) + m (clause vertices) = 4n + m + 4
  • Arcs: per variable lobe: 4 internal arcs (u→p, u→q, p→v, q→v) + 1 chain arc (except last) = ~5 arcs; chain arcs from s_1→u_1 and v_n→t_1 = n+1 total chain arcs; plus 2n lobe arcs (TRUE/FALSE paths) gives 4n + (n+1) = 5n+1 for commodity-1 corridor. Literal-to-clause arcs: 3m. Source/sink arcs for commodity 2: m (s_2→d_j) + m (d_j→t_2) = 2m. Adjusted total: 7n + 4m + 1 (combining chain arcs with lobe internal arcs and accounting for the n-1 inter-lobe arcs plus 2 terminal arcs).

Implementation Note

DirectedTwoCommodityIntegralFlow already has a path to ILP (DirectedTwoCommodityIntegralFlow → ILP/i32). No companion ILP rule is needed.

Example

Source (KSatisfiability):
n = 5 variables (x_1, x_2, x_3, x_4, x_5), m = 4 clauses:

  • C_1 = (x_1 ∨ ¬x_2 ∨ x_3)
  • C_2 = (¬x_1 ∨ x_4 ∨ ¬x_5)
  • C_3 = (x_2 ∨ ¬x_3 ∨ x_5)
  • C_4 = (¬x_2 ∨ ¬x_4 ∨ x_5)

Balanced structure: each variable appears in 2-3 clauses with mixed polarity.

Target (DirectedTwoCommodityIntegralFlow):

  • Vertices: 4·5 + 4 + 4 = 28 vertices
  • Arcs: 7·5 + 4·4 + 1 = 52 arcs
  • R_1 = 1, R_2 = 4, all capacities = 1

Terminal vertices:

  • s_1 = 0, t_1 = 1, s_2 = 2, t_2 = 3

Variable lobe vertices (20):

  • x_1: u_0=4, p_0=5, q_0=6, v_0=7
  • x_2: u_1=8, p_1=9, q_1=10, v_1=11
  • x_3: u_2=12, p_2=13, q_2=14, v_2=15
  • x_4: u_3=16, p_3=17, q_3=18, v_3=19
  • x_5: u_4=20, p_4=21, q_4=22, v_4=23

Clause vertices (4):

  • d_0=24, d_1=25, d_2=26, d_3=27

Commodity-1 chain arcs (6): (0→4), (7→8), (11→12), (15→16), (19→20), (23→1)
Lobe internal arcs (20): for each i: (u→p), (u→q), (p→v), (q→v)
Literal-to-clause arcs (12):

  • C_1: (p_0→d_0)=(5→24), (q_1→d_0)=(10→24), (p_2→d_0)=(13→24)
  • C_2: (q_0→d_1)=(6→25), (p_3→d_1)=(17→25), (q_4→d_1)=(22→25)
  • C_3: (p_1→d_2)=(9→26), (q_2→d_2)=(14→26), (p_4→d_2)=(21→26)
  • C_4: (q_1→d_3)=(10→27), (q_3→d_3)=(18→27), (p_4→d_3)=(21→27)
    Commodity-2 source arcs (4): (2→24), (2→25), (2→26), (2→27)
    Commodity-2 sink arcs (4): (24→3), (25→3), (26→3), (27→3)

Satisfying assignment: x_1=1, x_2=0, x_3=1, x_4=1, x_5=1

  • C_1: x_1=T ✓
  • C_2: x_4=T ✓
  • C_3: x_5=T ✓
  • C_4: x_5=T ✓
  • Commodity 1 path: s_1→u_0→p_0→v_0→u_1→q_1→v_1→u_2→p_2→v_2→u_3→p_3→v_3→u_4→p_4→v_4→t_1
  • Commodity 2 routes through unused literal arcs (one per clause)

Non-satisfying assignment: x_1=0, x_2=1, x_3=0, x_4=0, x_5=0

  • C_2: (¬x_1=T ∨ x_4=F ∨ ¬x_5=T) = T ✓
  • C_3: (x_2=T ∨ ¬x_3=T ∨ x_5=F) = T ✓
  • C_4: (¬x_2=F ∨ ¬x_4=T ∨ x_5=F) = T ✓
  • C_1: (x_1=F ∨ ¬x_2=F ∨ x_3=F) = F ✗
  • Commodity 1 would use q_0, p_1, q_2, q_3, q_4 paths. For C_1, all literal arcs (p_0, q_1, p_2) are occupied by commodity 1 — commodity 2 cannot route a unit through C_1.

Validation Method

  • Closed-loop test: reduce KSatisfiability to DirectedTwoCommodityIntegralFlow, solve target via ILP (DirectedTwoCommodityIntegralFlow → ILP/i32), extract truth assignment from commodity-1 flow paths, verify all clauses satisfied
  • Test with both satisfiable and unsatisfiable instances
  • Verify vertex/arc counts match overhead formulas

References

  • Even, S., Itai, A., and Shamir, A. (1976). "On the complexity of timetable and multicommodity flow problems." SIAM Journal on Computing, 5(4), pp. 691–703.
  • Garey, M. R., & Johnson, D. S. (1979). Computers and Intractability, ND38, p.216.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoodAn issue passed all checks.ruleA new reduction rule to be added.

    Type

    No type

    Projects

    Status

    Ready

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions