a
    ‡ù»j]F  ã                
   @   sÞ   d Z ddlZddlZddlmZmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z( d	d
„ Z)dd„ Z*dd„ Z+ddd„Z,dS )a^  HiGHS Linear Optimization Methods

Interface to HiGHS linear optimization software.
https://highs.dev/

.. versionadded:: 1.5.0

References
----------
.. [1] Q. Huangfu and J.A.J. Hall. "Parallelizing the dual revised simplex
           method." Mathematical Programming Computation, 10 (1), 119-142,
           2018. DOI: 10.1007/s12532-017-0130-5

é    Né   )ÚOptimizeWarningÚOptimizeResult)Úwarn)Ú_highs_wrapper)Ú	CONST_INFÚMESSAGE_LEVEL_NONEÚHIGHS_OBJECTIVE_SENSE_MINIMIZEÚMODEL_STATUS_NOTSETÚMODEL_STATUS_LOAD_ERRORÚMODEL_STATUS_MODEL_ERRORÚMODEL_STATUS_PRESOLVE_ERRORÚMODEL_STATUS_SOLVE_ERRORÚMODEL_STATUS_POSTSOLVE_ERRORÚMODEL_STATUS_MODEL_EMPTYÚMODEL_STATUS_OPTIMALÚMODEL_STATUS_INFEASIBLEÚ$MODEL_STATUS_UNBOUNDED_OR_INFEASIBLEÚMODEL_STATUS_UNBOUNDEDÚ5MODEL_STATUS_REACHED_DUAL_OBJECTIVE_VALUE_UPPER_BOUNDÚ%MODEL_STATUS_REACHED_OBJECTIVE_TARGETÚMODEL_STATUS_REACHED_TIME_LIMITÚ$MODEL_STATUS_REACHED_ITERATION_LIMITÚHIGHS_SIMPLEX_STRATEGY_DUALÚ HIGHS_SIMPLEX_CRASH_STRATEGY_OFFÚ)HIGHS_SIMPLEX_EDGE_WEIGHT_STRATEGY_CHOOSEÚ*HIGHS_SIMPLEX_EDGE_WEIGHT_STRATEGY_DANTZIGÚ(HIGHS_SIMPLEX_EDGE_WEIGHT_STRATEGY_DEVEXÚ0HIGHS_SIMPLEX_EDGE_WEIGHT_STRATEGY_STEEPEST_EDGE)Ú
csc_matrixÚvstackÚissparsec                  C   sv   ddt dtdtdtdtdtdtdtdtdt	dt
dtdtdtd	td
i}d}| | |¡\}}|› d| › d|› d�}||fS )zCConverts HiGHS status number/message to SciPy status number/messageN)é   z%HiGHS did not provide a status code. )r"   Ú )é   r#   )r   z&Optimization terminated successfully. )r   zTime limit reached. )r   zIteration limit reached. )r$   zThe problem is infeasible. )é   zThe problem is unbounded. )r"   z(The problem is unbounded or infeasible. )r"   z*The HiGHS status code was not recognized. z(HiGHS Status z: ú))r
   r   r   r   r   r   r   ÚMODEL_STATUS_RDOVUBr   r   r   r   r   r   r   Úget)Úhighs_statusÚhighs_messageZscipy_statuses_messagesZunrecognizedZscipy_statusZscipy_message© r+   úCE:\soccer\ml_env\Lib\site-packages\scipy/optimize/_linprog_highs.pyÚ_highs_to_scipy_status_message7   s4    ð
ÿÿÿr-   c                 C   sP   t  | ¡}t jdd��& t  | | ¡t | |< W d   ƒ n1 sB0    Y  | S )NÚignore©Úinvalid)ÚnpÚisinfÚerrstateÚsignr   )ÚxZinfsr+   r+   r,   Ú_replace_infT   s    
4r6   c                 C   sŒ   z||   ¡  W S  ty(   ||   Y S  ty†   t t¡}|j| j}td|› d| › dt	| 
¡ ƒ› d|› d�	tdd� ||  Y S 0 d S )NzOption z is z, but only values in z are allowed. Using default: Ú.r%   ©Ú
stacklevel)ÚlowerÚAttributeErrorÚKeyErrorÚinspectÚ	signatureÚ_linprog_highsÚ
parametersÚdefaultr   ÚsetÚkeysr   )ÚoptionZ
option_strÚchoicesÚsigZdefault_strr+   r+   r,   Ú_convert_to_highs_enum\   s    

ÿþýrG   TFc           .      K   s†  |rd|› d�}t |tdd� t|	dttttddœd�}| \}}}}}}}}|j ¡ \}}t	j
d	d
��" t	 |¡ t	j }W d  ƒ n1 sŽ0    Y  |}|}|}t	 ||f¡}t	 ||f¡}t|ƒsÐt|ƒrÞt||fƒ}nt	 ||f¡}t|ƒ}|t||t|||||||tt|||
dœ} |  |¡ t|ƒ}t|ƒ}t|ƒ}t|ƒ}|du �s`t	 |¡dk�rlt	 d¡}n
t	 |¡}t||j|j|j||||| t	j¡| ƒ
}!d|!v �rÞ|!d }"t	 |"t |ƒd… ¡}#t	 |"dt |ƒ… ¡}"nd\}"}#d|!v �rZ|!d }$t	 |$dt |ƒ… ¡}%t	 |$t |ƒd… ¡}&t	 |!d ddd…f ¡}'t	 |!d ddd…f ¡}(nd\}%}&d\}'}(|! !dd¡})|! !dd¡}*t"|)|*ƒ\}+}d|!v �r¨t	 |!d ¡nd},|,|"|#t#|"|%dœƒt#|#|&dœƒt#|,du �rÚdn|,| |(dœƒt#|,du �rødn||, |'dœƒ|! !d¡|+|!d t$k||! !dd¡�p4|! !dd¡|! !d¡dœ}-t	 %|,¡�r‚|du�r‚|- |! !dd¡|! !dd¡|! !dd¡dœ¡ |-S ) aý  
    Solve the following linear programming problem using one of the HiGHS
    solvers:

    User-facing documentation is in _linprog_doc.py.

    Parameters
    ----------
    lp :  _LPProblem
        A ``scipy.optimize._linprog_util._LPProblem`` ``namedtuple``.
    solver : "ipm" or "simplex" or None
        Which HiGHS solver to use.  If ``None``, "simplex" will be used.

    Options
    -------
    maxiter : int
        The maximum number of iterations to perform in either phase. For
        ``solver='ipm'``, this does not include the number of crossover
        iterations.  Default is the largest possible value for an ``int``
        on the platform.
    disp : bool
        Set to ``True`` if indicators of optimization status are to be printed
        to the console each iteration; default ``False``.
    time_limit : float
        The maximum time in seconds allotted to solve the problem; default is
        the largest possible value for a ``double`` on the platform.
    presolve : bool
        Presolve attempts to identify trivial infeasibilities,
        identify trivial unboundedness, and simplify the problem before
        sending it to the main solver. It is generally recommended
        to keep the default setting ``True``; set to ``False`` if presolve is
        to be disabled.
    dual_feasibility_tolerance : double
        Dual feasibility tolerance.  Default is 1e-07.
        The minimum of this and ``primal_feasibility_tolerance``
        is used for the feasibility tolerance when ``solver='ipm'``.
    primal_feasibility_tolerance : double
        Primal feasibility tolerance.  Default is 1e-07.
        The minimum of this and ``dual_feasibility_tolerance``
        is used for the feasibility tolerance when ``solver='ipm'``.
    ipm_optimality_tolerance : double
        Optimality tolerance for ``solver='ipm'``.  Default is 1e-08.
        Minimum possible value is 1e-12 and must be smaller than the largest
        possible value for a ``double`` on the platform.
    simplex_dual_edge_weight_strategy : str (default: None)
        Strategy for simplex dual edge weights. The default, ``None``,
        automatically selects one of the following.

        ``'dantzig'`` uses Dantzig's original strategy of choosing the most
        negative reduced cost.

        ``'devex'`` uses the strategy described in [15]_.

        ``steepest`` uses the exact steepest edge strategy as described in
        [16]_.

        ``'steepest-devex'`` begins with the exact steepest edge strategy
        until the computation is too costly or inexact and then switches to
        the devex method.

        Currently, using ``None`` always selects ``'steepest-devex'``, but this
        may change as new options become available.

    mip_max_nodes : int
        The maximum number of nodes allotted to solve the problem; default is
        the largest possible value for a ``HighsInt`` on the platform.
        Ignored if not using the MIP solver.
    unknown_options : dict
        Optional arguments not used by this particular solver. If
        ``unknown_options`` is non-empty, a warning is issued listing all
        unused options.

    Returns
    -------
    sol : dict
        A dictionary consisting of the fields:

            x : 1D array
                The values of the decision variables that minimizes the
                objective function while satisfying the constraints.
            fun : float
                The optimal value of the objective function ``c @ x``.
            slack : 1D array
                The (nominally positive) values of the slack,
                ``b_ub - A_ub @ x``.
            con : 1D array
                The (nominally zero) residuals of the equality constraints,
                ``b_eq - A_eq @ x``.
            success : bool
                ``True`` when the algorithm succeeds in finding an optimal
                solution.
            status : int
                An integer representing the exit status of the algorithm.

                ``0`` : Optimization terminated successfully.

                ``1`` : Iteration or time limit reached.

                ``2`` : Problem appears to be infeasible.

                ``3`` : Problem appears to be unbounded.

                ``4`` : The HiGHS solver ran into a problem.

            message : str
                A string descriptor of the exit status of the algorithm.
            nit : int
                The total number of iterations performed.
                For ``solver='simplex'``, this includes iterations in all
                phases. For ``solver='ipm'``, this does not include
                crossover iterations.
            crossover_nit : int
                The number of primal/dual pushes performed during the
                crossover routine for ``solver='ipm'``.  This is ``0``
                for ``solver='simplex'``.
            ineqlin : OptimizeResult
                Solution and sensitivity information corresponding to the
                inequality constraints, `b_ub`. A dictionary consisting of the
                fields:

                residual : np.ndnarray
                    The (nominally positive) values of the slack variables,
                    ``b_ub - A_ub @ x``.  This quantity is also commonly
                    referred to as "slack".

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the right-hand side of the
                    inequality constraints, `b_ub`.

            eqlin : OptimizeResult
                Solution and sensitivity information corresponding to the
                equality constraints, `b_eq`.  A dictionary consisting of the
                fields:

                residual : np.ndarray
                    The (nominally zero) residuals of the equality constraints,
                    ``b_eq - A_eq @ x``.

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the right-hand side of the
                    equality constraints, `b_eq`.

            lower, upper : OptimizeResult
                Solution and sensitivity information corresponding to the
                lower and upper bounds on decision variables, `bounds`.

                residual : np.ndarray
                    The (nominally positive) values of the quantity
                    ``x - lb`` (lower) or ``ub - x`` (upper).

                marginals : np.ndarray
                    The sensitivity (partial derivative) of the objective
                    function with respect to the lower and upper
                    `bounds`.

            mip_node_count : int
                The number of subproblems or "nodes" solved by the MILP
                solver. Only present when `integrality` is not `None`.

            mip_dual_bound : float
                The MILP solver's final estimate of the lower bound on the
                optimal solution. Only present when `integrality` is not
                `None`.

            mip_gap : float
                The difference between the final objective function value
                and the final dual bound, scaled by the final objective
                function value. Only present when `integrality` is not
                `None`.

    Notes
    -----
    The result fields `ineqlin`, `eqlin`, `lower`, and `upper` all contain
    `marginals`, or partial derivatives of the objective function with respect
    to the right-hand side of each constraint. These partial derivatives are
    also referred to as "Lagrange multipliers", "dual values", and
    "shadow prices". The sign convention of `marginals` is opposite that
    of Lagrange multipliers produced by many nonlinear solvers.

    References
    ----------
    .. [15] Harris, Paula MJ. "Pivot selection methods of the Devex LP code."
            Mathematical programming 5.1 (1973): 1-28.
    .. [16] Goldfarb, Donald, and John Ker Reid. "A practicable steepest-edge
            simplex algorithm." Mathematical Programming 12.1 (1977): 361-371.
    zUnrecognized options detected: z). These will be passed to HiGHS verbatim.r%   r8   Ú!simplex_dual_edge_weight_strategyN)ZdantzigZdevexzsteepest-devexZsteepestN)rE   r.   r/   )ÚpresolveZsenseÚsolverÚ
time_limitZhighs_debug_levelÚdual_feasibility_toleranceÚipm_optimality_toleranceZlog_to_consoleÚmip_max_nodesZoutput_flagÚprimal_feasibility_tolerancerH   Zsimplex_strategyZsimplex_crash_strategyZipm_iteration_limitZsimplex_iteration_limitÚmip_rel_gapr   Úslack)NNÚlambdaZ	marg_bndsr   ÚstatusÚmessager5   )ZresidualZ	marginalsÚfunZsimplex_nitZipm_nitÚcrossover_nit)r5   rQ   ÚconZineqlinZeqlinr:   ÚupperrU   rS   ÚsuccessrT   ÚnitrV   Úmip_node_countÚmip_dual_boundg        Úmip_gap)r[   r\   r]   )&r   r   rG   r   r   r   r   ÚTÚcopyr1   r3   Z	ones_likeÚinfZconcatenater!   r    r   r	   r   r   r   Úupdater6   ÚsumÚemptyÚarrayr   ZindptrÚindicesÚdataZastypeZuint8Úlenr(   r-   r   r   Úany).ZlprJ   rK   rI   ZdispÚmaxiterrL   rO   rM   rH   rP   rN   Zunknown_optionsrT   Z&simplex_dual_edge_weight_strategy_enumÚcZA_ubZb_ubZA_eqZb_eqZboundsZx0ZintegralityZlbZubZlhs_ubZrhs_ubZlhs_eqZrhs_eqÚlhsÚrhsÚAÚoptionsÚresrQ   rW   ZlamdaZmarg_ineqlinZ
marg_eqlinZ
marg_upperZ
marg_lowerr)   r*   rS   r5   Zsolr+   r+   r,   r?   m   sØ     Fûý
0î

ÿ

ÿþþþþ
è


ýr?   )
NTFNNNNNNN)-Ú__doc__r=   Únumpyr1   Ú	_optimizer   r   Úwarningsr   Z_highs._highs_wrapperr   Z_highs._highs_constantsr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r'   r   r   r   r   r   r   r   r   r   Zscipy.sparser   r    r!   r-   r6   rG   r?   r+   r+   r+   r,   Ú<module>   s&   h        ù