def anneal_minimize(
    initial: T,
    cost_func: Callable[[T], float],
    move_func: Callable[[T], T],
    random_sample: Callable[[], float],
    temp_initial: float = 1.0e-2,
    temp_final: float = 1e-6,
    cooling_factor: float = 0.99,
    repeat: int = 100,
    trace_func: Callable[[T, float, float, float, bool], None] | None = None,
) -> T:
    """Minimize solution using Simulated Annealing meta-heuristic.

    Args:
        initial: Initial solution of type T to the problem.
        cost_func: Callable which takes current solution of type T, evaluates it
            and returns float with the cost estimate. The better solution is,
            the lower resulting value should be; negative values are allowed.
        move_func: Callable which takes current solution of type T and returns a
            new solution candidate of type T which is random iteration over
            input solution. The input solution, which is argument to this
            callback should not be mutated.
        random_sample: Callable which gives uniformly sampled random value from
            the [0, 1) interval on each call.
        temp_initial: Optional initial temperature for simulated annealing
            optimization. Scale of this value is cost_func-dependent.
        temp_final: Optional final temperature for simulated annealing
            optimization, where search should be stopped. Scale of this value is
            cost_func-dependent.
        cooling_factor: Optional factor to be applied to the current temperature
            and give the new temperature, this must be strictly greater than 0
            and strictly lower than 1.
        repeat: Optional number of iterations to perform at each given
            temperature.
        trace_func: Optional callback for tracing simulated annealing progress.
            This is going to be called at each algorithm step for the arguments:
            solution candidate (T), current temperature (float), candidate cost
            (float), probability of accepting candidate (float), and acceptance
            decision (boolean).

    Returns:
        The best solution found.

    Raises:
        ValueError: When supplied arguments are invalid.
    """

    if not 0.0 < cooling_factor < 1.0:
        raise ValueError("Cooling factor must be within (0, 1) range")

    temp = temp_initial
    sol = initial
    sol_cost = cost_func(initial)
    best = sol
    best_cost = sol_cost

    if trace_func:
        trace_func(sol, temp, sol_cost, 1.0, True)

    while temp > temp_final:
        for _ in range(repeat):
            # Find a new solution candidate and evaluate its cost.
            cand = move_func(sol)
            cand_cost = cost_func(cand)

            # Store the best solution, regardless if it is accepted or not.
            if best_cost > cand_cost:
                best = cand
                best_cost = cand_cost

            accepted, probability = _accept(random_sample(), cand_cost - sol_cost, temp)
            if accepted:
                sol = cand
                sol_cost = cand_cost

            if trace_func:
                trace_func(cand, temp, cand_cost, probability, accepted)

        temp *= cooling_factor

    return best
Minimize solution using Simulated Annealing meta-heuristic.

    Args:
        initial: Initial solution of type T to the problem.
        cost_func: Callable which takes current solution of type T, evaluates it
            and returns float with the cost estimate. The better solution is,
            the lower resulting value should be; negative values are allowed.
        move_func: Callable which takes current solution of type T and returns a
            new solution candidate of type T which is random iteration over
            input solution. The input solution, which is argument to this
            callback should not be mutated.
        random_sample: Callable which gives uniformly sampled random value from
            the [0, 1) interval on each call.
        temp_initial: Optional initial temperature for simulated annealing
            optimization. Scale of this value is cost_func-dependent.
        temp_final: Optional final temperature for simulated annealing
            optimization, where search should be stopped. Scale of this value is
            cost_func-dependent.
        cooling_factor: Optional factor to be applied to the current temperature
            and give the new temperature, this must be strictly greater than 0
            and strictly lower than 1.
        repeat: Optional number of iterations to perform at each given
            temperature.
        trace_func: Optional callback for tracing simulated annealing progress.
            This is going to be called at each algorithm step for the arguments:
            solution candidate (T), current temperature (float), candidate cost
            (float), probability of accepting candidate (float), and acceptance
            decision (boolean).

    Returns:
        The best solution found.

    Raises:
        ValueError: When supplied arguments are invalid.
    
cirq-google/cirq_google/line/placement/optimization.py