
    khMY                     p    d dl mZmZmZmZmZmZ ddlmZ ddl	Z	ddl
Z
 G d de      Z G d d	e      ZeZy)
   )LpSolver_CMDLpSolver
subprocessPulpSolverErrorclocklog   )	constants    Nc                   d    e Zd ZdZd Z	 	 	 	 	 	 	 	 	 	 	 	 	 d
dZd Zd Zd Zd Z	e
d        Zd	 Zy)	CPLEX_CMDzThe CPLEX LP solverNc                 J    t        j                  | |||||||||	||
||       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 float maxMemory: max memory to use during the solving. Stops the solving when reached.
        :param int maxNodes: max number of nodes during branching. Stops the solving when reached.
        )gapRelmipmsg	timeLimitoptions	maxMemorymaxNodes	warmStartpath	keepFilesthreadsgapAbslogPathN)r   __init__)selfr   r   r   r   r   r   r   r   r   r   r   r   r   s                 y/var/www/html/SchoolMeal/SchoolMeal/pds_admin_SchoolMeal/Backend/venv/lib/python3.12/site-packages/pulp/apis/cplex_api.pyr   zCPLEX_CMD.__init__   s<    > 		
    c                 $    | j                  d      S )Ncplex)executableExtensionr   s    r   defaultPathzCPLEX_CMD.defaultPath<   s    ''00r   c                 8    | j                  | j                        S )True if the solver is available)
executabler   r#   s    r   	availablezCPLEX_CMD.available?   s    tyy))r   c                 l   | j                  | j                        st        d| j                  z         | j                  |j                  ddd      \  }}}|j                  |d      }	 t        j                  |       | j                  sNt        j                  | j                  t        j                  t        j                  t        j                        }n/t        j                  | j                  t        j                        }d	|z   d
z   }| j                  j                  dd      r#| j                  ||       |d	|z   d
z   z  }|dz  }| j                  |dt!        | j                        z   d
z   z  }| j"                  | j%                         z   }|D ]
  }	||	d
z   z  } |j'                         r| j(                  r|dz  }|dz  }n|dz  }|dz  }|d|z   d
z   z  }|dz  }|j+                  d      }|j-                  |       |j.                  dk7  rt        d| j                  z         t        j                  j1                  |      st2        j4                  }
dx}x}x}x}}n| j7                  |      \  }
}}}}}| j9                  |||       | j                  j                  d      dk7  r| j9                  d       |
t2        j4                  k7  rD|j;                  |       |j=                  |       |j?                  |       |jA                  |       |jC                  |
|       |
S #  Y xY w)"Solve a well formulated lp problemzPuLP: cannot execute lpsolmstr   )writeSOS)stdinstdoutstderr)r/   zread 
r   F)filenamevszset advance 1
Nzset timelimit zmipopt
zchange problem fixed
zchange problem lp
z	optimize
zwrite zquit
zUTF-8r   z$PuLP: Error while trying to execute r   z	cplex.log)"r'   r   r   create_tmp_filesnamewriteLPosremover   r   PopenPIPEoptionsDictgetwritesolr   strr   
getOptionsisMIPr   encodecommunicate
returncodeexistsr
   LpStatusInfeasiblereadsoldelete_tmp_filesassignVarsValsassignVarsDjassignConsPiassignConsSlackassignStatus)r   r+   tmpLptmpSoltmpMstr4   r!   
cplex_cmdsr   optionstatusvaluesreducedCostsshadowPricesslacks	solStatuss                   r   actualSolvezCPLEX_CMD.actualSolveC   s   tyy)!"9DII"EFF $ 5 5bggtUE RvvZZZ*	IIf xx$$		 oo!!	E $$TYYjooFEu_t+
U3MM6bM1'F*T11J++J>>%*S-@@4GGJ,,!22 	(F&4-'J	(88:xxj(
66
33
l"
h'$..
h
&&w/
*%q !"H499"TUUww~~f%11FHLLFL\LLL6I V$eVV4	*k9!!+.Y111f%OOL)OOL)v&
	*q	s   *L. .L3c                     t        dddddd      }|j                         D cg c]@  \  }}|| j                  v r-| j                  |   |j                  | j                  |         B c}}S c c}}w )Nzset logFile {}zset mip tolerances mipgap {}zset mip tolerances absmipgap {}zset mip limits treememory {}zset threads {}zset mip limits nodes {})r   r   r   r   r   r   )dictitemsr<   format)r   	params_eqkvs       r   r@   zCPLEX_CMD.getOptions   s     $144$.
	 ")
1D$$$)9)9!)<)H HHT%%a()
 	
 
s   AA.c           	         	 ddl mc m} |j                  |       j                         }|j                  d      }|j                  d      }|j                  d      }t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  d}||vrt        dj                  ||            ||   }t        j                  t        j                  t        j                  t        j                  t        j                  t        j                  d}|j                  |      }	i }
i }|j                  d	      }|D ]R  }|j                  d
      }|j                  d      }|j                  d      }	 t        |      |
|<   t        |      ||<   T i }i }|j                  d      D ]R  }|j                  d
      }|j                  d      }t        |      ||<   |j                  d      }	 t        |      ||<   T ||||
||	fS # t        $ r
 ddlm} Y Ow xY w# t        $ r d|
|<   Y w xY w# t        $ r d||<   Y w xY w)zRead a CPLEX solution filer   NheadersolutionStatusStringsolutionStatusValue)1101102104105107109113z;Unknown status returned by CPLEX: 
code: '{}', string: '{}')rh   ri   rj   rk   111rl   linearConstraintsr6   slackdual	variablesvaluereducedCost)xml.etree.ElementTreeetreeElementTreeImportErrorelementtree.ElementTreeparsegetrootfindr=   r
   LpStatusOptimalr   r]   LpSolutionIntegerFeasiblefloat	TypeError)r3   etsolutionXMLsolutionheaderstatusStringstatusValuecplexStatusrS   cplexSolStatusrX   rV   rW   constraints
constraintr6   ro   shadowPricerT   rU   variablerr   rs   s                         r   rG   zCPLEX_CMD.readsol   sx   	1.. hhx(002$))(3%))*@A$(()>?**,,,,,,,,,,,,,,	
 k)!NUU 
 [) 666666666666
 #&&{3	!&&':;% 		(J>>&)DNN7+E$..0K*%*;%7T" !<F4L		( #((5 		*H<<'DLL)E <F4L",,}5K*%*;%7T"		* v|\69LLy  	100	1V  *%)T"*  *%)T"*s5   	I 8I0I2III/.I/2JJc                 b   	 ddl mc m} |j                  dd      }t               }t               }|j                  |d|       |j                  |d|       |j                  |d      }|D cg c]/  }|j                         |j                  |j                         f1 }	}t        |	      D ]<  \  }
\  }}t        |t        |      t        |
      	      }|j                  |d
|       > |j                  |      }|j                  |dd       y# t        $ r
 ddlm} Y w xY wc c}w )zWrites a CPLEX solution filer   NCPLEXSolutionz1.2)versionrb   )attribrq   )r6   rr   indexr   zutf-8T)encodingxml_declaration)rt   ru   rv   rw   rx   Elementr[   
SubElementrr   r6   	enumerater?   write)r   r3   r4   r   rootattrib_headattrib_qualityrq   r`   rT   r   r6   rr   attrib_varsr-   s                  r   r>   zCPLEX_CMD.writesol   s   	1.. zz/5z9f
dH[9
dH^<MM$4	/1K!QWWY5J1661779%KK$-f$5 	E E=D%DE
#e*MKMM)ZMD	E nnT"		(Wd	C!  	100	1 Ls   	D 0D,D,D)(D))TTNNNNFFNNNNN)__name__
__module____qualname____doc__r6   r   r$   r(   rY   r@   staticmethodrG   r>    r   r   r   r      sm    D .
`1*@D
" AM AMFr   r   c                       e Zd ZdZd Z	 ddla	 	 	 	 	 	 	 ddZd ZddZd Z	d Z
dd	Zdd
ZddZd Zd Zd Zy# e$ rZeZ	 d Zd ZY dZ[ydZ[ww xY w)CPLEX_PYz
    The CPLEX LP/MIP solver (via a Python Binding)

    This solver wraps the python api of cplex.
    It has been tested against cplex 12.3.
    For api functions that have not been wrapped in this solver please use
    the base cplex classes
    r   Nc           
      >    t        j                  | |||||||       y)aO  
            :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 bool warmStart: if True, the solver will use the current value of variables as a start
            :param str logPath: path to the log file
            :param int threads: number of threads to be used by CPLEX to solve a problem (default None uses all available)
            )r   r   r   r   r   r   r   N)r   r   )r   r   r   r   r   r   r   r   s           r   r   zCPLEX_PY.__init__  s*    ( ##	r   c                      y)r&   Tr   r#   s    r   r(   zCPLEX_PY.available,  s    r   c                    | j                  |       t        j                  d       | j                  |       | j	                  |      }|j
                  D ]	  }d|_         |j                  j                         D ]	  }d|_         |S )z
            Solve a well formulated lp problem

            creates a cplex model, variables and constraints and attaches
            them to the lp model which it then solves
            zSolve the Model using cplexF)	buildSolverModelr   debug
callSolverfindSolutionValues
_variablesmodifiedr   rT   )r   r+   callbacksolutionStatusvarr   s         r   rY   zCPLEX_PY.actualSolve0  s     !!"%II34OOB!44R8N}} %$% nn335 ,
&+
#,!!r   c           	         |j                         }|D ci c]  }|j                  | c}| _        t        | j                        t        |      k7  rt	        d      t        j                  d       t        j                         x| _	        |_	        t        j                  d       | j                  s%| j                  j                  |j                         t        j                  d       |j                  t        j                  k(  rM|j                  j                  j!                  |j                  j                  j                  j"                         |j                  t	        d      |D cg c]'  }t%        |j                  j'                  |d            ) }}d }|D cg c]
  } ||       }}d	 }|D cg c]
  } ||       }}|D cg c]  }|j                   }	}d
 }
|D cg c]
  } |
|       }}dj)                  |      }|j                  j                   j+                  |||||	       g }g }g }t-        |j.                  j1                               }|j.                  j3                         D ]B  }t        |      dk(  r|j5                  g g f       n`|j1                         D cg c]  }|j                   }}|j3                         D cg c]  }t%        |       }}|j5                  ||f       |j                  t        j6                  k(  r|j5                  d       ni|j                  t        j8                  k(  r|j5                  d       n:|j                  t        j:                  k(  r|j5                  d       nt	        d      |j5                  t%        |j<                                E |j                  j>                  j+                  ||||       t        j                  d       | j                  s=| j                  jA                  t        j                  jB                  jD                         t        j                  d       | jF                  s| jI                  d       | jJ                  j'                  d      }|<| jF                  rtM        jN                  d       | jI                  tQ        |d             | jJ                  j'                  d      }|| jS                  |       | jT                  | jW                  | jT                         | jY                  | jJ                  j'                  dd             | jJ                  j'                  dd      r| j                  jZ                  j\                  j^                  }| j                  ja                         D cg c](  \  }}|jc                         ||jc                         f* }}}|stM        jN                  d       yte        | \  }}| j                  jZ                  j+                  t        jg                  ||      |d       yyc c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}}w )zV
            Takes the pulp lp model and translates it into a cplex model
            z1Variables must have unique names for cplex solverzcreate the cplex modelzset the name of the problemzset the sense of the problemNzNo objective set        c                 f    | j                   t        | j                         S t        j                   S N)lowBoundr~   r!   infinityr   s    r   cplex_var_lbz/CPLEX_PY.buildSolverModel.<locals>.cplex_var_lb[  s'    <<+ ..!NN?*r   c                 d    | j                   t        | j                         S t        j                  S r   )upBoundr~   r!   r   r   s    r   cplex_var_ubz/CPLEX_PY.buildSolverModel.<locals>.cplex_var_ubc  s%    ;;* -- >>)r   c                 @    | j                   t        j                  k(  ryy)NIC)catr
   	LpIntegerr   s    r   cplex_var_typesz2CPLEX_PY.buildSolverModel.<locals>.cplex_var_typesl  s    77i111r    )objlbubtypesnamesr   LGEz#Detected an invalid constraint type)lin_exprsensesrhsr   zset the type of the problemzset the loggingr   zS`logPath` argument replaces `msg=1`. The output will be redirected to the log file.wr   r   r   Fz.No variable with value found: mipStart aborted)indvalre   )4rq   r6   n2vlenr   r   r   r!   CplexsolverModelr   set_problem_namesenser
   
LpMaximize	objective	set_sensemaximizer~   r=   joinaddlistr   keysrT   appendLpConstraintLELpConstraintGELpConstraintEQconstantlinear_constraintsset_problem_typeproblem_typeLPr   
setlogfiler<   warningswarnopenchangeEpgapr   setTimeLimit
setThreads
MIP_startseffort_levelautor\   rr   zip
SparsePair)r   r+   model_variablesr   r   r   r   r   r   colnamesr   ctyperowsr   r   rownamesr   expr1coeffexpr2r   r   effortr_   r`   startr   r   s                               r   r   zCPLEX_PY.buildSolverModelC  s5    !llnO1@A##ADH488}O 44%G  II./05=Dr~II3488  11"'':II45xx9///((22NN,,22;; ||#%&899@OP5))#s34PCP+ 0??,s#?B?* 0??,s#?B?,;<S<H< 6EEc_S)EEEGGENENN$$((B2U( )  DFCBNN//12H nn335 8
z?a'KKR)1;1BC#SXXCEC7A7H7H7JKeU5\KEKKK/##y'?'??MM#&%%)A)AAMM#&%%)A)AAMM#&)*OPP

5*"5"5!567#8$ NN--11f#X 2  II3488  11%++2J2J2M2MNII'(88%&&**95G"88MMm Wc 23%%))(3F!  (~~)!!$..1OOD,,00DAB##K7))44AAFF/3xx~~/?'+q!1779CXQ	N  MM"RS;S  ++//$$#$6 8w B" Q @ @< F DKHs;   Y2,Y'Y?YY0Y$7Y)Y.:Y3Y3c                     | j                   j                  |       | j                   j                  |       | j                   j                  |       | j                   j	                  |       y)z;
            sets the logfile for cplex output
            N)r   set_error_streamset_log_streamset_warning_streamset_results_stream)r   fileobjs     r   r   zCPLEX_PY.setlogfile  sT     --g6++G4//8//8r   c                 j    | j                   j                  j                  j                  |xs d       y)zm
            Change cplex thread count used (None is default which uses all available resources)
            r   N)r   
parametersr   set)r   r   s     r   r   zCPLEX_PY.setThreads  s(     ''//33GLqAr   c                     | j                   j                  j                  j                  j                  j                  |       y)zI
            Change cplex solver integer bound gap tolerence
            N)r   r  r   
tolerancesmipgapr  )r   epgaps     r   r   zCPLEX_PY.changeEpgap  s0     ''++66==AA%Hr   c                 b    | j                   j                  j                  j                  |       y)zP
            Make cplex limit the time it takes --added CBM 8/28/09
            N)r   r  	timelimitr  )r   r   s     r   r   zCPLEX_PY.setTimeLimit  s$     ''1155i@r   c                     t                | _        | j                  j                          | xj                  t               z  c_        y)zSolves the problem with cplexN)r   	solveTimer   solve)r   rA   s     r   r   zCPLEX_PY.callSolver  s1     $gXDN""$NNeg%Nr   c                    i |j                   j                  j                  j                  t        j
                  |j                   j                  j                  j                  t        j
                  |j                   j                  j                  j                  t        j
                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                  t        j                  |j                   j                  j                  j                   t        j"                  |j                   j                  j                  j$                  t        j"                  |j                   j                  j                  j&                  t        j"                  |j                   j                  j                  j(                  t        j"                  |j                   j                  j                  j*                  t        j"                  |j                   j                  j                  j,                  t        j"                  |j                   j                  j                  j.                  t        j
                  |j                   j                  j                  j0                  t        j
                  |j                   j                  j                  j2                  t        j                  i}|j                   j                  j5                         |_        |j9                  |j6                  t        j:                        }|j                   j                  j                  j0                  t        j<                  |j                   j                  j                  j.                  t        j<                  |j                   j                  j                  j>                  t        j<                  i}|j9                  |j6                        }|jA                  ||       |jB                  D cg c]  }|jD                   }}|jF                  D cg c]  }| }	}	 |j                   j                  jI                         }
tK        tM        ||j                   j                  jO                  |                  }|jQ                  |       tK        tM        |	|j                   j                  jS                  |	                  }|jU                  |       |j                   jW                         tX        jZ                  j\                  j^                  k(  rtK        tM        ||j                   j                  ja                  |                  }|jc                  |       tK        tM        |	|j                   j                  je                  |	                  }|jg                  |       | jl                  rto        d|j6                         d|_8        |jB                  D ]	  }d|_9         |S c c}w c c}w # tX        jh                  jj                  $ r Y lw xY w)NzCplex status=TF):r   solutionrS   MIP_optimalr
   r|   optimaloptimal_tolerance
infeasiblerF   infeasible_or_unboundedMIP_infeasibleMIP_infeasible_or_unbounded	unboundedLpStatusUnboundedMIP_unboundedabort_dual_obj_limitLpStatusNotSolvedabort_iteration_limitabort_obj_limitabort_relaxedabort_time_limit
abort_userMIP_abort_feasibleMIP_time_limit_feasibleMIP_time_limit_infeasible
get_statuscplex_statusr=   LpStatusUndefinedr}   MIP_feasiblerM   r   r6   r   get_objective_valuer[   r   
get_valuesrI   get_linear_slacksrL   get_problem_typer!   r   r   r   get_reduced_costsrJ   get_dual_valuesrK   
exceptionsCplexSolverErrorr   print	resolveOK
isModified)r   r+   CplexLpStatusrS   CplexSolStatus
sol_statusr   	var_namescon	con_namesobjectiveValuevariablevaluesconstraintslackvaluesvariabledjvaluesconstraintpivaluess                  r   r   zCPLEX_PY.findSolutionValues  sc   ''..::I<U<U''..66	8Q8Q ''..@@)B[B[ ''..999;W;W	
 ''..FF	HdHd ''..==y?[?[ ''..JJILhLh ''..88):U:U ''..<<i>Y>Y ''..CCYE`E` ''..DDiFaFa ''..>>	@[@[ ''..<<i>Y>Y ''..??A\A\ ''..999;V;V  ''..AA9C\C\!" ''..FF	HaHa#$ ''..HH)JfJf%M( !nn55@@BBO"&&r	8S8STF''..FF	HkHk''..AA9CfCf''..;;Y=`=`N (++BOO<JOOFJ/-/]];c;I;(*77I7!#!8!8!L!L!N!%	2>>#:#:#E#Ei#PQ" !!.1(,	2>>#:#:#L#LY#WX)% ""#89>>2248P8P8S8SS'+%NN33EEiP($ OO$45)-%NN33CCIN*& OO$67 xxor7BL}} '!&'MK <74 ##44 s   >\7!	\<-F] ]! ]!c                     t        d      )zV
            looks at which variables have been modified and changes them
            z(Resolves in CPLEX_PY not yet implemented)NotImplementedError)r   r+   kwargss      r   actualResolvezCPLEX_PY.actualResolve  s     &&PQQr   c                      y)r&   Fr   r#   s    r   r(   zCPLEX_PY.available  s    r   c                 2    t        d| j                         )r*   zCPLEX_PY: Not Available:
)r   err)r   r+   s     r   rY   zCPLEX_PY.actualSolve  s    !$>txxj"IJJr   )TTNNFNNr   )g-C6?)r   )r   r   r   r   r6   r!   r   r(   rY   r   r   r   r   r   r   r   r@  	ExceptionerC  r   r   r   r   r      s     DaR" 	>		"&l	\	9	B	I	A	&D	L	Ru  
KK		K
Ks   < A	AAr   )corer   r   r   r   r   r   r   r
   r8   r   r   r   CPLEXr   r   r   <module>rH     s;    Q Q  	 g gTlRx lR^	 	r   