The (μ+1)(\mu+1) GA and the function Jumpk\mathrm{Jump}_k

Lax343628.Algorithm · concepts/Lax343628/Algorithm.lean · lax-343628

definition

Loading review…

Sign in with ORCID

Community review

Flags

Each flag is tied to a public ORCID identity and explains why this concept may be incorrect.

No flags have been submitted.

    Community review

    Flag this concept

    State precisely what appears incorrect. This explanation will be public under your ORCID name.

    No source line selected.

    Natural Language Statement

    Definition

    For x∈{0,1}nx\in\{0,1\}^n, let ∣x∣1|x|_1 be its number of ones. For a jump size k∈{1,…,n}k\in\{1,\dots,n\}, the function Jumpk ⁣:{0,1}n→N\mathrm{Jump}_k\colon\{0,1\}^n\to\mathbb N is

    Jumpk(x)={k+∣x∣1if ∣x∣1=n or ∣x∣1≤n−k,n−∣x∣1otherwise.\mathrm{Jump}_k(x)=\begin{cases}k+|x|_1 & \text{if } |x|_1=n \text{ or } |x|_1\le n-k,\\ n-|x|_1 & \text{otherwise.}\end{cases}

    The (μ+1)(\mu+1) genetic algorithm with crossover probability pc∈[0,1]p_c\in[0,1] maintains a population, a multiset of μ\mu individuals from {0,1}n\{0,1\}^n. One iteration, maximizing a fitness function ff, proceeds as follows:

    1. With probability pcp_c, choose two parents x,yx,y uniformly at random with replacement from the population. Create the offspring zz by uniform crossover of xx and yy, which takes each bit from xx or yy independently with probability 1/21/2, followed by standard bit mutation, which flips each bit independently with probability 1/n1/n.
    2. Otherwise, choose a parent xx uniformly at random and create zz by standard bit mutation of xx.
    3. Add zz to the population and remove an individual with the lowest fitness, breaking ties uniformly at random.
    Concept map
    1 concept; 3 descendants hidden
    100%
    Proven claimDefinitionThis conceptRelated conceptA → B: B builds on A

    Lean source view on GitHub

    1import Mathlib.Data.PNat.Basic
    2import Mathlib.Probability.Distributions.Uniform
    3import Mathlib.Probability.ProbabilityMassFunction.Constructions
    4
    5/-!
    6---
    7title: The (μ+1)(\mu+1) GA and the function Jumpk\mathrm{Jump}_k
    8type: definition
    9---
    10For x∈{0,1}nx\in\{0,1\}^n, let ∣x∣1|x|_1 be its number of ones. For a jump size k∈{1,…,n}k\in\{1,\dots,n\},
    11the function Jumpk ⁣:{0,1}n→N\mathrm{Jump}_k\colon\{0,1\}^n\to\mathbb N is
    12Jumpk(x)={k+∣x∣1if ∣x∣1=n or ∣x∣1≤n−k,n−∣x∣1otherwise.\mathrm{Jump}_k(x)=\begin{cases}k+|x|_1 & \text{if } |x|_1=n \text{ or } |x|_1\le n-k,\\ n-|x|_1 & \text{otherwise.}\end{cases}
    13
    14
    15The (μ+1)(\mu+1) genetic algorithm with crossover probability pc∈[0,1]p_c\in[0,1] maintains a
    16population, a multiset of μ\mu individuals from {0,1}n\{0,1\}^n. One iteration, maximizing a
    17fitness function ff, proceeds as follows:
    18
    191. With probability pcp_c, choose two parents x,yx,y uniformly at random with replacement from
    20 the population. Create the offspring zz by uniform crossover of xx and yy, which takes
    21 each bit from xx or yy independently with probability 1/21/2, followed by standard bit
    22 mutation, which flips each bit independently with probability 1/n1/n.
    232. Otherwise, choose a parent xx uniformly at random and create zz by standard bit mutation
    24 of xx.
    253. Add zz to the population and remove an individual with the lowest fitness, breaking ties
    26 uniformly at random.
    27-/
    28
    29namespace Lax343628.Algorithm
    30
    31open scoped ENNReal Classical BigOperators
    32
    33noncomputable section
    34
    35/-- A string in {0,1}n\{0,1\}^n. `Fin n` indexes positions 0,…,n−10,\ldots,n-1;
    36`Fin 2` consists of the values zero and one. -/
    37abbrev BitString (n : ℕ) := Fin n → Fin 2
    38
    39/-- A population of positive size μ\mu, with entries indexed separately even when equal.
    40An iteration writes the offspring into the slot of the deleted entry, or discards it if it
    41is deleted itself; up to the order of entries, this is adding it and then deleting. -/
    42abbrev Population (n : ℕ) (μ : ℕ+) := Fin (μ : ℕ) → BitString n
    43
    44/-- The number of one-bits in a string. -/
    45def ones {n : ℕ} (x : BitString n) : ℕ :=
    46 ∑ j : Fin n, (x j : ℕ)
    47
    48/-- The function Jumpk\mathrm{Jump}_k with jump size `k`, usually considered for n≥2n\ge2 and
    491≤k≤n/21\le k\le n/2. Fitness values are real numbers; natural-number subtraction is truncated
    50at zero. -/
    51def jump {n : ℕ} (k : ℕ) (x : BitString n) : ℝ :=
    52 if ones x ≤ n - k ∨ ones x = n then (k + ones x : ℕ) else (n - ones x : ℕ)
    53
    54/-- The all-one string 1n1^n, the unique optimum of Jumpk\mathrm{Jump}_k when 1≤k≤n1\le k\le n. -/
    55def optimum (n : ℕ) : BitString n := fun _ ↦ 1
    56
    57/-- A Bernoulli bit, equal to one with probability pp for 0≤p≤10\le p\le1.
    58Outside this interval it always returns the bit 0; all algorithm claims use valid probabilities. -/
    59def coin (p : ℝ) : PMF (Fin 2) :=
    60 if h : 0 ≤ p ∧ p ≤ 1 then
    61 PMF.ofFintype (fun b : Fin 2 ↦ ENNReal.ofReal (if b = 1 then p else 1 - p))
    62 -- Lean checks this proof that the probabilities sum to one; readers can skip it.
    63 (by simp_all [Fin.sum_univ_two, ← ENNReal.ofReal_add])
    64 else PMF.pure 0
    65
    66/-- Independent Bernoulli bits, each equal to one with probability pp: a string xx has
    67probability ∏jPr⁡[coin=xj]\prod_j \Pr[\text{coin}=x_j], which is p∣x∣1(1−p)n−∣x∣1p^{|x|_1}(1-p)^{n-|x|_1} for
    680≤p≤10\le p\le1. Here `coin p b` is the probability that the coin shows the bit `b`. -/
    69def independentBits (n : ℕ) (p : ℝ) : PMF (BitString n) :=
    70 PMF.ofFintype (fun x ↦ ∏ j, coin p (x j))
    71 -- Lean checks this proof that the probabilities sum to one; readers can skip it.
    72 (by
    73 have h := (coin p).tsum_coe
    74 rw [tsum_fintype] at h
    75 rw [← Fintype.prod_sum]
    76 simp [h])
    77
    78/-- Uniform crossover: at each position an independent fair mask bit selects one parent.
    79Sampling the mask uniformly among all bit strings gives independent fair choices. -/
    80def crossover {n : ℕ} (x y mask : BitString n) : BitString n :=
    81 fun j ↦ if mask j = 1 then x j else y j
    82
    83/-- Flip exactly the positions where the mutation mask is one. -/
    84def mutate {n : ℕ} (x mask : BitString n) : BitString n :=
    85 fun j ↦ if mask j = 1 then 1 - x j else x j
    86
    87/-- Uniform deletion among the μ+1\mu+1 entries of minimal `fitness`, including the offspring.
    88The minimum exists because the enlarged population is finite and nonempty. -/
    89def deletionIndex {n : ℕ} (fitness : BitString n → ℝ) {μ : ℕ+}
    90 (Q : Fin ((μ : ℕ) + 1) → BitString n) : PMF (Fin ((μ : ℕ) + 1)) :=
    91 PMF.uniformOfFinset
    92 (Finset.univ.filter fun i ↦ ∀ j, fitness (Q i) ≤ fitness (Q j))
    93 -- Lean checks this proof that a minimal entry exists; readers can skip it.
    94 (by simpa [Finset.filter_nonempty_iff] using Finite.exists_min fun j ↦ fitness (Q j))
    95
    96/-- One iteration of the (μ+1)(\mu+1) GA, maximizing `fitness`.
    97Crossover parents are independent uniform draws with replacement; the mutation-only
    98parent is uniform. Mutation flips each bit independently with probability 1/n1/n.
    99The offspring is inserted even if it equals an existing entry, before a worst entry is deleted.
    100Each `←` draws a sample from the distribution on its right. -/
    101def step {n : ℕ} (fitness : BitString n → ℝ) {μ : ℕ+} (p_c : ℝ) (P : Population n μ) :
    102 PMF (Population n μ) := do
    103 let useCrossover ← coin p_c
    104 -- `z'` is the uniform crossover of the parents `P u` and `P v`, or the parent `P u` itself.
    105 let z' ← if useCrossover = 1 then do
    106 let (u, v) ← PMF.uniformOfFintype (Fin (μ : ℕ) × Fin (μ : ℕ))
    107 let crossMask ← PMF.uniformOfFintype (BitString n)
    108 pure (crossover (P u) (P v) crossMask)
    109 else do
    110 let u ← PMF.uniformOfFintype (Fin (μ : ℕ))
    111 pure (P u)
    112 let flipMask ← independentBits n (1 / (n : ℝ))
    113 let z := mutate z' flipMask
    114 -- `Q` lists the μ + 1 entries: the population `P`, followed by the offspring `z`.
    115 let Q := Fin.lastCases z P
    116 let d ← deletionIndex fitness Q
    117 -- Deleting an old entry puts z into its slot; deleting the offspring (the last entry of
    118 -- `Q`) leaves P unchanged.
    119 pure (if h : d.val < (μ : ℕ) then Function.update P ⟨d.val, h⟩ z else P)
    120
    121end
    122end Lax343628.Algorithm
    123

    Discussion

    Ask a question or add context. Endorsements and structured flags are kept in the review panel above.

    Loading discussion…