最適化アルゴリズムExample集: Hock and Schittkowski Problem 74の疎な非線形計画法による解法 (nlp2_sparse_solve)
nAG数値計算ライブラリ > 最適化アルゴリズムExample集 > Hock and Schittkowski Problem 74の疎な非線形計画法による解法 (nlp2_sparse_solve)

非線形計画法-NLP(疎)

このExampleではHockとSchittkowskiの問題74を非線形計画法(NLP)で解いています。問題は4つの決定変数を持ち、6つの制約条件(3つの非線形制約、2つの線形制約、1つの変数の範囲制約)のもとで目的関数を最小化します。

目的関数:

タスク
Minimize f(x)=106x33+23106x43

目的関数は3次の項のみを含み、x3x4の変数のみに依存しています。係数は非常に小さい値(106のオーダー)です。

決定変数:

変数 範囲
x1 0.55x10.55
x2 0.55x20.55
x3 0x31200
x4 0x41200

制約条件:

制約
非線形制約1 1000sin(x10.25)+1000sin(x20.25)894.8
非線形制約2 1000sin(x10.25)+1000sin(x1x20.25)894.8
非線形制約3 1000sin(x20.25)+1000sin(x2x10.25)1294.8
線形制約1 x1x2x3+x40.55
線形制約2 x1x2+x3x40.55
変数の範囲制約 0.55x1,x20.55,0x3,x41200

非線形制約は三角関数の項を含み、線形制約は決定変数の1次式で表現されています。非線形制約の右辺は定数で、線形制約の右辺も定数になっています。変数の範囲制約は各変数の上限と下限を定義しています。

Exampleの実行コマンド:

python -m naginterfaces.library.examples.opt.nlp2_sparse_solve_ex

ソースコード表示コマンド:

python -c "import inspect; from naginterfaces.library.examples.opt import nlp2_sparse_solve_ex; print(''.join(inspect.getsourcelines(nlp2_sparse_solve_ex)[0]))"

出力結果例:

naginterfaces.library.opt.nlp2_sparse_solve Python Example Results.
Solve Hock and Schittkowski Problem 74.
Final objective value is 5.1264981e+03

マニュアル:

nlp2_sparse_solveのマニュアル

ソース:

#!/usr/bin/env python3
"``naginterfaces.library.opt.nlp2_sparse_solve`` Python Example."

# nAG Copyright 2017-2022.

# pylint: disable=invalid-name,too-many-locals

from math import cos, sin
import warnings

import numpy as np

from naginterfaces.base import utils
from naginterfaces.library import opt

def main():
    """
    Example for :func:`naginterfaces.library.opt.nlp2_sparse_solve`.

    Sparse NLP.

    >>> main()
    naginterfaces.library.opt.nlp2_sparse_solve Python Example Results.
    Solve Hock and Schittkowski Problem 74.
    Final objective value is 5.1264981e+03
    """

    print(
        'naginterfaces.library.opt.nlp2_sparse_solve Python Example Results.'
    )
    print('Solve Hock and Schittkowski Problem 74.')

    def cb_usrfun(_status, x, needf, f, needg, g):
        """The nonlinear constraints."""
        if needf > 0:
            f[:3] = [
                1000.*sin(-x[0]-0.25) + 1000.*sin(-x[1]-0.25),
                1000.*sin(x[0]-0.25) + 1000.*sin(x[0]-x[1]-0.25),
                1000.*sin(x[1]-0.25) + 1000.*sin(x[1]-x[0]-0.25),
            ]
            # There is no need to define the wholly linear
            # components f_3(x) and f_4(x)...
            f[5] = 1.e-6*x[2]**3 + 2.e-6*x[3]**3/3.
        if needg > 0:
            g = [
                -1000.*cos(-x[0]-0.25),
                -1000.*cos(-x[1]-0.25),
                1000.*cos(x[0]-0.25) + 1000.*cos(x[0]-x[1]-0.25),
                -1000.*cos(x[0]-x[1]-0.25),
                -1000.*cos(x[1]-x[0]-0.25),
                1000.*cos(x[1]-x[0]-0.25) + 1000.*cos(x[1]-0.25),
                3.e-6*x[2]**2,
                2.e-6*x[3]**2,
            ]
        return 0, f, g

    # Silence deprecation warning:
    warnings.simplefilter('ignore', utils.NagDeprecatedWarning)

    # Initialize the solver:
    comm = opt.nlp2_sparse_init()
    # Initial guess:
    x = [0., 0., 0., 0.]
    n = len(x)
    # There are six problem functions:
    nf = 6
    # The linear part of F and its packing information:
    a = [
        -1., -1., -1., 1., 1., -1., 3., 2.,
    ]
    nea = 8
    iafun = [1, 2, 4, 4, 5, 5, 6, 6]
    javar = [3, 4, 1, 2, 1, 2, 3, 4]
    # The coordinates of the nonzero elements of G:
    neg = 8
    igfun = [1, 1, 2, 2, 3, 3, 6, 6]
    jgvar = [1, 2, 1, 2, 1, 2, 3, 4]
    # Variable names:
    xnames = ['X1', 'X2', 'X3', 'X4']
    # Function names:
    fnames = [
        'NlnCon 1', 'NlnCon 2', 'NlnCon 3', 'LinCon 1', 'LinCon 2', 'Objectiv',
    ]
    # No constant objective term:
    objadd = 0.
    # Use row six of F as the objective:
    objrow = 6
    # Blank problem name:
    prob = ''
    # The bounds:
    xlow = [
        -0.55, -0.55, 0., 0.,
    ]
    flow = [
        -894.8, -894.8, -1294.8,
        -0.55, -0.55,
        -1.e+25,
    ]
    xupp = [
        0.55, 0.55, 1200., 1200.,
    ]
    fupp = [
        -894.8, -894.8, -1294.8,
        1.e+25, 1.e+25,
        1.e+25,
    ]
    # Cold start:
    start = 0
    # Initial state:
    xstate = np.zeros(n, dtype=int)
    f = np.zeros(nf)
    fstate = np.zeros(nf, dtype=int)
    fmul = np.zeros(nf)
    # No superbasics to specify:
    ns = 0

    nlp_soln = opt.nlp2_sparse_solve(
        start, objadd, objrow, prob,
        cb_usrfun, iafun, javar, nea, a, igfun, jgvar, neg,
        xlow, xupp, xnames, flow, fupp, fnames, x, xstate, f, fstate,
        fmul, ns, comm,
    )

    print('Final objective value is {:.7e}'.format(nlp_soln.f[objrow-1]))

if __name__ == '__main__':
    import doctest
    import sys
    sys.exit(
        doctest.testmod(
            None, verbose=True, report=False,
            optionflags=doctest.REPORT_NDIFF,
        ).failed
    )

関連情報
© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks