Artelys Knitro Artelys Knitro Home
  • Documentation
  • logo-new-blancArtelys
Python / Knitro API Julia / Knitro API

On this page

  • Introduction
  • Problem description
  • Input data
  • Model implementation
  • One shape, one solve
  • The same shape, with multistart
  • Every shape
  • What multistart is worth

Largest Diameter

Find the two points of a closed shape that lie furthest apart, when the shape is a black box the solver can only evaluate.

Notebook
Python / Knitro API Julia / Knitro API

Introduction

The goal of this example is to show a non-convex nonlinear problem involving a black-box function.

We consider a two-dimensional simple shape given as a function \(f: t \mapsto (x(t), y(t))\) that takes a parameter \(t \ge 0\) as input and returns the corresponding point in the plane. The goal is to find two points from the shape with the largest distance between them.

Example by Pierre Lemaire.

Problem description

Input

  • A closed shape \(f: t \mapsto (x(t), y(t))\), where \(t\) and \(t + 1\) give the same point

Variables

  • \(t_1, t_2 \ge 0\), the parameters of the 2 points we are looking for

Objective: maximize the distance between the two points

\[ \max_{t_1,\, t_2} \quad \sqrt{\big(x(t_2) - x(t_1)\big)^2 + \big(y(t_2) - y(t_1)\big)^2} \]

Note that there are no constraints.

The problem has the following properties:

  • 2 continuous variables: the parameters of the 2 points we are looking for
  • A black-box function
  • The black-box function is non-convex
  • The black-box function is “roughly” differentiable
  • An evaluation of the black-box function is cheap

The non-convexity of the objective function can be seen from the plots below. Indeed, the shapes contain multiple diameters that cannot be improved by infinitesimal changes of the variable values. These diameters all correspond to locally optimal solutions of the problem.

To illustrate this, we solve the problem first with the default configuration of Knitro. By default, Knitro stops as soon as it finds a locally optimal solution. Then we enable multistart. This option makes Knitro look for multiple locally optimal solutions and increases the chances of finding a globally optimal solution.

Input data

A shape is a function of one parameter returning a point. Shape holds that function and does nothing else. The parameter is reduced modulo one turn, so t and t + 1 give the same point, and the solver can wander outside [0, 1] without leaving the outline. Nothing about the geometry is exposed beyond the ability to call it.

Diameter carries what a solve returns, the length it found and the chord, the two parameters whose points lie that far apart.

struct Diameter
    length::Float64
    chord::Tuple{Float64,Float64}
end

struct Shape
    at::Function
    name::String
end

point(shape::Shape, t) = shape.at(t - floor(t))

Three kinds of outline are used. The rectangle is a control. It is convex, so its diameter is its diagonal. A blob is a circle whose radius is stirred by a mix of harmonics, deep enough that several chords cannot be lengthened by any small move, and a lower roughness keeps its lobes shallow. Each blob is seeded by its own number, so no two are alike and every run reproduces them.

Show the shape generators
function rectangle(width, height)
    function at(t)
        t < 0.25 && return (4 * width * t, 0.0)
        t < 0.50 && return (width, 4 * height * (t - 0.25))
        t < 0.75 && return (width - 4 * width * (t - 0.5), height)
        return (0.0, height - 4 * height * (t - 0.75))
    end
    return Shape(at, "rectangle($width, $height)")
end

const HARMONICS = [
    t -> cos(4 * pi * t),
    t -> sin(4 * pi * t),
    t -> cos(6 * pi * t),
    t -> sin(6 * pi * t),
    t -> cos(8 * pi * t),
    t -> exp(-25 * (t - 0.5)^2) - exp(-25 * 0.25),
]

function weights(seed, count)
    state = seed * 2654435761 % 2^31
    drawn = Float64[]
    for _ in 1:count
        state = (1103515245 * state + 12345) % 2^31
        push!(drawn, state / 2^31)
    end
    return drawn
end

function blob(seed; roughness=0.45)
    drawn = weights(seed, length(HARMONICS))
    amplitudes = [roughness * (2 * w - 1) / k for (k, w) in enumerate(drawn)]
    radius(t) = 1 + sum(a * f(t) for (a, f) in zip(amplitudes, HARMONICS))
    at(t) = (radius(t) * cos(2 * pi * t), radius(t) * sin(2 * pi * t))
    return Shape(at, "blob($seed)")
end

function transform(shape::Shape, matrix)
    function at(t)
        x, y = point(shape, t)
        return (
            matrix[1, 1] * x + matrix[1, 2] * y, matrix[2, 1] * x + matrix[2, 2] * y
        )
    end
    return Shape(at, "transform($(shape.name))")
end

The five shapes below are the convex control, three blobs of increasing waviness, and one of them stretched and sheared.

shapes = [
    rectangle(6, 8),
    blob(19),
    blob(14),
    blob(11),
    transform(blob(35), [1.4 0.0; 0.0 0.7]),
]

There are no axes. The coordinates say nothing on their own, only the form of the outline and the length of a chord across it. A chord that a solve stopped short at is drawn muted and dashed beside the best one found, so the two can be compared.

draw_all(shapes)
Shape AShape BShape CShape DShape E

Model implementation

using KNITRO

There is no expression to hand over, so the model is not built through JuMP here: KNITRO.jl also wraps Knitro’s C API one function at a time, and that is the layer callbacks live at. A context is created, two bounded variables are added to it, and the objective goes in as a function Knitro calls with a pair of parameter values.

function maximize_diameter(shape; multistart=false, num_threads=1)
    kc = KNITRO.KN_new()
    KNITRO.KN_add_vars(kc, 2, C_NULL)
    KNITRO.KN_set_var_lobnds_all(kc, [0.0, 0.0])
    KNITRO.KN_set_var_upbnds_all(kc, [1.0, 1.0])

    function objective(kc, cb, request, result, params)
        request.evalRequestCode == KNITRO.KN_RC_EVALFC || return -1
        t1, t2 = request.x
        result.obj[1] = hypot((point(shape, t2) .- point(shape, t1))...)
        return 0
    end

    KNITRO.KN_add_objective_callback(kc, objective)
    KNITRO.KN_set_obj_goal(kc, KNITRO.KN_OBJGOAL_MAXIMIZE)

    if multistart
        KNITRO.KN_set_int_param(kc, KNITRO.KN_PARAM_MSENABLE, KNITRO.KN_MS_ENABLE_YES)
        KNITRO.KN_set_int_param(kc, KNITRO.KN_PARAM_NUMTHREADS, num_threads)
    end

    KNITRO.KN_solve(kc)
    _, value, x, _ = KNITRO.KN_get_solution(kc)
    KNITRO.KN_free(kc)
    return Diameter(value, (x[1], x[2]))
end

evalRequestCode is checked because Knitro reuses one callback for several kinds of evaluation; returning -1 for anything else says this callback does not answer it. The value goes back in result.obj[1] rather than as a return value, the return code being reserved for whether the evaluation succeeded. No gradient is supplied, so Knitro takes finite differences of the same function, and that is why the shape has to be roughly differentiable.

One shape, one solve

By default, Knitro stops as soon as it finds a locally optimal solution, wherever the search happens to land.

single = maximize_diameter(shapes[2]);
=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    1.374231e+00   0.00e+00
      10    1.864329e+00   0.00e+00   2.08e-08   1.63e-07      0.19

EXIT: Locally optimal solution found.

Final Statistics
----------------
Final objective value               =   1.86432897978291e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   2.08e-08 / 2.08e-08
# of iterations                     =         10 
# of CG iterations                  =          0 
# of function evaluations           =         56
# of gradient evaluations           =          0
Total program time (secs)           =       0.19376 (     0.189 CPU time)
Time spent in evaluations (secs)    =       0.00064

================================================================================
Show the full outputHide the full output
draw(shapes[2]; chord=single.chord, title="One solve")
One solve, diameter 1.864t = 0.1325t = 0.5631

The same shape, with multistart

KN_PARAM_MSENABLE restarts the search from many initial parameter pairs and keeps the best. On a two-variable problem whose objective costs two function calls and a square root, that is cheap enough to be the default worth reaching for.

best = maximize_diameter(shapes[2]; multistart=true);
=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0      0      1.86433 0.00000e+00 2.07697e-08 3.04306e-03 3.82186e-03
     1    0      0      2.51988 0.00000e+00 8.37698e-08 1.62035e-03 5.56744e-03
     2    0      0      1.97992 0.00000e+00 3.31943e-06 1.03482e-03 6.71096e-03
     3    0      0      2.51988 0.00000e+00 6.42402e-07 1.07278e-03 7.89362e-03
     4    0      0      1.86433 0.00000e+00 4.36215e-07 1.15643e-03 9.16378e-03
     5    0      0      2.51988 0.00000e+00 4.19539e-08 1.16345e-03 1.04393e-02
     6    0      0      1.97992 0.00000e+00 8.91931e-07 1.09817e-03 1.16527e-02
     7    0      0      2.51988 0.00000e+00 8.72639e-07 1.02463e-03 1.27945e-02
     8    0      0      2.51988 0.00000e+00 1.09081e-07 1.15752e-03 1.40725e-02
     9    0      0      2.51988 0.00000e+00 2.25420e-08 1.38333e-03 1.55813e-02
    10    0      0      2.51988 0.00000e+00 1.80353e-07 1.15151e-03 1.68590e-02
    11    0      0      1.97992 0.00000e+00 4.60065e-09 1.07754e-03 1.80596e-02
    12    0      0      2.51988 0.00000e+00 1.26075e-07 1.09520e-03 1.92786e-02
    13    0      0      2.51988 0.00000e+00 1.12705e-08 1.20872e-03 2.06104e-02
    14    0      0      2.51988 0.00000e+00 2.22191e-08 1.48863e-03 2.22249e-02
    15    0      0      2.51988 0.00000e+00 1.34253e-07 1.08518e-03 2.34339e-02
    16    0      0      1.86433 0.00000e+00 9.06238e-09 1.20645e-03 2.47717e-02
    17    0      0      2.51988 0.00000e+00 1.40632e-08 1.09638e-03 2.59904e-02

MULTISTART: Best locally optimal solution is returned.
EXIT: Multi-start stopped because of a low estimated probability of finding
      an unobserved solution. Set ms_terminate=0 to disable multi-start rule-based
      termination procedure.
      18 solve(s) returned satisfactory solutions.

Final Statistics
----------------
Final objective value               =   2.51988484663122e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   1.09e-07 / 1.09e-07
# of iterations                     =        166 
# of CG iterations                  =          0 
# of function evaluations           =        946
# of gradient evaluations           =          0
Total program time (secs)           =       0.02606 (     0.026 CPU time)

================================================================================
Show the full outputHide the full output
draw(shapes[2]; chord=best.chord, missed=single.chord, title="With multistart")
With multistartt = 0.1325t = 0.5631t = 0.8808t = 0.3919one solve, 1.864multistart, 2.520

Both chords end on the outline and neither can be lengthened by nudging either end. The dashed one is a quarter shorter all the same.

Every shape

plain = [maximize_diameter(shape) for shape in shapes]
restarted = [maximize_diameter(shape; multistart=true) for shape in shapes];
Show the full outputHide the full output
=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    4.640061e+00   0.00e+00
      10    9.993806e+00   0.00e+00   4.80e+00   4.51e-03      0.04
      20    1.000000e+01   0.00e+00   5.00e-01   0.00e+00      0.05

EXIT: Primal feasible solution estimate cannot be improved; desired accuracy
      in dual feasibility could not be achieved.

HINT: Performance may improve by trying a different value for user option
      bar_murule or by enabling the concurrent solver (concurrent_solver=1).

Final Statistics
----------------
Final objective value               =   9.99999983588116e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   5.00e-01 / 3.47e-02
# of iterations                     =         20 
# of CG iterations                  =          5 
# of function evaluations           =        214
# of gradient evaluations           =          0
Total program time (secs)           =       0.04551 (     0.046 CPU time)
Time spent in evaluations (secs)    =       0.02075

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    1.374231e+00   0.00e+00
      10    1.864329e+00   0.00e+00   2.08e-08   1.63e-07      0.00

EXIT: Locally optimal solution found.

Final Statistics
----------------
Final objective value               =   1.86432897978291e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   2.08e-08 / 2.08e-08
# of iterations                     =         10 
# of CG iterations                  =          0 
# of function evaluations           =         56
# of gradient evaluations           =          0
Total program time (secs)           =       0.00167 (     0.002 CPU time)
Time spent in evaluations (secs)    =       0.00059

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    1.423355e+00   0.00e+00
       7    2.102511e+00   0.00e+00   3.96e-08   1.87e-06      0.00

EXIT: Locally optimal solution found.

Final Statistics
----------------
Final objective value               =   2.10251132372656e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   3.96e-08 / 9.73e-09
# of iterations                     =          7 
# of CG iterations                  =          0 
# of function evaluations           =         44
# of gradient evaluations           =          0
Total program time (secs)           =       0.00114 (     0.001 CPU time)
Time spent in evaluations (secs)    =       0.00046

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    1.418479e+00   0.00e+00
       9    2.353827e+00   0.00e+00   3.75e-08   3.44e-07      0.00

EXIT: Locally optimal solution found.

Final Statistics
----------------
Final objective value               =   2.35382655759700e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   3.75e-08 / 3.75e-08
# of iterations                     =          9 
# of CG iterations                  =          0 
# of function evaluations           =         54
# of gradient evaluations           =          0
Total program time (secs)           =       0.00123 (     0.001 CPU time)
Time spent in evaluations (secs)    =       0.00056

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3
Coefficient range:
  linear objective:          [0e+00, 0e+00] |                [0e+00, 0e+00]
  linear constraints:        [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic objective:       [0e+00, 0e+00] |                [0e+00, 0e+00]
  quadratic constraints:     [0e+00, 0e+00] |                [0e+00, 0e+00]
  variable bounds:           [1e+00, 1e+00] |                [1e+00, 1e+00]
  constraint bounds:         [0e+00, 0e+00] |                [0e+00, 0e+00]

Knitro using the Interior-Point/Barrier Direct algorithm.

    Iter       Objective  FeasError   OptError   ||Step||      Time 
--------  --------------  ---------  ---------  ---------  --------
       0    1.928182e+00   0.00e+00
       6    2.356799e+00   0.00e+00   4.69e-06   3.18e-05      0.00

EXIT: Locally optimal solution found.

Final Statistics
----------------
Final objective value               =   2.35679909647069e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   4.69e-06 / 7.23e-07
# of iterations                     =          6 
# of CG iterations                  =          0 
# of function evaluations           =         40
# of gradient evaluations           =          0
Total program time (secs)           =       0.00117 (     0.001 CPU time)
Time spent in evaluations (secs)    =       0.00050

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0   -102      10.0000 0.00000e+00    0.500000 2.31417e-03 2.80963e-03
     0    0      *      10.0000 0.00000e+00
     1    0   -102      10.0000 0.00000e+00    0.467589 1.70359e-03 4.65350e-03
     2    0   -102      10.0000 0.00000e+00    0.500000 7.31171e-02 7.79101e-02
     3    0   -102      10.0000 0.00000e+00    0.500000 2.52053e-02    0.103276
     4    0   -102      10.0000 0.00000e+00    0.500000 2.15240e-03    0.105565
     4    0      *      10.0000 0.00000e+00
     5    0   -102      10.0000 0.00000e+00    0.500000 2.21548e-03    0.107932
     6    0      0      10.0000 0.00000e+00 1.09855e-11 2.08072e-03    0.110158
     7    0   -102      10.0000 0.00000e+00    0.500000 1.83608e-03    0.112131
     8    0   -103      10.0000 0.00000e+00     6.67387 3.25957e-03    0.115543
     9    0   -102      10.0000 0.00000e+00     2.70977 2.54912e-03    0.118252
     9    0      *      10.0000 0.00000e+00
    10    0   -102      10.0000 0.00000e+00     10.9106 2.40306e-02    0.142442
    10    0      *      10.0000 0.00000e+00
    11    0   -102      10.0000 0.00000e+00    0.500000 2.90928e-03    0.145536
    12    0   -102      10.0000 0.00000e+00    0.500000 1.86104e-03    0.147541
    12    0      *      10.0000 0.00000e+00
    13    0      0      10.0000 0.00000e+00 1.98682e-07 1.75934e-03    0.149463
    14    0   -102      10.0000 0.00000e+00     2.76922 2.39383e-03    0.152008
    15    0   -102      10.0000 0.00000e+00    0.876471 2.04403e-03    0.154194
    16    0   -102      10.0000 0.00000e+00    0.500000 1.61240e-03    0.155936
    16    0      *      10.0000 0.00000e+00
    17    0   -102      10.0000 0.00000e+00    0.500000 1.64995e-03    0.157724
    17    0      *      10.0000 0.00000e+00
    18    0   -102      10.0000 0.00000e+00    0.500000 2.11815e-03    0.159982
    18    0      *      10.0000 0.00000e+00
    19    0   -101      10.0000 0.00000e+00    0.500000 2.26059e-03    0.162390

MULTISTART: Best locally optimal solution is returned.
EXIT: All multi-start solves have terminated.
      2 solve(s) returned satisfactory solutions.
      1 solve(s) reached xtol limit.
      16 solve(s) reached no improvement limit.
      1 solve(s) reached ftol limit.

Final Statistics
----------------
Final objective value               =   9.99999986251271e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   1.10e-11 / 7.63e-13
# of iterations                     =        469 
# of CG iterations                  =          0 
# of function evaluations           =       4742
# of gradient evaluations           =          0
Total program time (secs)           =       0.16246 (     0.162 CPU time)

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0      0      1.86433 0.00000e+00 2.07697e-08 1.17977e-03 1.72221e-03
     1    0      0      2.51988 0.00000e+00 8.37698e-08 1.40398e-03 3.22544e-03
     2    0      0      1.97992 0.00000e+00 3.31943e-06 9.54673e-04 4.27941e-03
     3    0      0      2.51988 0.00000e+00 6.42402e-07 1.00081e-03 5.38209e-03
     4    0      0      1.86433 0.00000e+00 4.36215e-07 1.10445e-03 6.59069e-03
     5    0      0      2.51988 0.00000e+00 4.19539e-08 1.12032e-03 7.81711e-03
     6    0      0      1.97992 0.00000e+00 8.91931e-07 1.07004e-03 8.99627e-03
     7    0      0      2.51988 0.00000e+00 8.72639e-07 9.97969e-04 1.01058e-02
     8    0      0      2.51988 0.00000e+00 1.09081e-07 1.11975e-03 1.13400e-02
     9    0      0      2.51988 0.00000e+00 2.25420e-08 1.35106e-03 1.28172e-02
    10    0      0      2.51988 0.00000e+00 1.80353e-07 1.13401e-03 1.40715e-02
    11    0      0      1.97992 0.00000e+00 4.60065e-09 1.06609e-03 1.52536e-02
    12    0      0      2.51988 0.00000e+00 1.26075e-07 1.06503e-03 1.64371e-02
    13    0      0      2.51988 0.00000e+00 1.12705e-08 1.22115e-03 1.77788e-02
    14    0      0      2.51988 0.00000e+00 2.22191e-08 1.51656e-03 1.94209e-02
    15    0      0      2.51988 0.00000e+00 1.34253e-07 1.09885e-03 2.06409e-02
    16    0      0      1.86433 0.00000e+00 9.06238e-09 1.21244e-03 2.19787e-02
    17    0      0      2.51988 0.00000e+00 1.40632e-08 1.09740e-03 2.31970e-02

MULTISTART: Best locally optimal solution is returned.
EXIT: Multi-start stopped because of a low estimated probability of finding
      an unobserved solution. Set ms_terminate=0 to disable multi-start rule-based
      termination procedure.
      18 solve(s) returned satisfactory solutions.

Final Statistics
----------------
Final objective value               =   2.51988484663122e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   1.09e-07 / 1.09e-07
# of iterations                     =        166 
# of CG iterations                  =          0 
# of function evaluations           =        946
# of gradient evaluations           =          0
Total program time (secs)           =       0.02327 (     0.023 CPU time)

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0      0      2.10251 0.00000e+00 3.96453e-08 9.88733e-04 1.50152e-03
     1    0      0      2.73711 0.00000e+00 2.57638e-08 1.30098e-03 2.90148e-03
     2    0      0      2.73711 0.00000e+00 2.29779e-07 1.25542e-03 4.25764e-03
     3    0      0      2.73711 0.00000e+00 1.65753e-07 1.06187e-03 5.42210e-03
     4    0      0      2.73711 0.00000e+00 1.03399e-07 1.20948e-03 6.73617e-03
     5    0      0      2.73711 0.00000e+00 5.74448e-09 1.26175e-03 8.10573e-03
     6    0      0      2.73711 0.00000e+00 7.21679e-07 1.25997e-03 9.48212e-03

MULTISTART: Best locally optimal solution is returned.
EXIT: Multi-start stopped because of a low estimated probability of finding
      an unobserved solution. Set ms_terminate=0 to disable multi-start rule-based
      termination procedure.
      7 solve(s) returned satisfactory solutions.

Final Statistics
----------------
Final objective value               =   2.73710681448387e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   7.22e-07 / 7.22e-07
# of iterations                     =         64 
# of CG iterations                  =          0 
# of function evaluations           =        374
# of gradient evaluations           =          0
Total program time (secs)           =       0.00954 (     0.009 CPU time)

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0      0      2.35383 0.00000e+00 3.75103e-08 1.24075e-03 1.81209e-03
     1    0      0      2.35383 0.00000e+00 2.22144e-07 1.54616e-03 3.46268e-03
     2    0      0      2.35383 0.00000e+00 4.41424e-08 1.01474e-03 4.57853e-03
     3    0      0      2.35383 0.00000e+00 7.35753e-09 1.08233e-03 5.76488e-03
     4    0      0      2.35383 0.00000e+00 1.30708e-08 1.37413e-03 7.24716e-03
     5    0      0      2.35383 0.00000e+00 7.19097e-08 1.31725e-03 8.67493e-03
     6    0      0      2.35383 0.00000e+00 8.01920e-07 1.53688e-03 1.03280e-02

MULTISTART: Best locally optimal solution is returned.
EXIT: Multi-start stopped because of a low estimated probability of finding
      an unobserved solution. Set ms_terminate=0 to disable multi-start rule-based
      termination procedure.
      7 solve(s) returned satisfactory solutions.

Final Statistics
----------------
Final objective value               =   2.35382655759700e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   7.19e-08 / 7.19e-08
# of iterations                     =         75 
# of CG iterations                  =          0 
# of function evaluations           =        415
# of gradient evaluations           =          0
Total program time (secs)           =       0.01039 (     0.010 CPU time)

================================================================================


=======================================
          Commercial License
         Artelys Knitro 16.0.0
=======================================

Knitro using 1 thread.
No start point provided -- Knitro computing one.

Knitro performing finite-difference gradient computation with 1 thread.
Knitro presolve eliminated 0 variables (0%) and 0 constraints (0%) in 0.00s.

feastol                  1e-06
feastol_abs              0.001
mip_numthreads           1
ms_enable                1
ms_numthreads            1
numthreads               1
opttol                   1e-06
opttol_abs               0.001

Problem Characteristics                     |           Presolved
-----------------------
Problem type: NLP (bound constrained)
Objective: maximize / general  
Number of variables:                      2 |                             2
  bounds:         lower     upper     range |     lower     upper     range
                      0         0         2 |         0         0         2
                             free     fixed |                free     fixed
                                0         0 |                   0         0
Number of constraints:                    0 |                             0
                    eq.     ineq.     range |       eq.     ineq.     range
  linear:             0         0         0 |         0         0         0
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          0         0         0 |         0         0         0
Number of nonzeros:
              objective  Jacobian   Hessian | objective  Jacobian   Hessian
  linear:             0         0           |         0         0          
  quadratic:          0         0         0 |         0         0         0
  nonlinear:          2         0         0 |         2         0         0
  total:              2         0         0 |         2         0         3

Knitro multistart will run with 1 thread.


Return codes description
------------------------
  0:  The final solution satisfies the termination conditions for verifying optimality.
  -100 to -199:  A feasible approximate solution was found.
  -200 to -299:  Knitro terminated at an infeasible point.
  -300 to -301:  The problem was determined to be unbounded.
  -400 to -499:  Knitro terminated because it reached a pre-defined limit.
    -400 to -409:  A feasible point was found.
    -410 to -419:  No feasible point was found.
  -500 to -599:  Knitro terminated with an input error or some non-standard error.
A more detailed description of individual return codes and their corresponding
termination messages is provided at
https://www.artelys.com/app/docs/knitro/3_referenceManual/returnCodes.html

 Solve Thrd Status   Objective   FeasError   Opt Error   Solve Time  Real Time 
 ----- ---- ------ ------------ ----------- ----------- ----------- -----------
     0    0      0      2.35680 0.00000e+00 4.69038e-06 1.03177e-03 1.60971e-03
     1    0      0      2.78954 0.00000e+00 9.41378e-07 1.23942e-03 2.94671e-03
     2    0      0      1.92686 0.00000e+00 2.71389e-07 1.12742e-03 4.17330e-03
     3    0      0      2.78954 0.00000e+00 1.16209e-07 1.39473e-03 5.67188e-03
     4    0      0      2.35680 0.00000e+00 1.04144e-07 1.00564e-03 6.78170e-03
     5    0      0      2.34668 0.00000e+00 2.96207e-07 1.40863e-03 8.29897e-03
     6    0      0      2.35680 0.00000e+00 8.09767e-08 1.15545e-03 9.56516e-03
     7    0      0      2.78954 0.00000e+00 1.16158e-08 1.45611e-03 1.11384e-02
     8    0      0      2.08788 0.00000e+00 4.78238e-06 1.08966e-03 1.23444e-02
     9    0      0      2.34668 0.00000e+00 4.52568e-07 1.03876e-03 1.35048e-02
    10    0      0      1.92686 0.00000e+00 1.76993e-07 1.28084e-03 1.49066e-02
    11    0      0      1.92686 0.00000e+00 1.16464e-08 1.20412e-03 1.62285e-02
    12    0      0      2.78954 0.00000e+00 3.35834e-07 1.31082e-03 1.76590e-02
    13    0      0      2.35680 0.00000e+00 2.33311e-06 1.24963e-03 1.90301e-02
    14    0      0      2.35680 0.00000e+00 6.94009e-08 1.18789e-03 2.03386e-02
    15    0      0      2.78954 0.00000e+00 6.36924e-08 1.05045e-03 2.15079e-02
    16    0      0      2.35680 0.00000e+00 7.44896e-12 9.98688e-04 2.26259e-02
    17    0      0      2.78954 0.00000e+00 2.58349e-09 1.29072e-03 2.40357e-02
    18    0      0      2.34668 0.00000e+00 4.11399e-07 1.42637e-03 2.55910e-02
    19    0      0      2.08788 0.00000e+00 2.92543e-06 1.10825e-03 2.68325e-02

MULTISTART: Best locally optimal solution is returned.
EXIT: All multi-start solves have terminated.
      20 solve(s) returned satisfactory solutions.

Final Statistics
----------------
Final objective value               =   2.78953619795665e+00
Final feasibility error (abs / rel) =   0.00e+00 / 0.00e+00
Final optimality error  (abs / rel) =   6.37e-08 / 6.37e-08
# of iterations                     =        158 
# of CG iterations                  =          0 
# of function evaluations           =        945
# of gradient evaluations           =          0
Total program time (secs)           =       0.02690 (     0.027 CPU time)

================================================================================
draw_diameters(shapes, plain, restarted)
rectangle(6, 8)t = 0.0000t = 0.5000t = 0.0000t = 0.5000one solve, 10.000multistart, 10.000blob(19)t = 0.1325t = 0.5631t = 0.8808t = 0.3919one solve, 1.864multistart, 2.520blob(14)t = 0.0000t = 0.3624t = 0.3016t = 0.7612one solve, 2.103multistart, 2.737blob(11)t = 0.2192t = 0.6722t = 0.6722t = 0.2192one solve, 2.354multistart, 2.354transform(blob(35))t = 0.0000t = 0.3663t = 0.3613t = 0.9051one solve, 2.357multistart, 2.790

What multistart is worth

Solving each shape both ways puts two numbers side by side, the first chord Knitro settles on and then the best of the restarts.

report_diameters(shapes, plain, restarted)
shape                 one solve  multistart     gain
----------------------------------------------------
rectangle(6, 8)          10.000      10.000    +0.0%
blob(19)                  1.864       2.520   +35.2%
blob(14)                  2.103       2.737   +30.2%
blob(11)                  2.354       2.354    +0.0%
transform(blob(35))       2.357       2.790   +18.4%

The rectangle is the control. It is convex, every local optimum is the global one, and the two solves agree exactly. So do some of the wrinkled outlines. On others the single solve lands a sixth to a quarter short of the answer. That is not a rounding gap but a different chord across a different pair of lobes.

The point is not the size of the gain but that nothing in the first solve tells you which case you are in. A black-box objective offers no bound and no certificate; the only evidence that a chord is the longest is having started from many places and come back to it.

 

Solved with Artelys Knitro · artelys.com