
    kh4                   ~   d dl mZ 	 d dlmZ d dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
 ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ d dlmZ d dlZ ej4                  e      Z	 ej<                  Ze!Z"ejF                  dvr	 d dl$m%Z% e%Z"	 d dlm%Z% e%Z"	 d dl'Z(d dl)Z) G d d      Z* G d de*      Z+ G d de"      Z, G d d      Z- G d de-      Z. G d de*      Z/ G d d      Z0 G d de0      Z1 G d  d!e1      Z2	 	 d%d"Z3d# Z4d$ Z5y# e$ r	 d dl mZ Y w xY w# e&$ r Y w xY w# e&$ r Y w xY w# e&$ r d dl(Z(Y w xY w)&    )annotations)CounterN)time)AnyLiteral   )LpSolverDefaultPULP_CBC_CMD)clock)value)	constants)mps_lp)Iterable)	maketrans)cli)OrderedDictc                     e Zd ZdZdZ ej                  d ej                  e       d      Z e	ed      Z
d Zd Z eee      Zd	 Zd
 Zd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!y)	LpElementz-Base class for LpVariable and LpConstraintVarz-+[] ->/[]________c                    |ri| j                   j                  |      r$t        j                  dj	                  |             t        |      j                  | j                        | _        y d | _        y )Nz=The name {} has illegal characters that will be replaced by _)	
expressionmatchwarningswarnformatstr	translatetrans_LpElement__nameselfnames     o/var/www/html/SchoolMeal/SchoolMeal/pds_admin_SchoolMeal/Backend/venv/lib/python3.12/site-packages/pulp/pulp.pysetNamezLpElement.setName   sW    $$T*SZZ
 d)--djj9DKDK    c                    | j                   S N)r!   r#   s    r%   getNamezLpElement.getName   s    {{r'   )fgetfsetc                @    || _         t        |       | _        d| _        y NT)r$   idhashmodifiedr"   s     r%   __init__zLpElement.__init__   s    	 tH	r'   c                    | j                   S r)   )r1   r*   s    r%   __hash__zLpElement.__hash__       yyr'   c                    | j                   S r)   r$   r*   s    r%   __str__zLpElement.__str__   r6   r'   c                    | j                   S r)   r8   r*   s    r%   __repr__zLpElement.__repr__   r6   r'   c                    t        |        S r)   LpAffineExpressionr*   s    r%   __neg__zLpElement.__neg__   s    "4(((r'   c                    | S r)    r*   s    r%   __pos__zLpElement.__pos__       r'   c                     yr/   rA   r*   s    r%   __bool__zLpElement.__bool__   s    r'   c                    t        |       |z   S r)   r=   r#   others     r%   __add__zLpElement.__add__       !$'%//r'   c                    t        |       |z   S r)   r=   rG   s     r%   __radd__zLpElement.__radd__   rJ   r'   c                    t        |       |z
  S r)   r=   rG   s     r%   __sub__zLpElement.__sub__   rJ   r'   c                    |t        |       z
  S r)   r=   rG   s     r%   __rsub__zLpElement.__rsub__   s    )$///r'   c                    t        |       |z  S r)   r=   rG   s     r%   __mul__zLpElement.__mul__   rJ   r'   c                    t        |       |z  S r)   r=   rG   s     r%   __rmul__zLpElement.__rmul__   rJ   r'   c                    t        |       |z  S r)   r=   rG   s     r%   __div__zLpElement.__div__   rJ   r'   c                    t        d      )Nz+Expressions cannot be divided by a variable)	TypeErrorrG   s     r%   __rdiv__zLpElement.__rdiv__   s    EFFr'   c                    t        |       |k  S r)   r=   rG   s     r%   __le__zLpElement.__le__       !$'500r'   c                    t        |       |k\  S r)   r=   rG   s     r%   __ge__zLpElement.__ge__   r\   r'   c                    t        |       |k(  S r)   r=   rG   s     r%   __eq__zLpElement.__eq__   r\   r'   c                    t        |t              r| j                  |j                  uS t        |t        t        f      r#|j                         r| |j                         uS yyr/   )
isinstance
LpVariabler$   r>   LpConstraintisAtomicatomrG   s     r%   __ne__zLpElement.__ne__  sP    eZ(99EJJ.. 2LAB~~5::<//r'   N)returnbool)"__name__
__module____qualname____doc__illegal_charsrecompileescaper   r   r    r&   r+   propertyr$   r3   r5   r9   r;   r?   rB   rE   rI   rL   rN   rP   rR   rT   rV   rY   r[   r^   r`   rg   rA   r'   r%   r   r      s    7 Ma			- 89;<JmZ0E
 w/D)0000000G111	r'   r   c                     e Zd ZdZddej
                  dfdZd ZeZe	d"d       Z
e
Zd Ze	dddej
                  g fd       Ze	dddej
                  g fd       Ze	ddej
                  fd	       Zd
 Zd Zd Zd Zd Zd#dZd$dZd Zd Zd%dZd Zd Zd Zd Zd Zd Zd&d'dZ d Z!d Z"d Z#d&dZ$d Z%d  Z&d! Z'y)(rc   aG  
    This class models an LP Variable with the specified associated parameters

    :param name: The name of the variable used in the output .lp file
    :param lowBound: The lower bound on this variable's range.
        Default is negative infinity
    :param upBound: The upper bound on this variable's range.
        Default is positive infinity
    :param cat: The category this variable is in, Integer, Binary or
        Continuous(default)
    :param e: Used for column based modelling: relates to the variable's
        existence in the objective function and constraints
    Nc                B   t         j                  | |       |x| _        | _        |x| _        | _        || _        d | _        d | _        |t        j                  k(  r1dx| _        | _        dx| _        | _        t        j                  | _        |r| j                  |       y y Nr   r   )r   r3   _lowbound_originallowBound_upbound_originalupBoundcatvarValuedjconstLpBinary	LpIntegeradd_expression)r#   r$   rw   ry   rz   es         r%   r3   zLpVariable.__init__  s     	4&2::$-077%.. 677D#dm455D"T\DH " r'   c                    t        | j                  | j                  | j                  | j                  | j
                  | j                        S )z
        Exports a variable into a dictionary with its relevant information

        :return: a dictionary with the variable information
        :rtype: dict
        )rw   ry   rz   r{   r|   r$   )dictrw   ry   rz   r{   r|   r$   r*   s    r%   toDictzLpVariable.toDict/  s;     ]]LL]]ww
 	
r'   c                2     | di |}||_         ||_        |S )aV  
        Initializes a variable object from information that comes from a dictionary (kwargs)

        :param dj: shadow price of the variable
        :param float varValue: the value to set the variable
        :param kwargs: arguments to initialize the variable
        :return: a :py:class:`LpVariable`
        :rtype: :LpVariable
        rA   )r|   r{   )clsr|   r{   kwargsvars        r%   fromDictzLpVariable.fromDictA  s"     mFm
r'   c                4    || _         | j                  |       y r)   )r   addVariableToConstraints)r#   r   s     r%   r   zLpVariable.add_expressionS  s    %%a(r'   c                F   t        |t              s|f}d|vr|dt        |      z  z  }|d   }|dd  }t        |      dk(  r,|D cg c]   }t        |t        ||gz         z  |||      " c}S |D cg c]   }t        j	                  |||||||gz         " c}S c c}w c c}w )N%_%sr   r   )rb   tuplelenrc   matrix)	r   r$   indicesrw   ry   rz   
indexStartindexis	            r%   r   zLpVariable.matrixW  s     '5)jGd?ECL((D
!"+w<1  4%
aS(8"998WcR  	  !!'8Wc:;K 
s   %B1%Bc           
     @   t        |t              s|f}d|vr|dt        |      z  z  }|d   }|dd }i }t        |      dk(  r3|D ],  }	t        |t        |t	        |	      gz         z  |||      ||	<   . |S |D ]#  }	t        j                  |||||||	gz         ||	<   % |S )a  
        This function creates a dictionary of :py:class:`LpVariable` with the specified associated parameters.

        :param name: The prefix to the name of each LP variable created
        :param indices: A list of strings of the keys to the dictionary of LP
            variables, and the main part of the variable name itself
        :param lowBound: The lower bound on these variables' range. Default is
            negative infinity
        :param upBound: The upper bound on these variables' range. Default is
            positive infinity
        :param cat: The category these variables are in, Integer or
            Continuous(default)

        :return: A dictionary of :py:class:`LpVariable`
        r   r   r   r   N)rb   r   r   rc   r   dicts)
r   r$   r   rw   ry   rz   r   r   dr   s
             r%   r   zLpVariable.dictsu  s    4 '5)jGd?ECL((D
!"+w<1 !5s1vh!6777C! 	  !'''8Wc:;K! r'   c                   t        |t              s|f}d|vr|dt        |      z  z  }|}t        |      dkD  rg }t        |      r\|d   }g }	|r2|r+|D ]%  }
|	j                  |D cg c]  }|
g|z   
 c}       ' n|}	|	}n|D 
cg c]  }
|
g }}
|d d }t        |      r\|D cg c]  }t        |       }}nt        |      dk(  r|d   }ni S i }|D ]  } | ||z  |||      ||<    |S c c}w c c}
w c c}w )Nr   r   r   r   )rb   r   r   extend)r   r$   r   rw   ry   rz   listsresfirstnresfrr   r   r   s                  r%   r   zLpVariable.dict  s2   '5)jGd?ECL((Dw<!Ce*b	!& @A KK#(>Q!q(>?@  #C(-.1A3.C.cr
 e* (++!U1X+E+\QAJEI 	9Atax7C8AaD	9! )?
 /+s   %C-

C2&C7c                    | j                   S r)   )rw   r*   s    r%   getLbzLpVariable.getLb      }}r'   c                    | j                   S r)   )ry   r*   s    r%   getUbzLpVariable.getUb  s    ||r'   c                .    || _         || _        d| _        y r/   )rw   ry   r2   )r#   lowups      r%   boundszLpVariable.bounds  s    r'   c                (    | j                  dd        y Nr   )r   r*   s    r%   positivezLpVariable.positive  s    Atr'   c                    | j                   S r)   )r{   r*   s    r%   r   zLpVariable.value  r   r'   c                D   | j                   | j                  d k7  rG| j                   | j                  kD  r.| j                   | j                  |z   k  r| j                  | _         nU| j                  d k7  rF| j                   | j                  k  r-| j                   | j                  |z
  k\  r| j                  | _         | j                  t        j
                  k(  rJt        t        | j                         | j                   z
        |k  rt        | j                         | _         y y y y r)   )r{   ry   rw   rz   r}   r   absround)r#   epsIntepss      r%   r   zLpVariable.round  s    ==$$MMDLL0MMT\\C%77 $%MMDMM1MMT]]S%88 $EOO+dmm,t}}<=G %dmm 4 H , %r'   c                    | j                   t        j                  k(  rR| j                  d k7  rCt	        | j                  t        | j                        z
        |k  rt        | j                        S | j                  S r)   )rz   r}   r   r{   r   r   r#   r   s     r%   roundedValuezLpVariable.roundedValue  sV    HH'%DMME$--$889S@''== r'   c                   | j                   d k7  r| j                   S | j                  d k7  rq| j                  d k7  rFd| j                  k\  rd| j                  k  ry| j                  dk\  r| j                  S | j                  S d| j                  k\  ry| j                  S | j                  d k7  rd| j                  k  ry| j                  S yr   )r{   rw   ry   r*   s    r%   valueOrDefaultzLpVariable.valueOrDefault  s    ==D == ]]d"||t#%!t||*;}})#}},#||+%==(\\T!DLL ||#r'   c                   | j                   dk(  r| j                  y| j                  y| j                  | j                  | j                  |z   kD  ry| j                  | j                  | j                  |z
  k  ry| j                  t
        j                  k(  r/t        t        | j                        | j                  z
        |kD  ryy)N__dummyTF)	r$   r{   ry   rw   rz   r}   r   r   r   r   s     r%   validzLpVariable.valid  s    99	!dmm&;== <<#s8J(J==$9L)LHH'E$--(4==89C?r'   c                   | j                   d k(  rt        d      | j                  d k7  r2| j                   | j                  kD  r| j                   | j                  z
  S | j                  d k7  r2| j                   | j                  k  r| j                   | j                  z
  S |rd| j                  t
        j                  k(  rGt        | j                         | j                   z
  dk7  r"t        | j                         | j                   z
  S y)Nzvariable value is Noner   )r{   
ValueErrorry   rw   rz   r}   r   r   )r#   mips     r%   infeasibilityGapzLpVariable.infeasibilityGap  s    ==D 566<<4DMMDLL$@==4<<//==D T]]T]]%B==4==00EOO+dmm$t}}49'$--77r'   c                    | j                   t        j                  k(  ry| j                   t        j                  k(  xr  | j                  dk(  xr | j
                  dk(  S )NTr   r   )rz   r}   r~   r   rw   ry   r*   s    r%   isBinaryzLpVariable.isBinary.  sE    88u~~%xx5??*Wt}}/AWdllVWFWWr'   c                <    | j                   t        j                  k(  S r)   )rz   r}   r   r*   s    r%   	isIntegerzLpVariable.isInteger3  s    xx5??**r'   c                >    | j                   d u xr | j                  d u S r)   rw   ry   r*   s    r%   isFreezLpVariable.isFree6  s    }}$=)==r'   c                T    | j                   d uxr | j                  | j                   k(  S r)   r   r*   s    r%   
isConstantzLpVariable.isConstant9  s#    }}D(JT\\T]]-JJr'   c                @    | j                   dk(  xr | j                  d u S r   r   r*   s    r%   
isPositivezLpVariable.isPositive<  s    }}!:dlld&::r'   c                   | j                         r| j                  dz   S | j                         r| j                  d| j                  dz   S | j                  d k(  rd}n?| j                  dk(  r | j                  t
        j                  k(  rd}n| j                  dd}|| j                  z  }| j                  |d| j                  dz  }|S )Nz freez = .12gz-inf <= r    z <= )r   r$   r   rw   rz   r}   LpContinuousry   r#   ss     r%   asCplexLpVariablezLpVariable.asCplexLpVariable?  s    ;;=99w&&??99T]]4$8999==D A ]]aDHH0B0B$BA==&d+A	TYY<<#4T*++Ar'   c                8    t        |       j                  ||      S r)   )r>   asCplexLpAffineExpressionr#   r$   include_constants      r%   r   z$LpVariable.asCplexLpAffineExpressionQ  s     !$'AA"
 	
r'   c                    t        |t              r| j                  |j                  uS t        |t        t        f      r#|j                         r| |j                         uS yyr/   )rb   r   r$   r>   rd   re   rf   rG   s     r%   rg   zLpVariable.__ne__V  sP    eY'99EJJ.. 2LAB~~5::<//r'   c                4    t        | j                               S r)   )ri   r   r*   s    r%   rE   zLpVariable.__bool__a  s    D%%'((r'   c                X    |j                         D ]  \  }}|j                  | |        y)zZadds a variable to the constraints indicated by
        the LpConstraintVars in e
        N)itemsaddVariable)r#   r   
constraintcoeffs       r%   r   z#LpVariable.addVariableToConstraintsd  s.     "# 	0J""4/	0r'   c           
        	 | j                   | j                  	ddfdfdd		fdfg}|D ]=  \  }}}}| |       s|s yt        dj                  | j                  |||             | _        y	)
a  
        sets the initial value of the variable to `val`
        May be used for warmStart a solver, if supported by the solver

        :param float val: value to set to variable
        :param bool check: if True, we check if the value fits inside the variable bounds
        :return: True if the value was set
        :raises ValueError: if check=True and the value does not fit inside the bounds
        smallerrw   c                      k  S r)   rA   )lbvals   r%   <lambda>z,LpVariable.setInitialValue.<locals>.<lambda>x  s    b r'   greaterry   c                      kD  S r)   rA   )ubr   s   r%   r   z,LpVariable.setInitialValue.<locals>.<lambda>y  s    sRx r'   Fz1In variable {}, initial value {} is {} than {} {}T)rw   ry   r   r   r$   r{   )
r#   r   checkconfigrel
bound_namebound_value	conditionr   r   s
    `      @@r%   setInitialValuezLpVariable.setInitialValuek  s     ]]\\
B(89	2'78

 8> 	3C[)&9;  GNN		3Z 		 r'   c                F    | j                   }|| j                  ||       yy)zk
        changes lower bound and upper bound to the initial value if exists.
        :return: None
        N)r{   r   )r#   r   s     r%   fixValuezLpVariable.fixValue  s%    
 mm?KKS! r'   c                "    | j                         S )zZ

        :return: True if upBound and lowBound are the same
        :rtype: bool
        )r   r*   s    r%   isFixedzLpVariable.isFixed  s       r'   c                P    | j                  | j                  | j                         y r)   )r   rv   rx   r*   s    r%   
unfixValuezLpVariable.unfixValue  s    D++T-C-CDr'   )NNh㈵>gHz>)r   r   T)r   ri   )(rj   rk   rl   rm   r}   r   r3   r   to_dictclassmethodr   	from_dictr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rg   rE   r   r   r   r   r   rA   r'   r%   rc   rc     s;    "4U5G5G4#$
  G  I)   :  + +Z *.%BTBT ! !F
5(!2 X
+>K;$

	)0:"!Er'   rc   c                      e Zd ZdZ edd      Zed)d       Zej                  d*d       Zd+d, fdZ	d Z
d Zd	 Zd
 Zd-dZd.dZd/dZd Zd Z	 d0	 	 	 d1dZd2dZd3d4dZed        Zd5dZ	 	 d0	 	 	 	 	 d6dZd7d8dZd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d  Z$d! Z%d" Z&d# Z'd$ Z(d9d%Z)d9d&Z*d9d'Z+d( Z,e,Z- xZ.S ):r>   a%  
    A linear combination of :class:`LpVariables<LpVariable>`.
    Can be initialised with the following:

    #.   e = None: an empty Expression
    #.   e = dict: gives an expression with the values being the coefficients of the keys (order of terms is undetermined)
    #.   e = list or generator of 2-tuples: equivalent to dict.items()
    #.   e = LpElement: an expression of length 1 with the coefficient 1
    #.   e = other: the constant is initialised as e

    Examples:

       >>> f=LpAffineExpression(LpElement('x'))
       >>> f
       1*x + 0
       >>> x_name = ['x_0', 'x_1', 'x_2']
       >>> x = [LpVariable(x_name[i], lowBound = 0, upBound = 10) for i in range(3) ]
       >>> c = LpAffineExpression([ (x[0],1), (x[1],-3), (x[2],4)])
       >>> c
       1*x_0 + -3*x_1 + 4*x_2 + 0
    z-+[] _____c                    | j                   S r)   )_LpAffineExpression__namer*   s    r%   r$   zLpAffineExpression.name      {{r'   c                j    |r*t        |      j                  | j                        | _        y d | _        y r)   )r   r   r    r   r"   s     r%   r$   zLpAffineExpression.name  s&    d)--djj9DKDKr'   c                   || _         |i }t        |t        t        f      r/|j                  | _        t
        |   |j                                y t        |t              r%|| _        t
        |   |j                                y t        |t              r|| _        t
        |   |       y t        |t              rd| _        t
        |   |dfg       y || _        t
        |           y ru   )r$   rb   r>   rd   constantsuperr3   r   r   r   r   )r#   r   r  r$   	__class__s       r%   r3   zLpAffineExpression.__init__  s    	9Aa,l;<JJDMGQWWY'4 $DMGQWWY'8$$DMGQ9%DMGq!fX&DMGr'   c                    t        |       dk(  xr6 | j                  dk(  xr% t        t        | j	                                     dk(  S Nr   r   r   r  nextitervaluesr*   s    r%   re   zLpAffineExpression.isAtomic  9    4yA~W$--1"4Wd4;;=>Q9RVW9WWr'   c                    t        |       dk(  S r   r   r*   s    r%   isNumericalConstantz&LpAffineExpression.isNumericalConstant  s    4yA~r'   c                F    t        t        | j                                     S r)   )r  r  keysr*   s    r%   rf   zLpAffineExpression.atom  s    D%&&r'   c                R    t        | j                        dk7  xs t        |       dkD  S N        r   floatr  r   r*   s    r%   rE   zLpAffineExpression.__bool__  #    dmm$+?TQ?r'   c                    | j                   }| j                         D ]%  \  }}|j                   y ||j                  |z  z  }' |S r)   r  r   r{   r#   r   vxs       r%   r   zLpAffineExpression.value  J    MMJJL 	 DAqzz!aA	  r'   c                z    | j                   }| j                         D ]  \  }}||j                         |z  z  } |S r)   r  r   r   r  s       r%   r   z!LpAffineExpression.valueOrDefault  A    MMJJL 	(DAq!!#a''A	(r'   c                2    || v r| |xx   |z  cc<   y || |<   y r)   rA   )r#   keyr   s      r%   addtermzLpAffineExpression.addterm  s     $;IIDIr'   c                    t               S r)   r=   r*   s    r%   	emptyCopyzLpAffineExpression.emptyCopy  s    !##r'   c                    t        |       S )z2Make a copy of self except the name which is resetr=   r*   s    r%   copyzLpAffineExpression.copy  s     "$''r'   c                   d}| j                         D ][  }| |   }|dk  r|dk7  r|dz  }n|dz  }| }n
|dk7  r|dz  }|dk(  r|t        |      z  }?|t        |      dz   t        |      z   z  }] |rS|| j                  n|}|dk(  rt        |      }|S |dk  r|dt        |       z   z  }|S |dkD  r|dt        |      z   z  }|S |dk(  rd}|S )	Nr   r   z - - + r   *0)sorted_keysr   r  )r#   r   override_constantr   r  r   r  s          r%   r9   zLpAffineExpression.__str__  s    !!# 	-Aq'CQw7JAHAdbU
axSVSX^c!f,,	- (9(At}}GXHBwM  a<hY//A
 	 \X..A  "WAr'   c                ^    t        | j                               }|j                  d        |S )z9
        returns the list of keys sorted by name
        c                    | j                   S r)   r8   r  s    r%   r   z0LpAffineExpression.sorted_keys.<locals>.<lambda>(  s
    !&& r'   r   )listr  sort)r#   results     r%   r+  zLpAffineExpression.sorted_keys#  s(     diik"()r'   c                    || j                   n|x}}| j                         D cg c]  }t        | |         dz   t        |      z   ! }}|j                  t        |             dj	                  |      }|S c c}w )Nr)  r(  )r  r+  r   appendjoin)r#   r,  r  r  lr   s         r%   r;   zLpAffineExpression.__repr__+  sv    .6DMM<M	
8 372B2B2DEQSa\C#a&(EE	XJJqM Fs   $A8c                &    t        d | D              S )Nc              3  2   K   | ]  }t        |        y wr)   r  ).0ts     r%   	<genexpr>z7LpAffineExpression._count_characters.<locals>.<genexpr>7  s     (a3q6(s   )sum)lines    r%   _count_charactersz$LpAffineExpression._count_characters4  s     (4(((r'   c                v   g }| dg}d}| j                         }|D ]  }| |   }|dk  rd}| }n|rd}nd}d}|dk(  r| d|j                   }	n| d|dz   dd|j                   }	| j                  |      t        |	      z   t        j
                  kD  r|dj                  |      gz  }|	g}||	gz  } ||fS )	z6
        helper for asCplexLpAffineExpression
        :r   z -z +r   r    r   )r+  r$   r?  r   r}   LpCplexLPLineSizer6  )
r#   r$   r3  r>  notFirst	variablesr  r   signterms
             r%   asCplexVariablesOnlyz'LpAffineExpression.asCplexVariablesOnly9  s     &
|$$&	 	Aq'CQwdHaxq) qqax8%%d+c$i7%:Q:QQ2774=/)v)	* t|r'   c                   | j                  |      \  }}| sd| j                   }n*d}|r&|| j                  n|}|dk  rd| z  }n
|dkD  rd| }| j                  |      t        |      z   t        j
                  kD  r|dj                  |      gz  }|g}n||gz  }|dj                  |      gz  }ddj                  |      z  }|S )U
        returns a string that represents the Affine Expression in lp format
        rB  r   r   z - %sr(  %s

)rH  r  r?  r   r}   rC  r6  )r#   r$   r   r,  r3  r>  rG  r  s           r%   r   z,LpAffineExpression.asCplexLpAffineExpressionX  s     006t}}o&DD%6%>DMMDU  a<"xi0D\ 
+D!!$'#d)3e6M6MMrwwt}o%F6DTFND2774=/!$))F++r'   c                   t        |t              r|dk(  r| S || S t        |t              r| j                  ||       | S t        |t        t
        f      rQ| xj                  |j                  |z  z  c_        |j                         D ]  \  }}| j                  |||z          | S t        |t              r*|j                         D ]  }| j                  ||        | S t        |t              r|D ]  }| j                  ||        | S t        j                  |      st        j                  d      | xj                  ||z  z  c_        | S )
        :param int sign: the sign of the operation to do other.
            if we add other => 1
            if we subtract other => -1
        r   rF  z"Cannot add/subtract NaN/inf values)rb   intr   r!  r>   rd   r  r   r   r	  
addInPlacer   mathisfiniter}   	PulpError)r#   rH   rF  r  r  r   s         r%   rQ  zLpAffineExpression.addInPlacey  s>    eS!uzK=KeY'LL%* )  2LABMMU^^d22M *1QD)*"  t$\\^ .-.  x( .-.  u%//"FGG MMUT\)Mr'   c                (    | j                  |d      S )Nr   rO  rQ  rG   s     r%   
subInPlacezLpAffineExpression.subInPlace  s    u2..r'   c                    | j                         }| j                   |_        | j                         D ]  \  }}| ||<    |S r)   )r#  r  r   )r#   r   r  r  s       r%   r?   zLpAffineExpression.__neg__  sD    NNmm^
JJL 	DAq2AaD	r'   c                    | S r)   rA   r*   s    r%   rB   zLpAffineExpression.__pos__  rC   r'   c                @    | j                         j                  |      S r)   r%  rQ  rG   s     r%   rI   zLpAffineExpression.__add__      yy{%%e,,r'   c                @    | j                         j                  |      S r)   r[  rG   s     r%   rL   zLpAffineExpression.__radd__  r\  r'   c                $    | j                  |      S r)   rV  rG   s     r%   __iadd__zLpAffineExpression.__iadd__  s    u%%r'   c                @    | j                         j                  |      S r)   r%  rW  rG   s     r%   rN   zLpAffineExpression.__sub__  r\  r'   c                &    |  j                  |      S r)   rV  rG   s     r%   rP   zLpAffineExpression.__rsub__      !!%((r'   c                $    | j                  |      S r)   )rW  rG   s     r%   __isub__zLpAffineExpression.__isub__  s      ''r'   c                   | j                         }t        |t        t        f      r| j                  |j                  z  |_        t        |      rIt        |       rt        d      | j                  }|dk7  rS|j                         D ]  \  }}||z  ||<    |S |j                  }|dk7  r | j                         D ]  \  }}||z  ||<    |S t        |t              r| t        |      z  S t        j                  |      st        j                  d      |dk7  r4| j                  |z  |_        | j                         D ]  \  }}||z  ||<    |S )Nz-Non-constant expressions cannot be multipliedr   z-Cannot multiply variables with NaN/inf values)r#  rb   r>   rd   r  r   rX   r   rc   rR  rS  r}   rT  r#   rH   r   cr  r  s         r%   rR   zLpAffineExpression.__mul__  sC   NNe0,?@7AJ5zt9#$STTAAv$)KKM )DAq#$q5AaD)   NN6 $

 %1 1u!%  z*,U333=='oo&UVV!!]]U2
 JJL %DAq 19AaD%r'   c                    | |z  S r)   rA   rG   s     r%   rT   zLpAffineExpression.__rmul__      e|r'   c                r   t        |t        t        f      st        |t              r"t	        |      rt        d      |j                  }t        j                  |      st        j                  d      | j                         }| j                  |z  |_        | j                         D ]  \  }}||z  ||<    |S Nz:Expressions cannot be divided by a non-constant expressionz+Cannot divide variables with NaN/inf values)rb   r>   rd   rc   r   rX   r  rR  rS  r}   rT  r#  r   )r#   rH   r   r  r  s        r%   rV   zLpAffineExpression.__div__  s    e0,?@J:E
 5zP  NNE}}U#//"OPPNN]]U*
JJL 	DAqu9AaD	r'   c                $    | j                  |      S r)   )rV   rG   s     r%   __truediv__zLpAffineExpression.__truediv__  s    ||E""r'   c                j   | j                         }t        |       rt        d      | j                  }t	        |t
        t        f      r6|j                  |z  |_        |j                         D ]  \  }}||z  ||<    |S t        j                  |      st        j                  d      ||z  |_        |S rl  )r#  r   rX   r  rb   r>   rd   r   rR  rS  r}   rT  rg  s         r%   rY   zLpAffineExpression.__rdiv__  s    NNt9L  MMe0,?@!+AJ 11u! 	 u%//"OPPAJr'   c                    t        |t        t        f      rt        | t        j
                  |      S t        | |z
  t        j
                        S Nrhs)rb   rP  r  rd   r}   LpConstraintLErG   s     r%   r[   zLpAffineExpression.__le__  <    ec5\*e&:&:FFue.B.BCCr'   c                    t        |t        t        f      rt        | t        j
                  |      S t        | |z
  t        j
                        S rq  )rb   rP  r  rd   r}   LpConstraintGErG   s     r%   r^   zLpAffineExpression.__ge__  ru  r'   c                    t        |t        t        f      rt        | t        j
                  |      S t        | |z
  t        j
                        S rq  )rb   rP  r  rd   r}   LpConstraintEQrG   s     r%   r`   zLpAffineExpression.__eq__  ru  r'   c                ~    | j                         D cg c]  \  }}t        |j                  |       c}}S c c}}w )z
        exports the :py:class:`LpAffineExpression` into a list of dictionaries with the coefficients
        it does not export the constant

        :return: list of dictionaries with the coefficients
        :rtype: list
        )r$   r   )r   r   r$   )r#   kr  s      r%   r   zLpAffineExpression.toDict  s-     8<zz|Dtq!!&&*DDDs   !9rh   
str | Noner$   r}  )Nr  N)r  r  r$   r}  rh   float | Nonerh   r  )r   r   r   zfloat | int)TN)r   ri   r,  r  )rh   zlist[LpElement]r)   )r,  r  r$   r   )r$   r   r   ri   r,  r  r   rF  zLiteral[+1, -1])rh   rd   )/rj   rk   rl   rm   r   r    rr   r$   setterr3   re   r  rf   rE   r   r   r!  r#  r%  r9   r+  r;   staticmethodr?  rH  r   rQ  rW  r?   rB   rI   rL   r_  rN   rP   re  rR   rT   rV   rn  rY   r[   r^   r`   r   r   __classcell__r  s   @r%   r>   r>     sI   . gw'E  
[[ 0X'
@$( PT $@L> ) )D "&*.	  (	B!F/--&-)(8"#"DDDE Gr'   r>   c                  l   e Zd ZdZdej
                  ddfdZd*dZd*dZd Z	d Z
d Zd+d,d	Zd-d
Zd Zd Zd.d/dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd0d1dZd Zd Zed        ZeZe d2d       Z!e!jD                  d3d       Z!d Z#d Z$d Z%d  Z&d! Z'd" Z(d4d#Z)d5d$Z*d% Z+d& Z,d' Z-d*d(Z.d6d)Z/y)7rd   zAn LP constraintNc                    t        |t              r|n
t        |      | _        || _        | j                  j                  | _        || xj                  |z  c_        || _        d| _        d| _        d| _        y)aG  
        :param e: an instance of :class:`LpAffineExpression`
        :param sense: one of :data:`~pulp.const.LpConstraintEQ`, :data:`~pulp.const.LpConstraintGE`, :data:`~pulp.const.LpConstraintLE` (0, 1, -1 respectively)
        :param name: identifying string
        :param rhs: numerical value of constraint target
        NT)	rb   r>   exprr$   r  sensepislackr2   )r#   r   r  r$   rs  s        r%   r3   zLpConstraint.__init__!  se     $A'9:A@RST@U		#yy11?MMS M

r'   c                    | j                   t        j                  k(  s| j                   t        j                  k(  r| j                   S y r)   )r  r}   rw  ry  r  r*   s    r%   r   zLpConstraint.getLb2  4    JJ%...DJJ%BVBV4VMM>!r'   c                    | j                   t        j                  k(  s| j                   t        j                  k(  r| j                   S y r)   )r  r}   rt  ry  r  r*   s    r%   r   zLpConstraint.getUb8  r  r'   c                    | j                   j                  d| j                        }| j                  =|dt        j
                  | j                     z   dz   t        | j                         z   z  }|S )NF)r   r,  rB  )r  r9   r  r  r}   LpConstraintSensesr   r   s     r%   r9   zLpConstraint.__str__>  sa    IIuV::!u//

;;cACDWWWAr'   c                    | j                   j                  | j                        }| j                  &|dt        j
                  | j                     z   dz   z  }|S )Nr,  rB  z 0)r  r;   r  r  r}   r  r   s     r%   r;   zLpConstraint.__repr__D  sO    II?::!u//

;;dBBAr'   c                   | j                   j                  |      \  }}t        | j                               dk(  r|dgz  }| j                   }|dk(  rd}dt
        j                  | j                      d|d}| j                   j                  |      t        |      z   t
        j                  kD  r|dj                  |      gz  }|g}n||gz  }|dj                  |      gz  }ddj                  |      z  }|S )z2
        Returns a constraint as a string
        r   r*  rB  r   r   rK  rL  )r  rH  r   r  r  r}   r  r  r?  rC  r6  )r#   r$   r3  r>  rh  rG  s         r%   asCplexLpConstraintz LpConstraint.asCplexLpConstraintJ  s     yy55d;tyy{q SEMD]]N6A5++DJJ78!DB99&&t,s4y85;R;RRrwwt}o%F6DTFND2774=/!$))F++r'   c                R    | j                   j                  ||| j                        S )rJ  r  )r  r   r  r   s      r%   r   z&LpConstraint.asCplexLpAffineExpression^  s,     yy22"dmm 3 
 	
r'   c                "    | | _         d| _        y)zX
        alters the RHS of a constraint so that it can be modified in a resolve
        TN)r  r2   )r#   RHSs     r%   	changeRHSzLpConstraint.changeRHSf  s     r'   c                    t        | j                  j                         | j                  | j                   | j                  j                  z         S )zMake a copy of selfrr  )rd   r  r%  r  r  r*   s    r%   r%  zLpConstraint.copym  s:    IINNdjjt}}ntyy?Q?Q.Q
 	
r'   c                .    t        | j                        S )Nr  )rd   r  r*   s    r%   r#  zLpConstraint.emptyCopys  s    $**--r'   c                   t        |t              r| j                  |j                  z  dk\  s| }| xj                  |j                  |z  z  c_        | j                  j                  |j                  |       | xj                  |j                  |z  z  c_        | S t        |t        t        f      r6| xj                  ||z  z  c_        | j                  j                  ||       | S t        |t              r@| xj                  |j                  |z  z  c_        | j                  j                  ||       | S t        |t              r| j                  j                  ||       | S t        dt        |       d      )rN  r   zConstraints and z cannot be added)rb   rd   r  r  r  rQ  rP  r  r>   rc   rX   type)r#   rH   rF  s      r%   rQ  zLpConstraint.addInPlacev  s6    e\*JJ,1uMMU^^d22MII  T2JJ%++,,J  U|,MMUT\)MII  -  12MMU^^d22MII  -
 	 z*II  -  .tE{m;KLMMr'   c                &    | j                  |d      S Nr   rV  rG   s     r%   rW  zLpConstraint.subInPlace  s    ub))r'   c                n    | j                         }|j                   |_        |j                   |_        |S r)   )r%  r  r  r#   rh  s     r%   r?   zLpConstraint.__neg__  s,    IIKjj[
&&r'   c                @    | j                         j                  |      S r)   r[  rG   s     r%   rI   zLpConstraint.__add__  r\  r'   c                @    | j                         j                  |      S r)   r[  rG   s     r%   rL   zLpConstraint.__radd__  r\  r'   c                @    | j                         j                  |      S r)   ra  rG   s     r%   rN   zLpConstraint.__sub__  r\  r'   c                &    |  j                  |      S r)   rV  rG   s     r%   rP   zLpConstraint.__rsub__  rc  r'   c                x   t        |t        t        f      r:| j                         }|j                  |z  |_        |j
                  |z  |_        |S t        |t              rD| j                         }|j                  |j                  z  |_        |j
                  |z  |_        |S t        dt        |             )Nz Cannot multiple LpConstraint by 	rb   rP  r  r%  r  r  r>   rX   r  r#   rH   rh  s      r%   rR   zLpConstraint.__mul__  s    ec5\*		Ae+AJVVe^AFH12		Aenn4AJVVe^AFH>tE{mLMMr'   c                    | |z  S r)   rA   rG   s     r%   rT   zLpConstraint.__rmul__  rj  r'   c                x   t        |t        t        f      r:| j                         }|j                  |z  |_        |j
                  |z  |_        |S t        |t              rD| j                         }|j                  |j                  z  |_        |j
                  |z  |_        |S t        dt        |             )NzCannot divide LpConstraint by r  r  s      r%   rn  zLpConstraint.__truediv__  s    ec5\*		Ae+AJVVe^AFH12		Aenn4AJVVe^AFH<T%[MJKKr'   c                    | j                         }| j                  t        j                  k(  rt	        |      |k  S || j                  z  | k\  S r)   )r   r  r}   ry  r   )r#   r   r   s      r%   r   zLpConstraint.valid  sC    jjl::---s8s?"#t++r'   c                     t        | g|i |S )z|
        Builds an elastic subproblem by adding variables to a hard constraint

        uses FixedElasticSubProblem
        )FixedElasticSubProblemr#   argsr   s      r%   makeElasticSubProblemz"LpConstraint.makeElasticSubProblem  s     &d<T<V<<r'   c                    t        | j                  | j                  | j                  | j                  | j
                  j                               S )z
        exports constraint information into a dictionary

        :return: dictionary with all the constraint information
        )r  r  r  r$   coefficients)r   r  r  r  r$   r  r   r*   s    r%   r   zLpConstraint.toDict  s=     **ww]]))+
 	
r'   c                L     | |d   |d    |d   |d         }|d   |_         |S )z
        Initializes a constraint object from a dictionary with necessary information

        :param dict _dict: dictionary with data
        :return: a new :py:class:`LpConstraint`
        r  r  r$   r  )r   rs  r$   r  r  )r  )r   _dictr}   s      r%   r   zLpConstraint.fromDict  sA     N#z""v.	
 ;r'   c                    | j                   S r)   )_LpConstraint__namer*   s    r%   r$   zLpConstraint.name  r   r'   c                `    |%|j                  t        j                        | _        y d | _        y r)   )r   r>   r    r  r"   s     r%   r$   zLpConstraint.name  s&    ..);)A)ABDKDKr'   c                    t        |       dk(  xr6 | j                  dk(  xr% t        t        | j	                                     dk(  S r  r  r*   s    r%   re   zLpConstraint.isAtomic  r
  r'   c                6    | j                   j                         S r)   )r  r  r*   s    r%   r  z LpConstraint.isNumericalConstant   s    yy,,..r'   c                6    | j                   j                         S r)   )r  rf   r*   s    r%   rf   zLpConstraint.atom      yy~~r'   c                R    t        | j                        dk7  xs t        |       dkD  S r  r  r*   s    r%   rE   zLpConstraint.__bool__  r  r'   c                ,    t        | j                        S r)   )r   r  r*   s    r%   __len__zLpConstraint.__len__	  s    499~r'   c                ,    t        | j                        S r)   )r  r  r*   s    r%   __iter__zLpConstraint.__iter__  s    DIIr'   c                     | j                   |   S r)   )r  )r#   r   s     r%   __getitem__zLpConstraint.__getitem__  s    yy~r'   c                :    | j                   j                  ||      S r)   )r  get)r#   r   defaults      r%   r  zLpConstraint.get  s    yy}}S'**r'   c                6    | j                   j                         S r)   )r  r  r*   s    r%   r  zLpConstraint.keys  r  r'   c                6    | j                   j                         S r)   )r  r	  r*   s    r%   r	  zLpConstraint.values  s    yy!!r'   c                6    | j                   j                         S r)   )r  r   r*   s    r%   r   zLpConstraint.items  s    yy  r'   c                    | j                   }| j                         D ]%  \  }}|j                   y ||j                  |z  z  }' |S r)   r  r  s       r%   r   zLpConstraint.value  r  r'   c                z    | j                   }| j                         D ]  \  }}||j                         |z  z  } |S r)   r  r  s       r%   r   zLpConstraint.valueOrDefault&  r  r'   r  r   )r$   r   r   ri   )r  r  r   r  r   )r   r  rh   ri   r|  r~  )r   r   )r   rc   r  r  rh   r  r  )0rj   rk   rl   rm   r}   ry  r3   r   r   r9   r;   r  r   r  r%  r#  rQ  rW  r?   rI   rL   rN   rP   rR   rT   rn  r   r  r   r   r   r   rr   r$   r  re   r  rf   rE   r  r  r  r  r  r	  r   r   r   rA   r'   r%   rd   rd     s   U%9%9$ "(

.0*---)NL,=
    I  
[[ X/ @+ "!r'   rd   c                  D    e Zd ZdZdej
                  dddfdZd ZddZy)LpFractionConstraintzK
    Creates a constraint that enforces a fraction requirement a/b = c
    N      ?c                    || _         |||| _        ||z   | _        n$|||| _        ||z
  | _        n|| _        || _        | j                   || j                  z  z
  }t        j	                  | ||d|       || _        y)a  
        creates a fraction Constraint to model constraints of
        the nature
        numerator/denominator {==, >=, <=} RHS
        numerator/(numerator + complement) {==, >=, <=} RHS

        :param numerator: the top of the fraction
        :param denominator: as described above
        :param sense: the sense of the relation of the constraint
        :param RHS: the target fraction value
        :param complement: as described above
        Nr   )r  rs  r$   )	numerator
complementdenominatorrd   r3   r  )r#   r  r  r  r  r$   r  lhss           r%   r3   zLpFractionConstraint.__init__2  s    * #:#9(DO(:5D$);*D)I5DO*D(DOnnsT%5%555dCu!$Gr'   c                "   t        t        | j                              t        j                  k\  r+t        | j
                        t        | j                        z  S t        t        | j
                              t        j                  k  ryt        )zW
        Determines the value of the fraction in the constraint after solution
        r  r   r   r  r}   EPSr  ZeroDivisionErrorr*   s    r%   findLHSValuez!LpFractionConstraint.findLHSValueU  sb     uT%%&'5994(51A1A+BBB5()UYY6''r'   c                     t        | g|i |S )z
        Builds an elastic subproblem by adding variables and splitting the
        hard constraint

        uses FractionElasticSubProblem
        )FractionElasticSubProblemr  s      r%   r  z*LpFractionConstraint.makeElasticSubProblemb  s     )????r'   )r  r   r   r   )	rj   rk   rl   rm   r}   ry  r3   r  r  rA   r'   r%   r  r  -  s/     ""!F(@r'   r  c                  $    e Zd ZdZddZd Zd Zy)LpConstraintVarz`A Constraint that can be treated as a variable when constructing
    a LpProblem by columns
    Nc                l    t         j                  | |       t        | j                  |||      | _        y )N)r$   r  rs  r   )r   r3   rd   r$   r   )r#   r$   r  rs  r   s        r%   r3   zLpConstraintVar.__init__q  s(    4&&DIIUqQr'   c                P    | j                   j                  j                  ||       y)zS
        Adds a variable to the constraint with the
        activity coeff
        N)r   r  r!  )r#   r   r   s      r%   r   zLpConstraintVar.addVariableu  s    
 	$$S%0r'   c                6    | j                   j                         S r)   )r   r   r*   s    r%   r   zLpConstraintVar.value|  s    $$&&r'   )NNNN)rj   rk   rl   rm   r3   r   r   rA   r'   r%   r  r  l  s    R1'r'   r  c                     e Zd ZdZdej
                  fdZd Zd Zd Z	d Z
d Zd	 ZeZed
        ZeZd ZeZed        ZeZeej
                  fd       Zd Zd Zd4dZd Zd5dZd6dZd7dZd8dZd9dZd Zd:dZ d:d;dZ!d Z"d Z#	 d<	 	 	 d=dZ$d:dZ%	 d>	 d?dZ&d@d Z'dAd!Z(dBd"Z)d# Z*d$ Z+d% Z,dCd&Z-d' Z.d( Z/d) Z0d:d*Z1d+ Z2d, Z3	 dDd-Z4d:d.Z5e6fd/Z7d0 Z8d1 Z9d2 Z:d:d3Z;y)E	LpProblemzAn LP ProblemNoNamec                   d|v r't        j                  d       |j                  dd      }d| _        t	               | _        || _        || _        i | _        i | _	        t        j                  | _        t        j                  | _        d| _        d| _        d| _        g | _        g | _        d| _        g | _        i | _        d| _        d| _        d| _        d| _        y)a  
        Creates an LP Problem

        This function creates a new LP Problem  with the specified associated parameters

        :param name: name of the problem used in the output .lp file
        :param sense: of the LP problem objective.                  Either :data:`~pulp.const.LpMinimize` (default)                 or :data:`~pulp.const.LpMaximize`.
        :return: An LP Problem
        rB  z6Spaces are not permitted in the name. Converted to '_'_Nr   Fr   )r   r   replace	objective
_DICT_TYPEconstraintsr$   r  sos1sos2r}   LpStatusNotSolvedstatusLpSolutionNoSolutionFound
sol_status	noOverlapsolversolverModelmodifiedVariablesmodifiedConstraints	resolveOK
_variables_variable_idsdummyVarsolutionTimesolutionCpuTime
lastUnused)r#   r$   r  s      r%   r3   zLpProblem.__init__  s     $;MMRS<<S)D484>L	
		--99!##% ,. 	   r'   c                   | j                   dz   }| j                  dk(  r|dz  }n|dz  }|t        | j                        dz   z  }| j                  r>|dz  }| j                  j                         D ]  \  }}||j                  |      dz   z  } |dz  }| j                         D ]9  }||j                         dz   t        j                  |j                     z   dz   z  }; |S )	Nz:
r   z	MINIMIZE
z	MAXIMIZE
rL  zSUBJECT TO
z
VARIABLES
rB  )r$   r  reprr  r  r   r  rE  r   r}   LpCategoriesrz   )r#   r   nrh  r  s        r%   r;   zLpProblem.__repr__  s    II::?AA	T$..!D((A((..0 51Q**1-445	]! 	PA$$&,u/A/A!%%/HH4OOA	Pr'   c                @    | j                   j                         }|d= |S )Nr  )__dict__r%  )r#   states     r%   __getstate__zLpProblem.__getstate__  s!    ""$/"r'   c                    | j                   j                  |       i | _        | j                  D ]  }|| j                  |j                  <    y r)   )r  updater  r  r1   )r#   r  r  s      r%   __setstate__zLpProblem.__setstate__  sC    U# 	+A)*Dqvv&	+r'   c                $   t        | j                  | j                        }| j                  |_        | j                  j                         |_        | j                  j                         |_        | j                  j                         |_        |S )z8Make a copy of self. Expressions are copied by referencer$   r  )r  r$   r  r  r  r%  r  r  )r#   lpcopys     r%   r%  zLpProblem.copy  sb    		<>>!--224iinn&iinn&r'   c                   t        | j                  | j                        }| j                  | j                  j	                         |_        t        t        t        f          |_        | j                  j                         D ]"  \  }}|j	                         |j                  |<   $ | j                  j	                         |_
        | j                  j	                         |_        |S )z4Make a copy of self. Expressions are copied by valuer	  )r  r$   r  r  r%  r  r   rd   r  r   r  r  )r#   r
  r{  r  s       r%   deepcopyzLpProblem.deepcopy  s    		<>>%#~~224F'\(9:<$$**, 	-DAq$%FFHFq!	-iinn&iinn&r'   c                
   	 | j                          | j                          | j                  J | j                         }t        t        | j                  j                  | j                  j                               | j                  j                         D cg c]  }|j                          c}|D cg c]  }|j                          c}t        | j                  | j                  | j                  | j                        t        | j                  j                               t        | j                   j                                     S # t        j                  $ r t        j                  d      w xY wc c}w c c}w )a  
        creates a dictionary from the model with as much data as possible.
        It replaces variables by variable names.
        So it requires to have unique names for variables.

        :return: dictionary with model data
        :rtype: dict
        zZDuplicated names found in variables:
to export the model, variable names need to be unique)r$   r  )r$   r  r  r  )r  r  rE  
parametersr  r  )checkDuplicateVarsr}   rT  fixObjectiver  rE  r   r$   r   r  r	  r  r  r  r1  r  r  r#   rE  r  s      r%   r   zLpProblem.toDict  s(   	##%
 	~~)))NN$	^^((t~~7L7L7N .2-=-=-D-D-FGG+45aqxxz5YYjj{{??	 dii&&()dii&&()
 	
  	//m 	 H5s   E E;
6F )E8c           	         |d   }ddh}|D ci c]  }|||   
 }} | di |}|d   |_         |d   |_        |d   D ci c]  }|d   t        j                  di | c}|d   d   D ci c]  }|d      |d	    }}|t	        ||d   d   
      z  }fd}	|d   D cg c]
  } |	|       }
}|
D ]  }|t
        j                  |      z  } d } ||d         |_         ||d         |_        |fS c c}w c c}w c c}w c c}w )a$  
        Takes a dictionary with all necessary information to build a model.
        And returns a dictionary of variables and a problem object

        :param _dict: dictionary with the model stored
        :return: a tuple with a dictionary of variables and a :py:class:`LpProblem`
        r  r$   r  r  r  rE  r  r  r   )r   r$   c                h    t        |       } | d   D ci c]  }|d      |d    c}| d<   | S c c}w )Nr  r$   r   )r   )r}   r  r   s     r%   
edit_constz&LpProblem.fromDict.<locals>.edit_const  sH    KE49.4I%/0AfI'
*%E.! L%s   /r  c                L    t        |       D  ci c]  \  }} || 
 c} }S c c} }w r)   )	enumerate)r  r{  s     r%   r   z$LpProblem.fromDict.<locals>.<lambda>*  s     9Q<!@41a!Q$!@ !@s    r  r  rA   )r  r  rc   r   r>   rd   r  r  )r   r  params	pb_paramsr{  r  pbr  obj_er  r  rh  list_to_dictr   s                @r%   r   zLpProblem.fromDict  sa    |$W%	&/06!900[4[8$	|, =B+<NOqqy*--222O 6;;5G5WXQvY7+XX
 5u[/A&/IJJ	 /4M.BCz!}CC 	+A,''**B	+ AuV}-uV}-Bw? 1 P Y Ds   C< D.D%Dc                    t        |d      5 }t        j                  | j                         |g|i | ddd       y# 1 sw Y   yxY w)a  
        Creates a json file from the LpProblem information

        :param str filename: filename to write json
        :param args: additional arguments for json function
        :param kwargs: additional keyword arguments for json function
        :return: None
        wN)openjsondumpr   )r#   filenamer  r   r   s        r%   toJsonzLpProblem.toJson2  sC     (C  	9AIIdkkmQ888	9 	9 	9s	   )?Ac                    t        |      5 }t        j                  |      }ddd       | j                        S # 1 sw Y   xY w)z
        Creates a new Lp Problem from a json file with information

        :param str filename: json file name
        :return: a tuple with a dictionary of variables and an LpProblem
        :rtype: (dict, :py:class:`LpProblem`)
        N)r  r  loadr   )r   r!  r   datas       r%   fromJsonzLpProblem.fromJson@  s>     (^ 	 q99Q<D	 ||D!!	  	 s	   ;Ac                T    t        j                  |fd|i|}| j                  |      S )Nr  )mpslpreadMPSr   )r   r!  r  r   r%  s        r%   fromMPSzLpProblem.fromMPSO  s)    }}X=U=f=||D!!r'   c                    t        | j                        D ci c]  \  }}|d|z   }}}| j                         }t        |      D ci c]  \  }}|j                  d|z   }}}||dfS c c}}w c c}}w )NzC%07dzX%07dOBJ)r  r  rE  r$   )r#   r   r{  constraintsNamesr  variablesNamess         r%   normalisedNameszLpProblem.normalisedNamesT  sx    7@AQAQ7RStq!Aw{NSS^^%
:CJ:OP$!Q!&&'A+-PP66 TPs   A,
A2c                l    | j                         D ]!  }|j                  t        j                  k(  s! y yr  )rE  rz   r}   r   )r#   r  s     r%   isMIPzLpProblem.isMIPZ  s0    ! 	Auu'	 r'   c                R    | j                         D ]  }|j                  ||        y)z
        Rounds the lp variables

        Inputs:
            - none

        Side Effects:
            - The lp variables are rounded
        N)rE  r   )r#   r   r   r  s       r%   roundSolutionzLpProblem.roundSolution`  s(     ! 	!AGGFC 	!r'   c                    | xj                   dz  c_         	 d| j                   z  }|| j                  vr	 |S | xj                   dz  c_         6)Nr   z_C%d)r  r  r   s     r%   unusedConstraintNamezLpProblem.unusedConstraintNamem  sL    1(A((( OOq O	 r'   c                    | j                         D ]  }|j                  |      r y | j                  j                         D ]  }|j                  |      r y y)NFT)rE  r   r  r	  )r#   r   r  rh  s       r%   r   zLpProblem.validv  sY    ! 	A773<	 !!((* 	A773<	 r'   c                $   d}| j                         D ]&  }t        t        |j                  |            |      }( | j                  j                         D ]7  }|j                  d      rt        t        |j                               |      }9 |S r   )rE  maxr   r   r  r	  r   r   )r#   r   gapr  rh  s        r%   r   zLpProblem.infeasibilityGap  s    ! 	9Ac!,,S12C8C	9!!((* 	/A771:#aggi.#.	/ 
r'   c                    |j                   | j                  vr5| j                  j                  |       || j                  |j                   <   yy)z
        Adds a variable to the problem before a constraint is added

        :param variable: the variable to be added
        N)r1   r  r  r5  )r#   variables     r%   r   zLpProblem.addVariable  sA     == 2 22OO""8,08Dx}}- 3r'   c                4    |D ]  }| j                  |        y)z
        Adds variables to the problem before a constraint is added

        :param variables: the variables to be added
        N)r   r  s      r%   addVariableszLpProblem.addVariables  s!      	 AQ	 r'   c                :   | j                   r)| j                  | j                   j                                | j                  j	                         D ]!  }| j                  |j                                # | j
                  j                  d        | j
                  S )z
        Returns the problem variables

        :return: A list containing the problem variables
        :rtype: (list, :py:class:`LpVariable`)
        c                    | j                   S r)   r8   r/  s    r%   r   z%LpProblem.variables.<locals>.<lambda>  s
    166 r'   r0  )r  r=  r  r  r	  r  r2  r  s     r%   rE  zLpProblem.variables  sx     >>dnn1134!!((* 	(Aaffh'	(!12r'   c                    i }| j                   r | j                   D ]  }|||j                  <    | j                  j                         D ]  }|D ]  }|||j                  <     |S r)   )r  r$   r  r	  )r#   rE  r  rh  s       r%   variablesDictzLpProblem.variablesDict  sr    	>>^^ &$%	!&&!&!!((* 	&A &$%	!&&!&	& r'   Nc                (    | j                  ||       y r)   )addConstraintr#   r   r$   s      r%   addzLpProblem.add  s    :t,r'   c                   t        |t              st        d      |r||_        	 |j                  r|j                  }n| j	                         }|| j                  v r0| j                  rt        j                  d|z         t        d|       || j                  |<   | j                  j                  |       | j                  |j                                y # t
        $ r t        d      w xY w)Nz!Can only add LpConstraint objectszoverlapping constraint names: z&Warning: overlapping constraint names:)rb   rd   rX   r$   r5  AttributeErrorr  r  r}   rT  printr  r5  r=  r  rD  s      r%   rC  zLpProblem.addConstraint  s    *l3?@@"JO	A!002 4###~~oo&F&MNN>E!+  ''
3*//+,  	A?@@	As   )C C,c                    t        |t              r|dz   }	 |j                  }|j                  }|| _        || j
                  _        d| _        y# t        $ r d}Y -w xY w)z
        Sets the input variable as the objective function. Used in Columnwise Modelling

        :param obj: the objective function of type :class:`LpConstraintVar`

        Side Effects:
            - The objective function is set
        r  NF)rb   rc   r   r$   rG  r  r  )r#   objr$   s      r%   setObjectivezLpProblem.setObjective  s`     c:&)C	..C88D "	  	D	s   A AAc                   t        |t              r|\  }}nd }|du r| S |du rt        d      t        |t              r| j	                  |j
                         | S t        |t              r| j	                  ||       | S t        |t              r=| j                  t        j                  d       || _        ||| j                  _        | S t        |t              st        |t        t        f      rD| j                  t        j                  d       t        |      | _        || j                  _        | S t        d      )NTFz/A False object cannot be passed as a constraintz%Overwriting previously set objective.zNCan only add LpConstraintVar, LpConstraint, LpAffineExpression or True objects)rb   r   rX   r  rC  r   rd   r>   r  r   r   r$   rc   rP  r  )r#   rH   r$   s      r%   r_  zLpProblem.__iadd__  s&   eU#KE4DD=Ke^MNN/u//0& % |,ud+" ! 12~~)EF"DN&*#  z*je.M~~)EF/6DN"&DNN
  ` r'   c                   t        |t              r(|j                         D ]  \  }}|| j                  |<    yt        |t              rt        |j                               j                  | j                               D ]   }|j                  |j                  z   |_        " |j                  j                         D ]*  \  }}|j                  |z   |_        | j                  |       , |r7|j                  t        d      | xj                  |j                  z  c_
        yy|D ]N  }t        |t              r|d   }|d   }nd}|s|j                  }|s| j                         }|| j                  |<   P y)a  
        extends an LpProblem by adding constraints either from a dictionary
        a tuple or another LpProblem object.

        :param bool use_objective: determines whether the objective is imported from
        the other problem

        For dictionaries the constraints will be named with the keys
        For tuples an unique name will be generated
        For LpProblems the name of the problem will be added to the constraints
        name
        Nz%Objective not set by provided problemr   r   )rb   r   r   r  r  setrE  
differencer$   rC  r  r   r   r5  )r#   rH   use_objectiver$   r   r  rh  s          r%   r   zLpProblem.extend  sT   * eT"$)KKM 4 j)3  &4y)*+66t~~7GH -aff,- ,,224 &ad*""1%& ??*$%LMM%//1 
  
+a'Q4D!AD66D446D)*  &
+r'   c           
     x   g }|d k(  rQ| j                   D ]@  }| j                   |   }|j                  |D cg c]  }|j                  |||   f c}       B |S | j                   D ]H  }||   }| j                   |   }|j                  |D cg c]  }||j                     |||   f c}       J |S c c}w c c}w r)   )r  r   r$   )r#   translationcoefsrh  cstr  ctrs          r%   r  zLpProblem.coefficients3  s    $%% A&&q)3?aqvvq#a&1?@A 	 %% P!!n&&q)#NQ{1662CQ@NOP  @
 Os   B2
B7
c                8    t        j                  | |||||      S )aq  
        Writes an mps files from the problem information

        :param str filename: name of the file to write
        :param int mpsSense:
        :param bool rename: if True, normalized names are used for variables and constraints
        :param mip: variables and variable renames
        :return:

        Side Effects:
            - The file is created
        )mpsSenserenamer   with_objsense)r(  writeMPS)r#   r!  rW  rX  r   rY  s         r%   rZ  zLpProblem.writeMPS@  s'     ~~'
 	
r'   c                6    t        j                  | ||||      S )a\  
        Write the given Lp problem to a .lp file.

        This function writes the specifications (objective function,
        constraints, variables) of the defined Lp problem to a file.

        :param str filename: the name of the file to be created.
        :return: variables

        Side Effects:
            - The file is created
        )r!  writeSOSr   
max_length)r(  writeLP)r#   r!  r\  r   r]  s        r%   r^  zLpProblem.writeLPX  s      }}8hCJ
 	
r'   c                    t        d | j                         D              }|j                         D ch c]  \  }}|dk\  s||f }}}|rt        j                  d|       yc c}}w )z
        Checks if there are at least two variables with the same name
        :return: 1
        :raises `const.PulpError`: if there ar duplicates
        c              3  4   K   | ]  }|j                     y wr)   r8   )r:  r;  s     r%   r<  z/LpProblem.checkDuplicateVars.<locals>.<genexpr>o  s     Nx}}Ns      zRepeated variable names: N)r   rE  r   r}   rT  )r#   name_counterr$   countrepeated_namess        r%   r  zLpProblem.checkDuplicateVarsi  ss     NT^^=MNN-9-?-?-A
)dEUaZT5M
 
 //$=n=M"NOO 
s   A&A&c                    | j                         D cg c]&  }t        |j                        |kD  r|j                  ( }}|rt        j                  d|       yc c}w )z
        Checks if variables have names smaller than `max_length`
        :param int max_length: max size for variable name
        :return:
        :raises const.PulpError: if there is at least one variable that has a long name
        z'Variable names too long for Lp format: N)rE  r   r$   r}   rT  )r#   r]  r;  
long_namess       r%   checkLengthVarszLpProblem.checkLengthVarsv  sg     !NN,
8==!J. MM

 

 //9*F  
s   +Ac                X    | j                         }|D ]  }|dk7  s	||   ||   _         y Nr   )rA  r{   r#   r	  rE  r$   s       r%   assignVarsValszLpProblem.assignVarsVals  s7    &&(	 	8Dy +1$<	$(	8r'   c                X    | j                         }|D ]  }|dk7  s	||   ||   _         y ri  )rA  r|   rj  s       r%   assignVarsDjzLpProblem.assignVarsDj  s7    &&(	 	2Dy %+D\	$"	2r'   c                `    |D ]  }	 ||   | j                   |   _         y # t        $ r Y )w xY wr)   )r  r  KeyError)r#   r	  r$   s      r%   assignConsPizLpProblem.assignConsPi  sA     	D,24L  &)	  s   !	--c                    |D ]c  }	 |r>d| j                   |   j                  t        ||         z   z  | j                   |   _        n t        ||         | j                   |   _        e y # t        $ r Y rw xY wr  )r  r  r  r  ro  )r#   r	  activityr$   s       r%   assignConsSlackzLpProblem.assignConsSlack  s     
	D	35((.77%t:MM4D$$T*0 493FD$$T*0
	  s   A A**	A65A6c                V    | j                   t        ddd      | _         | j                   S )Nr   r   )r  rc   r*   s    r%   get_dummyVarzLpProblem.get_dummyVar  s&    == &y!Q7DM}}r'   c                    | j                   t        d      | _         d}nd}| j                   j                         r)| j                         }| xj                   |z  c_         ||fS d }||fS )Nr   TF)r  r>   r  ru  r#   wasNoner  s      r%   r  zLpProblem.fixObjective  sm    >>!/2DNGG>>--/((*HNNh&N    H  r'   c                H    |rd | _         y || xj                   |z  c_         y y r)   )r  rw  s      r%   restoreObjectivezLpProblem.restoreObjective  s%    !DN!NNh&N "r'   c                    |s| j                   }|st        }| j                         \  }}| j                           |j                  | fi |}| j                          | j                  ||       || _         |S )a  
        Solve the given Lp problem.

        This function changes the problem to make it suitable for solving
        then calls the solver.actualSolve() method to find the solution

        :param solver:  Optional: the specific solver to be used, defaults to the
              default solver.

        Side Effects:
            - The attributes of the problem object are changed in
              :meth:`~pulp.solver.LpSolver.actualSolve()` to reflect the Lp solution
        )r  r	   r  
startClockactualSolve	stopClockrz  )r#   r  r   rx  r  r  s         r%   solvezLpProblem.solve  sr     [[F$F --/###D3F3gx0r'   c                D    t                | _        t                | _        y)z,initializes properties with the current timeN)r   r  r   r  r*   s    r%   r|  zLpProblem.startClock  s     %x!VGr'   c                x    | xj                   t               z  c_         | xj                  t               z  c_        y)z#updates time wall time and cpu timeN)r  r   r  r   r*   s    r%   r~  zLpProblem.stopClock  s(    TV#'r'   c                   |s| j                   }|st        }|sdgt        |      z  }|sdgt        |      z  }| j                          g }t	        t        |||            D ]  \  }\  }}	}
| j                  |       |j                  |       }|j                  |       |r| j                  | d       | j                  t        j                  k(  r| |t        |      |
z  |	z   k  d| fz  } | j                  t        j                  k(  s| |t        |      |
z  |	z   k\  d| fz  }  | j                          || _         |S )ag  
        Solve the given Lp problem with several objective functions.

        This function sequentially changes the objective of the problem
        and then adds the objective function as a constraint

        :param objectives: the list of objectives to be used to solve the problem
        :param absoluteTols: the list of absolute tolerances to be applied to
           the constraints should be +ve for a minimise objective
        :param relativeTols: the list of relative tolerances applied to the constraints
        :param solver: the specific solver to be used, defaults to the default solver.

        r   r   zSequence.lpSequence_Objective_)r  r	   r   r|  r  ziprK  r}  r5  r^  r  r}   
LpMinimizer   
LpMaximizer~  )r#   
objectivesabsoluteTolsrelativeTolsr  debugstatusesr   rJ  absolr   r  s               r%   sequentialSolvezLpProblem.sequentialSolve  sM   & [[F$F3Z0L3Z0L$-
L,7%
 	S A UC c"''-FOOF#s+./zzU---uSzC/%77;Nqc9RRRu///uSzC/%77;Nqc9RRR	S 	r'   c                    |s| j                   }| j                  r | j                   j                  | fi |S  | j                  dd|i|S )zI
        resolves an Problem using the same solver as previously
        r  rA   )r  r  actualResolver  )r#   r  r   s      r%   resolvezLpProblem.resolve  sL     [[F>>,4;;,,T<V<<4::6V6v66r'   c                    || _         y)zQSets the Solver for this problem useful if you are using
        resolve
        N)r  )r#   r  s     r%   	setSolverzLpProblem.setSolver   s     r'   c                ,    t        | j                        S )z8

        :return: number of variables in model
        )r   r  r*   s    r%   numVariableszLpProblem.numVariables&  s    
 4%%&&r'   c                ,    t        | j                        S )z:

        :return: number of constraints in model
        )r   r  r*   s    r%   numConstraintszLpProblem.numConstraints-  s    
 4##$$r'   c                    | j                   S r)   r  r*   s    r%   getSensezLpProblem.getSense4  s    zzr'   c                P   |t         j                  vr!t        j                  dt        |      z         |3|t         j                  vr!t        j                  dt        |      z         || _        |.t         j                  j                  |t         j                        }|| _	        y)z
        Sets the status of the model after solving.
        :param status: code for the status of the model
        :param sol_status: code for the status of the solution
        :return:
        zInvalid status code: zInvalid solution status code: T)
r}   LpStatusrT  r   
LpSolutionr  LpStatusToSolutionr  r  r  )r#   r  r  s      r%   assignStatuszLpProblem.assignStatus7  s     '//"9CK"GHH!j8H8H&H//"BS_"TUU115577J %r'   r   r  r   )r;  rc   )rE  zIterable[LpVariable])rh   zlist[LpVariable]r)   )r   rd   r   )rH   zWLpProblem | dict[str, LpConstraint] | Iterable[tuple[str, LpConstraint] | LpConstraint]rP  ri   )r   r   r   F)rY  ri   )r   r   d   )rh   None)r]  rP  rh   r  )F)NNNF)<rj   rk   rl   rm   r}   r  r3   r;   r  r  r%  r  r   r   r   r   r   r"  to_jsonr&  	from_jsonr*  r/  r1  r3  r5  r   r   r   r=  rE  rA  rE  rC  rK  r_  r   r  rZ  r^  r  rg  rk  rm  rp  rs  ru  r  rz  r  r|  r~  r  r  r	   r  r  r  r  r  rA   r'   r%   r  r    s   $E,<,< &P"+
 
D G+ +Z I
9 G
" 
" I%*%5%5 " "7!9 --2*L #-+@-+ -+^ LQ
DH
0
"P"82
!'8$
( TY,\	7  / '%r'   r  c                  l     e Zd ZdZ	 	 	 d
	 	 	 	 	 	 	 d fdZddZd ZddZddZd Z	d Z
dd	Z xZS )r  aT  
    Contains the subproblem generated by converting a fixed constraint
    :math:`\sum_{i}a_i x_i = b` into an elastic constraint.

    :param constraint: The LpConstraint that the elastic constraint is based on
    :param penalty: penalty applied for violation (+ve or -ve) of the constraints
    :param proportionFreeBound:
        the proportional bound (+ve and -ve) on
        constraint violation that is free from penalty
    :param proportionFreeBoundList: the proportional bound on         constraint violation that is free from penalty, expressed as a list        where [-ve, +ve]
    c                   |j                    d}t        | 	  |t        j                         || _        |j                  | _        |j                   | _        | |dfz  } t        ddd      | _	        t        ddd      | _
        t        ddd      | _        |j                  | j                  | j                  z   | j                  z          |r||f}|rUt        |j                  |d   z        | j                  _        t        |j                  |d   z         | j                  _        |Gd | j                  _        d | j                  _        || j                  z  || j                  z  z
  | _        y t#               | _        y )	N_elastic_SubProblem_Constraint_free_boundr   ry   rw   _pos_penalty_var_neg_penalty_varr   )r$   r  r3   r}   r  r   r  r  rc   freeVarupVarlowVarrQ  r   ry   rw   r  r>   )r#   r   penaltyproportionFreeBoundproportionFreeBoundListsubProblemNamer  s         r%   r3   zFixedElasticSubProblem.__init__\  s\    'OO,,?@)9)9:$"++'''
M))!-QG 2AJ
 !3QKdllT[[84::EF':<O&P#"#&z':':=TUV=W'W#XDLL %(##&=a&@@& %DLL!
 !%DJJ#'DKK $tzz1Gdkk4IIDN/1DNr'   c                B    t        | |d      }|rt        |      }||S yy)zL
        safe way to get the value of a variable that may not exist
        r   r  )getattrr   )r#   attribr   r   s       r%   
_findValuez!FixedElasticSubProblem._findValue  s.     dFA&*C
r'   c                p   | j                  d      }| j                  d      }| j                  d      }t        ||z         t        j                  k\  }|rat        j                  d| j                  d|d|d|d|
       t        j                  d	| j                          d
| j                          |S )D
        returns true if the penalty variables are non-zero
        r  r  r  zisViolated z, upVar z	, lowVar z
, freeVar z result zisViolated value lhs z
 constant )	r  r   r}   r  logr  r$   r  r  )r#   r  r  r  r3  s        r%   
isViolatedz!FixedElasticSubProblem.isViolated  s     (*//),UV^$		1II99eVWf> II-d.?.?.A-B*TXXJWXr'   c                <    | j                         | j                  z
  S )zT
        The amount the actual value varies from the RHS (sense: LHS - RHS)
        )r  r  r*   s    r%   findDifferenceFromRHSz,FixedElasticSubProblem.findDifferenceFromRHS  s       "TXX--r'   c                    | j                  d      }| j                  d      }| j                  d      }| j                  j                         }|t        d      || j                  z
  |z
  |z
  |z
  S )
        for elastic constraints finds the LHS value of the constraint without
        the free variable and or penalty variable assumes the constant is on the
        rhs
        r  r  r  zConstraint has no value)r  r   r   r   r  )r#   r  r  r  r   s        r%   r  z#FixedElasticSubProblem.findLHSValue  sp     (*//),__**,
677DMM)E1F:WDDr'   c                H    d| j                   _        d| j                  _        y)zde-elasticize constraintr   N)r  ry   r  rw   r*   s    r%   deElasticizez#FixedElasticSubProblem.deElasticize  s    

 r'   c                    d| j                   _        d| j                   _        d| j                  _        d| j                  _        y)zF
        Make the Subproblem elastic again after deElasticize
        r   N)r  rw   ry   r  r*   s    r%   reElasticizez#FixedElasticSubProblem.reElasticize  s4      

!

#r'   c                   | d| _         t        | d      r| j                   dz   | j                  _         t        | d      r| j                   dz   | j                  _         t        | d      r| j                   dz   | j                  _         yy)	zC
        Alters the name of anonymous parts of the problem
        r  r  r  r  r  r  r  N)r$   hasattrr  r  r  r"   s     r%   	alterNamez FixedElasticSubProblem.alterName  sv     f/0	4# $		M 9DLL4!"ii*<<DJJO4"#yy+==DKK #r'   )NNN)r   rd   r  r  r  r  r  ztuple[float, float] | None)r  r   rh   r  r  r  )rj   rk   rl   rm   r3   r  r  r  r  r  r  r  r  r  s   @r%   r  r  M  sc    " !%,0>B"2 "2 "2 *	"2
 "<"2H .E!
$
>r'   r  c                  .    e Zd ZdZ	 	 	 	 	 ddZd Zd Zy)r  a@  
    Contains the subproblem generated by converting a Fraction constraint
    numerator/(numerator+complement) = b
    into an elastic constraint

    :param name: The name of the elastic subproblem
    :param penalty: penalty applied for violation (+ve or -ve) of the constraints
    :param proportionFreeBound: the proportional bound (+ve and -ve) on
        constraint violation that is free from penalty
    :param proportionFreeBoundList: the proportional bound on
        constraint violation that is free from penalty, expressed as a list
        where [-ve, +ve]
    Nc
                <   | d}
|| _         |||| _        ||z   | _        n+|||| _        ||z
  | _        nt        j                  d      || _        d x| _        | _        t        j                  | |
t        j                         t        ddd      | _        t        ddd      | _        t        ddd      | _        |r||g}	|	r|	\  }}nd\  }}| t               z  } |t        j                   t        j"                  fv r||z   | _        t%        | j                   | j                  t        j"                  | j                  | j                  	      | _        |Ud | j                  _        | xj*                  d
|z  | j                  z  z  c_        | xj&                  | j                  z  c_        | | j&                  dfz  } |t        j                   t        j,                  fv r||z
  | _        t%        | j                   | j                  t        j,                  | j                  | j                  	      | _        |Rd | j                  _        | xj*                  || j                  z  z  c_        | xj.                  | j                  z  c_        | | j.                  dfz  } y y )Nr  z8only one of denominator and complement must be specifiedr  r   r  r  r  )r   r   )r  r   _upper_constraint_lower_constraint)r  r  r  r}   rT  r  	lowTargetupTargetr  r3   r  rc   r  r  r  r>   ry  rt  r  upConstraintrw   r  rw  lowConstraintry   )r#   r$   r  r  r  r  r  r  r  r  r  upProportionFreeBoundlowProportionFreeBounds                r%   r3   z"FractionElasticSubProblem.__init__  sm    !6!45":#9(DO(:5D$);*D)I5DO//J  )--41A1AB!-QG 2AJ
 !3QK':<O&P#"<S9!#9<B9!#9"$$U))5+?+?@@"77DM 4$$ ,,!D "'+$"w,"<<!!T[[0!D%%':::DU))5+?+?@@ #99DN!5$$ ,,"D "%)

"'DJJ"66""djj0"D&&(;;;D Ar'   c                "   t        t        | j                              t        j                  k\  r+t        | j
                        t        | j                        z  S t        t        | j
                              t        j                  k  ryt        )r  r  r  r*   s    r%   r  z&FractionElasticSubProblem.findLHSValue"	  sb     uT%%&'5994(51A1A+BBB5()UYY6''r'   c                   t        t        | j                              t        j                  k\  rV| j
                  | j
                  | j                         kD  ry| j                  | j                         | j                  kD  ryyyy)r  NTF)r   r   r  r}   r  r  r  r  r*   s    r%   r  z$FractionElasticSubProblem.isViolated2	  ss     uT%%&'5994~~)>>D$5$5$77}}($$&6 7 )
 r'   )NNNNN)rj   rk   rl   rm   r3   r  r  rA   r'   r%   r  r    s)    (   $D<L( r'   r  c                4    t               j                  |       S )zl
    Calculate the sum of a list of linear expressions

    :param vector: A list of linear expressions
    )r>   rQ  )vectors    r%   lpSumr  B	  s     **622r'   c                H    t        | t              xr t        | t               S r)   )rb   r   r>   )rJ  s    r%   _vector_liker  S	  s    c8$PZ=O-P)PPr'   c           
     8   t        |       st        |      s| |z  S t        |       st        | gt        |      z  |      S t        |      st        | |gt        |       z        S t        t	        | |      D cg c]  \  }}t        ||       c}}      S c c}}w )z<Calculate the dot product of two lists of linear expressions)r  lpDotr   r  r  )v1v2e1e2s       r%   r  r  W	  s    L$4Bw"bTCG^R(("R"B((#b"+>BeBm>??>s   8B
)r  zuIterable[LpAffineExpression | LpVariable | int | float] | Iterable[tuple[LpElement, float]] | int | float | LpElement)6
__future__r   collectionsr   sysr   rR  r   typingr   r   apisr	   r
   	apis.corer   	utilitiesr   r   r   r}   r   r(  collections.abcr   logging	getLoggerrj   r  r   r   rG  stringr   r  platformodictr   ImportErrorujsonr  ro   r   rc   r>   rd   r  r  r  r  r  r  r  r  rA   r'   r%   <module>r     s   #2`D   
     /      $ g!!I 
<<w% 
+ 
 
\ \~LE LE^~ ~BL L^<@< <@~'i '(J JZ}>Y }>@r 6 rj3	3"Q	@KF  ! !    
  sH   %D	 D D% D0 	DDD"!D"%D-,D-0	D<;D<