Documentation

TauCeti.Combinatorics.Network.Augmentation

Walk assignments and augmentation along residual walks #

Weighting a directed walk p by q : K gives the arrow assignment walkAssignment p q, which places n • q on an arrow that p traverses n times; natural-number scalar multiplication needs no multiplicative structure on K. A walk from s to t raises the excess at t by q and lowers the excess at s by q, so a closed walk gives a circulation. A walk that repeats no arrow, such as a directed path or cycle, places q on each arrow it traverses and zero elsewhere. For 0 ≤ q it is then an ordinary s–t flow for any nonnegative capacities that are at least q along the walk.

Applied to the residual arrows of a feasible assignment, this is augmentation. Augmenting an ordinary s–t flow between distinct terminals s ≠ t along a residual walk that repeats no arrow, by an amount between zero and the residual capacities along the walk, gives a flow of value larger by that amount. The largest such amount is the bottleneck of the walk, its least residual capacity, which is positive on an augmenting path, where every residual capacity is positive. Directed paths and cycles repeat no arrow (TauCeti.ArrowWalk.IsPath.nodup_arrows, TauCeti.ArrowWalk.IsCycle.nodup_arrows), so all of this applies to them. Along a closed residual walk that repeats no arrow, the residual update preserves feasibility for arbitrary lower and upper bounds and preserves every excess: this is cycle augmentation of bounded circulations.

Main definitions #

Main results #

References #

Walk assignments #

noncomputable def TauCeti.walkAssignment {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t : V} (p : ArrowWalk Q s t) (q : K) :

The assignment of the walk p weighted by q: an arrow traversed n times by p carries n • q.

Instances For
    theorem TauCeti.walkAssignment_apply {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t : V} (p : ArrowWalk Q s t) (q : K) {x y : V} (e : Q x y) :
    @[simp]
    theorem TauCeti.Assignment.map_walkAssignment {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {L : Type u_1} {F : Type u_2} [AddMonoid L] [FunLike F K L] [AddMonoidHomClass F K L] (φ : F) {s t : V} (p : ArrowWalk Q s t) (q : K) :
    (walkAssignment p q).map ⇑φ = walkAssignment p (φ q)

    Additive coefficient maps commute with weighting a walk.

    @[simp]
    theorem TauCeti.walkAssignment_nil {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] (s : V) (q : K) :
    @[simp]
    theorem TauCeti.walkAssignment_zero {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t : V} (p : ArrowWalk Q s t) :
    @[simp]
    theorem TauCeti.walkAssignment_cons {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t x : V} (p : ArrowWalk Q s t) (e : Q t x) (q : K) :

    Extending a walk by an arrow adds the weight on that arrow.

    @[simp]
    theorem TauCeti.walkAssignment_comp {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t x : V} (p : ArrowWalk Q s t) (p' : ArrowWalk Q t x) (q : K) :

    The assignment of a concatenation is the sum of the assignments of its pieces.

    theorem TauCeti.walkAssignment_eq_zero_of_notMem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t : V} (p : ArrowWalk Q s t) (q : K) {x y : V} {e : Q x y} (he : ⟨x, ⟨y, e⟩⟩ ∉ p.arrows) :

    The assignment of a walk is zero on an arrow the walk does not traverse.

    theorem TauCeti.walkAssignment_eq_of_mem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {s t : V} {p : ArrowWalk Q s t} (hp : p.arrows.Nodup) (q : K) {x y : V} {e : Q x y} (he : ⟨x, ⟨y, e⟩⟩ ∈ p.arrows) :

    A walk that traverses no arrow twice carries its weight on each arrow it traverses.

    theorem TauCeti.walkAssignment_mem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] {S : Type u_1} [SetLike S K] [AddSubmonoidClass S K] {H : S} {s t : V} (p : ArrowWalk Q s t) {q : K} (hq : q ∈ H) {x y : V} (e : Q x y) :

    A walk assignment takes values in any additive submonoid containing the weight.

    theorem TauCeti.walkAssignment_nonneg {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] [Preorder K] [AddLeftMono K] {s t : V} (p : ArrowWalk Q s t) {q : K} (hq : 0 ≤ q) :

    A walk weighted by a nonnegative amount gives a nonnegative assignment.

    theorem TauCeti.walkAssignment_le {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] [Preorder K] {s t : V} {p : ArrowWalk Q s t} (hp : p.arrows.Nodup) {q : K} (hq : 0 ≤ q) {x y : V} (e : Q x y) :

    A walk that traverses no arrow twice carries at most its nonnegative weight on every arrow.

    theorem TauCeti.walkAssignment_mem_Icc {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] [Preorder K] {s t : V} {p : ArrowWalk Q s t} (hp : p.arrows.Nodup) {q : K} (hq : 0 ≤ q) {cap : Assignment Q K} (hcap : 0 ≤ cap) (hle : ∀ a ∈ p.arrows, q ≤ cap a.snd.snd) :

    Feasibility of a walk. A walk that traverses no arrow twice, weighted by q ≥ 0, lies between zero and any nonnegative capacities that are at least q on every arrow it traverses.

    theorem TauCeti.walkAssignment_bottleneck_le {V : Type u} {Q : V → V → Type v} {K : Type w} [AddMonoid K] [LinearOrder K] {f : Assignment Q K} (hf : 0 ≤ f) {s t : V} {p : ArrowWalk Q s t} (hp : p.arrows.Nodup) (hne : p.arrows ≠ []) :

    A walk that traverses no arrow twice, weighted by its bottleneck for a nonnegative assignment f, is bounded by f.

    theorem TauCeti.arrowSum_walkAssignment_univ_singleton {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommMonoid K] [Fintype V] [DecidableEq V] [(x y : V) → Fintype (Q x y)] {s t : V} (p : ArrowWalk Q s t) (q : K) (v : V) :

    The total value that a walk weighted by q brings into v is q times the number of visits of the walk to v after its start.

    @[simp]
    theorem TauCeti.excessAt_walkAssignment {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [DecidableEq V] {s t : V} (p : ArrowWalk Q s t) (q : K) (v : V) :
    excessAt (walkAssignment p q) v = (if v = t then q else 0) - if v = s then q else 0

    Excess of a walk. A walk from s to t weighted by q has excess q at t, excess -q at s, and zero excess elsewhere; for a closed walk the two cancel.

    theorem TauCeti.isCirculation_walkAssignment {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] {s : V} (c : ArrowWalk Q s s) (q : K) :

    A closed walk gives a circulation.

    noncomputable def TauCeti.walkFlow {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [Preorder K] {cap : Assignment Q K} {s t : V} (p : ArrowWalk Q s t) (hp : p.arrows.Nodup) {q : K} (hq : 0 ≤ q) (hcap : 0 ≤ cap) (hle : ∀ a ∈ p.arrows, q ≤ cap a.snd.snd) :
    Flow cap s t

    A walk from s to t that traverses no arrow twice, weighted by q ≥ 0, as an ordinary s–t flow for nonnegative capacities that are at least q on every arrow it traverses.

    Instances For
      @[simp]
      theorem TauCeti.walkFlow_toFun {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [Preorder K] {cap : Assignment Q K} {s t : V} {p : ArrowWalk Q s t} {hp : p.arrows.Nodup} {q : K} {hq : 0 ≤ q} {hcap : 0 ≤ cap} {hle : ∀ a ∈ p.arrows, q ≤ cap a.snd.snd} :
      (walkFlow p hp hq hcap hle).toFun = walkAssignment p q
      theorem TauCeti.val_walkFlow {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [Preorder K] {cap : Assignment Q K} {s t : V} {p : ArrowWalk Q s t} {hp : p.arrows.Nodup} {q : K} {hq : 0 ≤ q} {hcap : 0 ≤ cap} {hle : ∀ a ∈ p.arrows, q ≤ cap a.snd.snd} (hst : s ≠ t) :
      (walkFlow p hp hq hcap hle).val = q

      A walk between distinct vertices, weighted by q, is a flow of value q.

      theorem TauCeti.card_filter_pos_sub_walkAssignment_bottleneck_lt {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [LinearOrder K] [IsOrderedAddMonoid K] {f : Assignment Q K} {s t : V} {p : ArrowWalk Q s t} (hne : p.arrows ≠ []) (hpos : ∀ a ∈ p.arrows, 0 < f a.snd.snd) :
      {a : (x : V) × (y : V) × Q x y | 0 < (f - walkAssignment p (ArrowWalk.bottleneck f p hne)) a.snd.snd}.card < {a : (x : V) × (y : V) × Q x y | 0 < f a.snd.snd}.card

      Subtracting a nonempty walk of positive arrows, weighted by its bottleneck, strictly decreases the number of arrows of positive value: the arrows of positive value afterwards were positive before, and an arrow attaining the bottleneck becomes nonpositive. Repeated arrows may make the difference negative.

      theorem TauCeti.sub_walkAssignment_bottleneck_spec {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [LinearOrder K] [IsOrderedAddMonoid K] {S : Type u_1} [SetLike S K] [AddSubgroupClass S K] (H : S) {f : Assignment Q K} (hf : 0 ≤ f) (hH : ∀ ⦃x y : V⦄ (e : Q x y), f e ∈ H) {s t : V} {p : ArrowWalk Q s t} (hp : p.arrows.Nodup) (hne : p.arrows ≠ []) (hpos : ∀ a ∈ p.arrows, 0 < f a.snd.snd) :
      0 < ArrowWalk.bottleneck f p hne ∧ ArrowWalk.bottleneck f p hne ∈ H ∧ 0 ≤ f - walkAssignment p (ArrowWalk.bottleneck f p hne) ∧ (∀ ⦃x y : V⦄ (e : Q x y), (f - walkAssignment p (ArrowWalk.bottleneck f p hne)) e ∈ H) ∧ {a : (x : V) × (y : V) × Q x y | 0 < (f - walkAssignment p (ArrowWalk.bottleneck f p hne)) a.snd.snd}.card < {a : (x : V) × (y : V) × Q x y | 0 < f a.snd.snd}.card

      Subtracting a walk of positive arrows that traverses no arrow twice, weighted by its bottleneck, leaves a nonnegative assignment in the same additive subgroup and strictly decreases the number of positive arrows.

      theorem TauCeti.excessAt_sign_of_sub_walkAssignment {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] [PartialOrder K] [IsOrderedAddMonoid K] {f : Assignment Q K} {s t : V} (hst : s ≠ t) {p : ArrowWalk Q s t} {q : K} (hq : 0 < q) (hg : 0 ≤ f - walkAssignment p q) (hin : ∀ (w : V) (e : Q w s), f e = 0) (hout : ∀ (w : V) (e : Q t w), f e = 0) :
      excessAt f s < 0 ∧ 0 < excessAt f t ∧ (∀ (v : V), excessAt (f - walkAssignment p q) v < 0 → excessAt f v < 0) ∧ ∀ (v : V), 0 < excessAt (f - walkAssignment p q) v → 0 < excessAt f v

      Subtract a walk from s to t ≠ s, weighted by q > 0, from a nonnegative assignment f that vanishes on the arrows entering s and on the arrows leaving t, such that the difference g is still nonnegative. Then f has negative excess at s and positive excess at t, and every vertex of negative, respectively positive, excess for g has negative, respectively positive, excess for f.

      Augmentation #

      theorem TauCeti.excessAt_residualUpdate_walkAssignment_self {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Fintype V] [(x y : V) → Fintype (Q x y)] (f : Assignment Q K) {s : V} (c : ArrowWalk (ResidualHom Q) s s) (q : K) (v : V) :

      Cycle augmentation. Updating along a closed residual walk preserves the excess at every vertex. Together with residualUpdate_walkAssignment_mem_Icc, augmenting a bounded circulation along a residual cycle gives a bounded circulation.

      theorem TauCeti.residualUpdate_walkAssignment_mem_Icc {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Preorder K] [AddLeftMono K] {lo hi f : Assignment Q K} (hf : f ∈ Set.Icc lo hi) {s t : V} {p : ArrowWalk (ResidualHom Q) s t} (hp : p.arrows.Nodup) {q : K} (hq : 0 ≤ q) (hle : ∀ a ∈ p.arrows, q ≤ residualCapacity lo hi f a.snd.snd) :

      Feasibility of augmentation. Updating a feasible assignment f along a residual walk that traverses no arrow twice, by an amount between zero and the residual capacities along the walk, gives a feasible assignment. Lower bounds may be negative. For a closed walk, such as a residual cycle, the update also preserves every excess (excessAt_residualUpdate_walkAssignment_self).

      noncomputable def TauCeti.Flow.augmentWalk {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Preorder K] [AddLeftMono K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} (f : Flow cap s t) (p : ArrowWalk (ResidualHom Q) s t) (hp : p.arrows.Nodup) {q : K} (hq : 0 ≤ q) (hle : ∀ a ∈ p.arrows, q ≤ residualCapacity 0 cap f.toFun a.snd.snd) :
      Flow cap s t

      The augmentation of an ordinary s–t flow f along a residual walk from s to t that traverses no arrow twice, by an amount q between zero and the residual capacities along the walk: each forward residual arrow of the walk raises its arrow's value by q, and each reverse residual arrow lowers it by q.

      Instances For
        @[simp]
        theorem TauCeti.Flow.augmentWalk_toFun {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Preorder K] [AddLeftMono K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {q : K} {hq : 0 ≤ q} {hle : ∀ a ∈ p.arrows, q ≤ residualCapacity 0 cap f.toFun a.snd.snd} :
        @[simp]
        theorem TauCeti.Flow.val_augmentWalk {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Preorder K] [AddLeftMono K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {q : K} {hq : 0 ≤ q} {hle : ∀ a ∈ p.arrows, q ≤ residualCapacity 0 cap f.toFun a.snd.snd} (hst : s ≠ t) :
        (f.augmentWalk p hp hq hle).val = f.val + q

        Augmenting along a residual walk between distinct terminals increases the value by the augmenting amount.

        theorem TauCeti.Flow.augmentWalk_mem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [Preorder K] [AddLeftMono K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {q : K} {hq : 0 ≤ q} {hle : ∀ a ∈ p.arrows, q ≤ residualCapacity 0 cap f.toFun a.snd.snd} {S : Type u_1} [SetLike S K] [AddSubgroupClass S K] {H : S} (hf : ∀ ⦃v w : V⦄ (e : Q v w), f.toFun e ∈ H) (hqH : q ∈ H) {v w : V} (e : Q v w) :
        (f.augmentWalk p hp hq hle).toFun e ∈ H

        Augmenting a flow with values in an additive subgroup along a residual walk, by an amount in the subgroup, gives a flow with values in the subgroup.

        noncomputable def TauCeti.Flow.augmentBottleneck {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [IsOrderedAddMonoid K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} (f : Flow cap s t) (p : ArrowWalk (ResidualHom Q) s t) (hp : p.arrows.Nodup) (hne : p.arrows ≠ []) :
        Flow cap s t

        The augmentation of an ordinary s–t flow f along a residual walk from s to t that traverses an arrow but no arrow twice, by its bottleneck: the least residual capacity of an arrow of the walk, which is the largest amount that the residual capacities along the walk allow.

        Instances For
          @[simp]
          theorem TauCeti.Flow.augmentBottleneck_toFun {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [IsOrderedAddMonoid K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {hne : p.arrows ≠ []} :
          @[simp]
          theorem TauCeti.Flow.val_augmentBottleneck {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [IsOrderedAddMonoid K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {hne : p.arrows ≠ []} (hst : s ≠ t) :

          Augmenting along a residual walk between distinct terminals by its bottleneck increases the value by the bottleneck.

          theorem TauCeti.Flow.bottleneck_residualCapacity_mem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hne : p.arrows ≠ []} {S : Type u_1} [SetLike S K] [AddSubgroupClass S K] {H : S} (hcap : ∀ ⦃v w : V⦄ (e : Q v w), cap e ∈ H) (hf : ∀ ⦃v w : V⦄ (e : Q v w), f.toFun e ∈ H) :

          The bottleneck of a residual walk lies in an additive subgroup that contains the capacities and the flow values.

          theorem TauCeti.Flow.augmentBottleneck_mem {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [IsOrderedAddMonoid K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {hne : p.arrows ≠ []} {S : Type u_1} [SetLike S K] [AddSubgroupClass S K] {H : S} (hcap : ∀ ⦃v w : V⦄ (e : Q v w), cap e ∈ H) (hf : ∀ ⦃v w : V⦄ (e : Q v w), f.toFun e ∈ H) {v w : V} (e : Q v w) :
          (f.augmentBottleneck p hp hne).toFun e ∈ H

          Augmenting by the bottleneck preserves values in an additive subgroup that contains the capacities.

          theorem TauCeti.Flow.val_lt_val_augmentBottleneck {V : Type u} {Q : V → V → Type v} {K : Type w} [AddCommGroup K] [LinearOrder K] [IsOrderedAddMonoid K] [Fintype V] [(x y : V) → Fintype (Q x y)] {cap : Assignment Q K} {s t : V} {f : Flow cap s t} {p : ArrowWalk (ResidualHom Q) s t} {hp : p.arrows.Nodup} {hne : p.arrows ≠ []} (hst : s ≠ t) (hpos : ∀ a ∈ p.arrows, 0 < residualCapacity 0 cap f.toFun a.snd.snd) :
          f.val < (f.augmentBottleneck p hp hne).val

          Augmentation along an augmenting path. If every arrow of a residual walk between distinct terminals has positive residual capacity, as on an augmenting path, then augmenting by the bottleneck strictly increases the value of the flow.