
    kh              	         d dl mZ ddlmZmZmZmZmZmZ ddlm	Z	m
Z
mZ d dlZddlmZ d dlmZ erdd	lmZ d d
lmZ d dlZd dlZdZe
dk(  redz  ZdgZe
dk(  rdZej0                  j3                  ej0                  j5                  e      de
 de de       Z G d de      ZeZ G d de      ZddZ  G d de      Z!e!jE                         re!Zda# G d de      Z$da% G d de      Z&y)    )annotations   )LpSolver_CMDLpSolver
subprocessPulpSolverErrorclocklog)devnulloperating_systemarchN   )	constants)TYPE_CHECKING)	LpProblem)mktempcbcwinz.exezlibCoinMP.soosxi64z../solverdir/cbc//c                      e Zd ZdZd Zd Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZd ZddZd Z	dddZ
d	 Z	 dd
Zd Zd Zd Zy)COIN_CMDz5The COIN CLP/CBC LP solver
    now only uses cbc
    c                ,    | j                  t              S N)executableExtensioncbc_pathselfs    x/var/www/html/SchoolMeal/SchoolMeal/pds_admin_SchoolMeal/Backend/venv/lib/python3.12/site-packages/pulp/apis/coin_api.pydefaultPathzCOIN_CMD.defaultPath;   s    ''11    Nc                    t        j                  | fi d|d|d|d|d|d|d|d|	d	|
d
|d|d|d|d|d|d| y)a  
        :param bool mip: if False, assume LP even if integer variables
        :param bool msg: if False, no log is shown
        :param float timeLimit: maximum time for solver (in seconds)
        :param float gapRel: relative gap tolerance for the solver to stop (in fraction)
        :param float gapAbs: absolute gap tolerance for the solver to stop
        :param int threads: sets the maximum number of threads
        :param list options: list of additional options to pass to solver
        :param bool warmStart: if True, the solver will use the current value of variables as a start
        :param bool keepFiles: if True, files are saved in the current directory and not deleted after solving
        :param str path: path to the solver binary
        :param str logPath: path to the log file
        :param bool presolve: if True, adds presolve on, if False, adds presolve off
        :param bool cuts: if True, adds gomory on knapsack on probing on, if False adds cuts off
        :param int strong: number of variables to look at in strong branching (range is 0 to 2147483647)
        :param str timeMode: "elapsed": count wall-time to timeLimit; "cpu": count cpu-time
        :param int maxNodes: max number of nodes during branching. Stops the solving when reached.
        gapRelmipmsg	timeLimitpresolvecutsstrongoptions	warmStartpath	keepFilesthreadsgapAbslogPathtimeModemaxNodesN)r   __init__r   r%   r&   r'   r$   r0   r(   r)   r*   r+   r,   r.   r-   r/   r1   r2   r3   s                    r    r4   zCOIN_CMD.__init__>   s    L 		
	
 	
 		

  	
 	
 	
 	
 	
  	
 	
  	
 	
 	
 	
  !	
" #	
r"   c                R    t        j                  |       }| j                  |_        |S zMake a copy of self)r   copyoptionsDictr   aCopys     r    r8   zCOIN_CMD.copyx   s%    !!$' ,,r"   c                (     | j                   |fi |S )"Solve a well formulated lp problem)	solve_CBC)r   lpkwargss      r    actualSolvezCOIN_CMD.actualSolve~   s    t~~b+F++r"   c                8    | j                  | j                        S )True if the solver is available)
executabler-   r   s    r    	availablezCOIN_CMD.available   s    tyy))r"   c                &	   | j                  | j                        s-t        d| j                   dt        j                                | j                  |j                  dddd      \  }}}}|rC|j                  |d      \  }}}	}
d	|z   d	z   }|j                  t        j                  k(  r]|d
z  }nW|j                  |      }|D ci c]  }|j                  |j                   }}|j                  D ci c]  }|| }	}d	|z   d	z   }| j                  j                  dd      r| j                  |||||	       |d| d	z  }| j                   |d| j                    d	z  }| j                  j                  d      | j                  d   r|dz  }n|dz  }| j                  j                  d      | j                  d   r|dz  }n|dz  }| j"                  | j%                         z   }|D ]  }|d|z   d	z   z  } | j&                  r|dz  }n|dz  }|dz  }|d|z   d	z   z  }| j                  j                  d      }|r;| j(                  rt+        j,                  d       t/        | j                  d   d      }n| j1                         }t3        j4                  | j                  |z          g }|j7                  | j                         |j9                  |dd j;                                | j(                  s_t<        dk(  rVt?        j@                         }|xjB                  t>        jD                  z  c_!        t?        jF                  |||tH        |      }nt?        jF                  |||tH               }|jK                         d!k7  r*|r|jM                          t        d"| j                  z         	 |jM                          t        j                  jO                  |      st        d#| j                  z         | jQ                  |||||	      \  }}}}}}|jS                  |       |jU                  |       |jW                  |       |jY                  |d$%       |j[                  ||       | j]                  ||||       |S c c}w c c}w #  Y xY w)&zSolve a MIP problem using CBCzPulp: cannot execute z cwd: r?   mpssolmstr   )rename z-max r,   Fz-mips Nz-sec r(   z-presolve on z-presolve off r)   z"-gomory on knapsack on probing on z
-cuts off -z-branch z-initialSolve z-printingOptions all z
-solution r1   zS`logPath` argument replaces `msg=1`. The output will be redirected to the log file.wr   )stdoutstderrstdinstartupinfo)rN   rO   rP   r   zBPulp: Error while trying to execute, use msg=True for more detailszPulp: Error while executing T)activity)/rD   r-   r   osgetcwdcreate_tmp_filesnamewriteMPSsenser   
LpMaximizewriteLPconstraintsr9   getwritesolr'   r+   
getOptionsr%   r&   warningswarnopenget_piper
   debugappendextendsplitr   r   STARTUPINFOdwFlagsSTARTF_USESHOWWINDOWPopenr   waitcloseexistsreadsol_MPSassignVarsValsassignVarsDjassignConsPiassignConsSlackassignStatusdelete_tmp_files)r   r?   use_mpstmpLptmpMpstmpSoltmpMstvsvariablesNamesconstraintsNamesobjectiveNamecmdsvcr+   optionr1   pipeargsrQ   r   statusvaluesreducedCostsshadowPricesslacks
sol_statuss                              r    r>   zCOIN_CMD.solve_CBC   sc   tyy)!'		{&F  )-(=(=GGT5%)
%vvv BD++q CN C?B 0- <#%Dxx9///E"B689affaffn9N9.0nn=1==;$DU3MM&"b.:JKfVHA&&D>>%eDNN+1--D
+7
+-( .)'3'<= *%,,!22 	'FC&L3&&D	'88JD$$D''v%++""&&y1xxi ((3S9D==?D		$))d"#DIIDHNN$%xx,5$002K:#B#BB""T$g;C ""4TQC88:?

!T)) 	JJL ww~~f%!"@499"LMM VR^=MN	

&!
%
%
6D1

+feVV<c :=z	s   R5
R1R Rc                    t        dddddd      }|j                         D cg c]>  \  }}| j                  j                  |      |j	                  | j                  |         @ c}}S c c}}w )Nzratio {}zallow {}z
threads {}z	strong {}ztimeMode {}zmaxNodes {})r$   r0   r/   r*   r2   r3   )dictitemsr9   r\   format)r   	params_eqkr   s       r    r^   zCOIN_CMD.getOptions   sv     ""
	 ")
1##A&2 HHT%%a()
 	
 
s   AA,c                   |D ci c]  }|j                   d }}|j                         D 	ci c]  \  }	}||	
 }
}	}|j                         D 	ci c]  \  }	}||	
 }}	}i }i }i }| j                  |      \  }}t        |      5 }|D ]  }t	        |      dk  r n{|j                         }|d   dk(  r|dd }|d   }|d   }|d   }||
v r"t        |      ||
|   <   t        |      ||
|   <   ||v sjt        |      |||   <   t        |      |||   <    ddd       ||||||fS c c}w c c}}	w c c}}	w # 1 sw Y   "xY w)zf
        Read a CBC solution file generated from an mps or lp file (possible different names)
        r   r   z**r   N   )rV   r   
get_statusra   lenrf   float)r   filenamer?   rz   r{   r|   r}   r   r   r   	reverseVn	reverseCnr   r   r   r   r   flvnvaldjs                         r    rn   zCOIN_CMD.readsol_MPS   sv    &((!&&!)((&4&:&:&<=daQT=	=&6&<&<&>?daQT?	?!__X6
(^ 	<q <q6Q;GGIQ44<!"AqTdqT?,1#JF9R=)27)L2/?,1#JF9R=)27)L2/<	<" v|\6:MM5 )=?	< 	<s#   D'D,D2A,D83$D88Ec           
        |D ci c]/  }|j                   |j                         |j                         nd1 }}g }|t        |j                               D 	
cg c]  \  }	\  }
}|	|||
   df c}}
}	z  }dg}||D cg c]  } dj                  |  c}z  }t        |d      5 }|j                  |       ddd       yc c}w c c}}
}	w c c}w # 1 sw Y   yxY w)z
        Writes a CBC solution file generated from an mps / lp file (possible different names)
        returns True on success
        Nr   z$Stopped on time - objective value 0
z{:>7} {} {:>15} {:>23}
rM   T)rV   value	enumerater   r   ra   
writelines)r   r   r?   rz   r{   r|   r   r   value_linesir   linestupr   s                 r    r]   zCOIN_CMD.writesol  s    
 NPP!&&qwwy'<!'')!CPP2;N<P<P<R2S
 
%.QAQ6!9a 
 	
 99[Qc3,33S9QQ(C  	 ALL	   Q
 R	  s   4CC
 C'CCc                    |D ci c]  }|j                   |j                    }}|j                  D ci c]  }|| }}| j                  |||||      S c c}w c c}w )z
        Read a CBC solution file generated from an lp (good names)
        returns status, values, reducedCosts, shadowPrices, slacks, sol_status
        )rV   r[   rn   )r   r   r?   rz   r   r{   r   r|   s           r    
readsol_LPzCOIN_CMD.readsol_LP0  sa    
 355Q!&&!&&.55*,..9QAqD99"b.BRSS 69s
   A
Ac                   t         j                  t         j                  t         j                  t         j                  t         j                  d}t         j
                  t         j                  t         j                  t         j                  d}t        |      5 }|j                         j                         }d d d        |j                  d   t         j                        }|j                  |d   t         j                        }|t         j                  k(  r6t        |      dk\  r(|d   dk(  r t         j                  }t         j                  }||fS # 1 sw Y   xY w)N)Optimal
InfeasibleInteger	UnboundedStopped)r   r   r   r   r         	objective)r   LpStatusOptimalLpStatusInfeasibleLpStatusUnboundedLpStatusNotSolvedLpSolutionOptimalLpSolutionInfeasibleLpSolutionUnboundedLpSolutionNoSolutionFoundra   readlinerf   r\   LpStatusUndefinedr   LpSolutionIntegerFeasible)r   r   	cbcStatuscbcSolStatusr   
statusstrsr   r   s           r    r   zCOIN_CMD.get_status9  s    00#66 33"44 22
	 !22#88"66 ::	
 (^ 	.q++-J	. z!}i.I.IJ!%%qM9>>


 Y000S_5I!}+"22&@@
z!!	. 	.s   EETTNNNNNNNFFNNNelapsedN)r?   r   )Tr   )__name__
__module____qualname____doc__rV   r!   r4   r8   rA   rE   r>   r^   rn   r]   r   r    r"   r    r   r   4   s     D2
 #8
t,*dL
" QU ND$T"r"   r   c                     e Zd ZdZd ZeZ	 ej                  dk7  rK ej                  eej                        s.ddl	Z	 ej                  ee	j                  e	j                  z          	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy#  d Zd	dZY yxY w)
PULP_CBC_CMDzQ
    This solver uses a precompiled version of cbc provided with the package
    ntr   Nc                ~    |t        d      t        j                  | | j                  |||||||||	|
|||||       y )Nz&Use COIN_CMD if you want to set a path)r-   r%   r&   r'   r$   r0   r(   r)   r*   r+   r,   r.   r/   r1   r2   r3   )r   r   r4   pulp_cbc_pathr5   s                    r    r4   zPULP_CBC_CMD.__init__x  sb    & %&NOO''#!##!!#  r"   c                     yrC   Fr   r   s    r    rE   zPULP_CBC_CMD.availablek      r"   c                2    t        d| j                  z        )r=   z5PULP_CBC_CMD: Not Available (check permissions on %s))r   r   r   r?   callbacks      r    rA   zPULP_CBC_CMD.actualSolveo  s     !G$$% r"   r   r   )r   r   r   r   rV   r   rS   accessX_OKstatchmodS_IXUSRS_IXOTHr4   rE   rA   r   r"   r    r   r   \  s     D!M=77d?299]BGG4t||(CD$ #(			s   AA; ;	Br   c                   t         j                  dk(  r-t        j                  j	                  t        | d               }|S t        j                  }| dd D ]  }t        j                  ||        t        j                  | d   |      }|S )zu
    function that loads the DLL useful for debugging installation problems
    path is a list of paths actually
    r   N)mode)rS   rV   ctypeswindllLoadLibrarystrRTLD_GLOBALCDLL)r-   libr   libpaths       r    COINMP_DLL_load_dllr     s}    
 
ww$mm''DH6 J !!CRy 	,GKKd+	, kk$r(.Jr"   c                     e Zd ZdZd Z	  ee      ZdZdZ	dZ
dZej                  ej                  _        ej                   ej"                  _        ej                   ej$                  _        ej                  ej&                  _        ej                  ej(                  _        	 	 	 	 	 	 	 	 ddZd Zed        Zd	 Zd
 Zy# eef$ r ed        Zd ZY yw xY w)
COINMP_DLLz
    The COIN_MP LP MIP solver (via a DLL or linux so)

    :param timeLimit: The number of seconds before forcing the solver to exit
    :param epgap: The fractional mip tolerance
             "   c	                Z   t        j                  | g|	i |
 d | _        | j                  j	                  d      }|t        |      | _        | j                  t        | j                        | _        || _        || _        || _	        || _
        || _        || _        || _        || _        y )Nr$   )r   r4   fracGapr9   r\   r   r'   r)   r(   dualcrashscaleroundingintegerPresolver*   )r   r)   r(   r   r   r   r   r   r*   r   r@   r$   s               r    r4   zCOINMP_DLL.__init__  s     d4T4V4DL%%))(3F!$V}~~)!&t~~!6DI$DMDIDJDJ$DM#2D  DKr"   c                @   t        j                  |       }| j                  |_        | j                  |_        | j                  |_        | j
                  |_        | j                  |_        | j                  |_        | j                  |_        | j                  |_	        |S r7   )
r   r8   r)   r(   r   r   r   r   r   r*   r:   s     r    r8   zCOINMP_DLL.copy  sp    MM$'EEJ!]]ENEJ**EK**EK!]]EN$($8$8E!;;ELLr"   c                     yrC   Tr   clss    r    rE   zCOINMP_DLL.available   s     r"   c                6    | j                   j                         S )z
            returns a solver version string

            example:
            >>> COINMP_DLL().getSolverVersion() # doctest: +ELLIPSIS
            '...'
            )r   CoinGetVersionStrr   s    r    getSolverVersionzCOINMP_DLL.getSolverVersion  s     88--//r"   c                l   d| _         | j                  j                  d       | j                  j                  |j                        x| _        }| j                  j                  || j                  t        j                  | j                               | j                  r| j                  rE| j                  j                  || j                  t        j                  | j                               nD| j                  j                  || j                   t        j                  | j                               | j"                  rD| j                  j                  || j$                  t        j                  | j"                               | j                  j'                         }| j                   rt)        d       | j+                  |      \  }}}}}}	}
}}}}}}}}}}}}}}}| j                  j-                  |||||||
|	|||||||||||d       |j/                         r(| j                  r| j                  j1                  ||       | j                  dk(  rV| j                  j3                  |t        j4                  d       t        j6                  t        j                                      t9                | _        | j                  j=                  |d       | xj:                  t9               z  c_        t>        j@                  t>        jB                  t>        jB                  t>        jD                  t>        jD                  t>        jD                  t>        jF                  d}| j                  jI                  |      }| j                  jK                  |      }| j                  jM                  |      }t        j                  |z  }t        j                  |z  } |       }  |       }! |       }" |       }#| j                  jO                  |t        jP                  |       t        jP                  |!      t        jP                  |"      t        jP                  |#             i }$i }%i }&i }'|j/                         r,| j                  r | j                  jS                  |      |_*        tW        |      D ]@  }(| |(   |$| jX                  |(   j                  <   |!|(   |%| jX                  |(   j                  <   B |j[                  |$       |j]                  |%       tW        |      D ],  }(|#|(   |&| j^                  |(   <   |"|(   |'| j^                  |(   <   . |ja                  |&       |jc                  |'       | j                  je                          || j                  jI                  |         })|jg                  |)       |)S )r=   r    zBefore getCoinMPArrays	Objective)r   r   r   r   r   r   r   )4rc   r   CoinInitSolverCoinCreateProblemrV   hProbCoinSetIntOptionCOIN_INT_LOGLEVELr   c_intr&   r'   r%   CoinSetRealOptionCOIN_REAL_MIPMAXSECc_doubleCOIN_REAL_MAXSECONDSr   COIN_REAL_MIPFRACGAPCoinGetInfinityprintgetCplexStyleArraysCoinLoadProblemisMIPCoinLoadIntegerCoinRegisterMsgLogCallbackc_char_pPOINTERr	   coinTimeCoinOptimizeProblemr   r   r   r   r   CoinGetSolutionStatusCoinGetSolutionTextCoinGetObjectValueCoinGetSolutionValuesbyrefCoinGetMipBestBound	bestBoundrangen2vro   rp   n2crq   rr   CoinFreeSolverrs   )*r   r?   r   
coinDblMaxnumVarsnumRowsnumels
rangeCountobjectSenseobjectCoeffsobjectConst	rhsValuesrangeValuesrowType
startsBaselenBaseindBaseelemBaselowerBoundsupperBounds
initValuescolNamesrowNames
columnTyper  r  CoinLpStatussolutionStatussolutionTextobjectValueNumVarDoubleArrayNumRowsDoubleArray	cActivitycReducedCostcSlackValuescShadowPricesvariablevaluesvariabledjvaluesconstraintpivaluesconstraintslackvaluesr   r   s*                                             r    rA   zCOINMP_DLL.actualSolve  s    DJHH##B'!%!;!;BGG!DDDJHH%%t--v||DHH/E ~~88HH..t779X HH..117
 ||**444foodll6S 113Jzz./0 ((,/HH$$), xxzdhh((
;xx1}336??2.0Lv||0L0N #WHDMHH((2MMUW$M ,,////......//L "XX;;EBN8877>L((55e<K !'' 9!'7!:)+I,.L-/L.0MHH**Y'\*\*]+  N!!#$&!xxzdhh#xx;;EB7^ E3<Q<txx{//05A!_ !!1!12E n-OO,-7^ E2?2B"488A;/5A!_%dhhqk2E OO./45HH##%!$(("@"@"GHFOOF#Mr"   c                     yr   r   r   s    r    rE   zCOINMP_DLL.available  s     r"   c                    t        d      )r=   zCOINMP_DLL: Not Availabler   )r   r?   s     r    rA   zCOINMP_DLL.actualSolve  s    !"=>>r"   N)r   r   r   r   r   r   r   r   )r   r   r   r   rV   r   coinMP_pathr   r   r  r  r  r   r  r  restyper  r   r  r  r  r4   r8   classmethodrE   r   rA   ImportErrorOSErrorr   r"   r    r   r     s    D^!+. ! !&,oo#(.%*0//')/&*0//' 	!<	 
	 
		0L	a ! 	?		 
		?	?s   B? ?CCr   c                  ~    e Zd ZdZd Z	 ddla	 	 	 	 	 ddZd Zd ZddZ	d Z
dd	Zdd
Zy# e$ r
 d ZddZY yw xY w)YAPOSIBa  
    COIN OSI (via its python interface)

    Copyright Christophe-Marie Duquesne 2012

    The yaposib variables are available (after a solve) in var.solverVar
    The yaposib constraints are available in constraint.solverConstraint
    The Model is in prob.solverModel
    r   Nc                ~    t        j                  | ||       |r|| _        yt        j	                         d   | _        y)a  
            Initializes the yaposib solver.

            @param mip:          if False the solver will solve a MIP as
                                 an LP
            @param msg:          displays information from the solver to
                                 stdout
            @param timeLimit:    not supported
            @param epgap:        not supported
            @param solverParams: not supported
            r   N)r   r4   
solverNameyaposibavailable_solvers)r   r%   r&   r'   epgaprI  solverParamss          r    r4   zYAPOSIB.__init__  s5    ( dC-",")";";"=a"@r"   c                   |j                   }|j                  }t        j                  t        j                  t        j
                  t        j
                  t        j
                  d}|j                         D ]8  }|j                  j                  |_	        |j                  j                  |_        : |j                  j                         D ]F  }|j                  j                  |_        |j"                   |j                  j$                  z
  |_        H | j(                  rt+        d|       d|_        |j                         D ]	  }d|_         |j1                  |t        j                        }|j3                  |       |S )N)optimal	undefined	abandoned
infeasiblelimitreachedzyaposib status=TF)solverModelr   r   r   r   r   	variables	solverVarsolutionvarValuereducedcostr   r[   r   solverConstraintr   piconstantrR   slackr&   r  	resolveOK
isModifiedr\   rs   )r   r?   modelr1  yaposibLpStatusvarconstrr   s           r    findSolutionValueszYAPOSIB.findSolutionValues  s3   NNE"\\N$44&88&99':: ) < <O ||~ 3"}}55223 ..//1 S"3388	 &/&2I2I2R2RRS xx'8BL||~ '!&'$((9T9TUFOOF#Mr"   c                     yr   r   r   s    r    rE   zYAPOSIB.available  s    r"   c                F   d}| j                   dk(  rot        t               d      }t        j                  d      }t        j
                  d       t        j                  |j                               dk7  rt        d      t                | _	        |j                  j                  | j                         | xj                  t               z  c_	        | j                   dk(  r@t        j
                  d       t        j                  |       t        j
                  |       yy)zSolves the problem with yaposibNr   rM   r   z&couldn't redirect stdout - dup() error)r&   ra   r   rS   duprl   filenor   r	   	solveTimerT  solver%   )r   r?   r   
savestdouttempfiles        r    
callSolverzYAPOSIB.callSolver  s    Jxx1}#.VVAY
66(//+,1)*RSS#gXDNNN  *NNeg%Nxx1}z"$	 r"   c                   t        j                  d       t        j                  | j                        |_        |j
                  }|j                  |_        t        j                  d       |j                  t        j                  k(  rd|j                  _        t        j                  d       |j                         D ]  }|j                  j                  t        j                  g             }|j                  |_        |j                   |j                   |_        |j$                  |j$                  |_        |j(                  t        j*                  k(  rd|_        |j.                  j1                  |d      |j                  |j2                  <   ||_         t        j                  d       |j6                  j9                         D ]&  \  }}|j:                  j                  t        j                  |j9                         D cg c]  \  }}|j4                  j2                  |f c}}            }|j                  t        j<                  k(  r|j>                   |_        n}|j                  t        j@                  k(  r|j>                   |_        nM|j                  t        jB                  k(  r%|j>                   |_        |j>                   |_        ntE        d      ||_        ||_#        ) yc c}}w )	zX
            Takes the pulp lp model and translates it into a yaposib model
            zcreate the yaposib modelzset the sense of the problemTz add the variables to the problemNg        z"add the Constraints to the problem#Detected an invalid constraint type)$r
   rc   rJ  ProblemrI  rT  rV   rX   r   rY   objmaximizerU  colsaddveclowBound
lowerboundupBound
upperboundcat	LpIntegerintegerr   r\   indexrV  r[   r   rowsLpConstraintLEr\  LpConstraintGELpConstraintEQr   rZ  )	r   r?   probrb  colrV   
constraintr   rows	            r    buildSolverModelzYAPOSIB.buildSolverModel  s8    II01$__T__=BN>>DDIII45xx9///$(!II89||~ 
$iimmGKKO488||+%(\\CN{{*%([[CN77i111"&CK&(ll&6&6sC&@# #
$ II:;$&NN$8$8$: 2 jiimmKK /9.>.>.@ *U !]]00%8 ##y'?'??&0&9&9%9CN%%)A)AA&0&9&9%9CN%%)A)AA&0&9&9%9CN&0&9&9%9CN)*OPP.1
+'2s   "K5c                   | j                  |       t        j                  d       | j                  ||       | j	                  |      }|j                         D ]	  }d|_         |j                  j                         D ]	  }d|_         |S )z
            Solve a well formulated lp problem

            creates a yaposib model, variables and constraints and attaches
            them to the lp model which it then solves
            zSolve the model using yaposibr   F)	r  r
   rc   rm  rd  rU  modifiedr[   r   )r   r?   r   r1  rb  r  s         r    rA   zYAPOSIB.actualSolve9  s     !!"%II56OOBO2!44R8N||~ %$% nn335 ,
&+
#,!!r"   c                   t        j                  d       |j                  j                         D ]  }|j                  }|j
                  s|j                  t        j                  k(  r|j                   |_
        L|j                  t        j                  k(  r|j                   |_        ||j                  t        j                  k(  r%|j                   |_
        |j                   |_        t        d       | j                  ||       | j!                  |      }|j#                         D ]	  }d|_         |j                  j                         D ]	  }d|_         |S )z
            Solve a well formulated lp problem

            uses the old solver and modifies the rhs of the modified
            constraints
            zResolve the model using yaposibro  r  F)r
   rc   r[   r   rZ  r  rX   r   r  r\  ry  r  rw  r  r   rm  rd  rU  )r   r?   r   r  r  r1  rb  s          r    actualResolvezYAPOSIB.actualResolveL  s3    II78 nn335 U
 11&&!''9+C+CC*4*=*=)=#))Y-E-EE*4*=*=)=#))Y-E-EE*4*=*=)=*4*=*=)=-.STTU OOBO2!44R8N||~ %$% nn335 ,
&+
#,!!r"   c                     yr   r   r   s    r    rE   zYAPOSIB.available  r   r"   c                    t        d      )r=   zYAPOSIB: Not Availabler@  r   s      r    rA   zYAPOSIB.actualSolve  s    !":;;r"   )TTNNNr   )r   r   r   r   rV   rJ  r4   rd  rE   rm  r  rA   r  rD  r   r"   r    rG  rG    sk     Dw" 	 	A4	6		%&+	2Z	"&	"q  <		<<s   - <<rG  c                  ~     e Zd ZdZ	 ddlma 	 	 	 	 	 	 d fd	Zd Zd Zd Z	d Z
d	 Z xZS #  d
 Z	ddZY  xZS xY w)CYLPCyLPr   )cyc                V    t        |   d|||d| || _        || _        || _        y)a(  
            :param bool mip: if False, assume LP even if integer variables
            :param bool msg: if False, no log is shown
            :param float gapRel: relative gap tolerance for the solver to stop (in fraction)
            :param float gapAbs: absolute gap tolerance for the solver to stop
            :param int threads: sets the maximum number of threads
            :param float timeLimit: maximum time for solver (in seconds)
            :param dict solverParams: list of named options to pass directly to the HiGHS solver
            )r%   r&   r'   Nr   )superr4   r0   r$   r/   )	r   r%   r&   r0   r$   r/   r'   rM  	__class__s	           r    r4   zCYLP.__init__  s3    & GS#SlS DK DK"DLr"   c                @   | j                  |       | j                  |      }| j                  |       t        j                  t        j
                  t        j
                  t        j                  t        j                  t        j                  d}|j                  j                  }t        |       t        j
                  t        j
                  t        j                  t        j
                  t        j                  d}|j                  |t        j                        S )N)r   r   r   r   r   r   )zlinear relaxation unboundedzrelaxation infeasiblerW  zproblem proven infeasiblezrelaxation abandoned)r  rm  rd  r   r   r   r   r   rT  r   r  r\   )r   r?   r@   	my_statusmy_map	sol_statsmy_map_2s          r    rA   zCYLP.actualSolve  s    !!"%+I##B' ,,////....//F --I)/8/K/K)2)E)E%55-6-I-I(1(C(CH <<	9+F+FGGr"   c                    |j                         }|j                  j                  }t        ||      D ]  \  }}||_         y r   )rU  rT  primalVariableSolutionziprX  )r   r?   my_vars	my_valuesrb  r   s         r    rd  zCYLP.findSolutionValues  sB    llnG==I!'95 %
U$% r"   c                     y)NTr   r   s    r    rE   zCYLP.available  s    r"   c                (   t                | _        | j                  r| j                  |j                  _        | j
                  r| j
                  |j                  _        | j                  r| j                  |j                  _        | j                  r| j                  |j                  _
        | j                  j                  d      x}r||j                  _        |j                  j                         }| xj                  t               z  c_        |S )Nr3   )r	   ri  r'   rT  maximumSecondsr$   allowableFractionGapr0   allowableGapr/   numberThreadsr9   r\   maximumNodesrj  )r   r?   	max_nodesstop_statuss       r    rm  zCYLP.callSolver  s    #gXDN~~04-{{6:kk3{{.2kk+||/3||, ,,00<<y<.7+....0KNNeg%Nr"   c                   t         j                         }|j                   d}|j                  |       |j	                  |      }	 t        j                  |       |dk7  rt        d      |j                         }||_	        y #  Y ,xY w)Nz	-pulp.mpsr   zError reading MPS file)
r  CyClpSimplexrV   rW   readMpsrS   remover   getCbcModelrT  )r   r?   my_modelrw   success	cbc_models         r    r  zCYLP.buildSolverModel  s    (Hy	*FKK&&v.G		&! !|%&>?? ,,.I 'BN!s   B Bc                     yr   r   r   s    r    rE   zCYLP.availableu  r   r"   c                    t        d      )r=   zCyLP: Not Availabler@  r   s      r    rA   zCYLP.actualSolvey  s    !"788r"   )TTNNNNr   )r   r   r   rV   cylpr  r4   rA   rd  rE   rm  r  __classcell__)r  s   @r    r  r  m  s[    DB' 	#0	H4	(		$	'O9		9 	9s   . 	<r  )r-   z	list[str])'
__future__r   corer   r   r   r   r	   r
   r   r   r   rS   r   r   typingr   r   rl  r   r   r_   r   rA  r-   joindirname__file__r   r   COINr   r   r   rE   rJ  rG  r  r  r   r"   r    <module>r     s	  4 # Q Q 1 1 	      uHuDGGOOH!23C2DAdV1XJW
b"| b"J	 D8 DN"g gT D
C"h C"L 
E'8 E'r"   