Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type to loop variables only #947

Merged
merged 12 commits into from
Feb 1, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

## Unreleased
### Added
- Added cdef to loop variables for slight speedup
Joao-Dionisio marked this conversation as resolved.
Show resolved Hide resolved
- Added wrappers for setting and getting heuristic timing
- Added transformed option to getVarDict, updated test
- Added categorical data example
1 change: 1 addition & 0 deletions src/pyscipopt/benders.pxi
Original file line number Diff line number Diff line change
@@ -175,6 +175,7 @@ cdef SCIP_RETCODE PyBendersSolvesub (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL
cdef SCIP_RETCODE PyBendersPostsolve (SCIP* scip, SCIP_BENDERS* benders, SCIP_SOL* sol,
SCIP_BENDERSENFOTYPE type, int* mergecands, int npriomergecands, int nmergecands, SCIP_Bool checkint,
SCIP_Bool infeasible, SCIP_Bool* merged) noexcept with gil:
cdef int i
DominikKamp marked this conversation as resolved.
Show resolved Hide resolved
cdef SCIP_BENDERSDATA* bendersdata
bendersdata = SCIPbendersGetData(benders)
PyBenders = <Benders>bendersdata
16 changes: 16 additions & 0 deletions src/pyscipopt/conshdlr.pxi
Original file line number Diff line number Diff line change
@@ -169,6 +169,7 @@ cdef SCIP_RETCODE PyConsFree (SCIP* scip, SCIP_CONSHDLR* conshdlr) noexcept with

cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef int i
cdef constraints = []
DominikKamp marked this conversation as resolved.
Show resolved Hide resolved
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
@@ -178,6 +179,7 @@ cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c
cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexit(constraints)
@@ -186,6 +188,7 @@ cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c
cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitpre(constraints)
@@ -194,6 +197,7 @@ cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitpre(constraints)
@@ -202,6 +206,7 @@ cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consinitsol(constraints)
@@ -210,6 +215,7 @@ cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
cdef SCIP_RETCODE PyConsExitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool restart) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consexitsol(constraints, restart)
@@ -246,6 +252,7 @@ cdef SCIP_RETCODE PyConsTrans (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* s
cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool* infeasible) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consinitlp(constraints)
@@ -255,6 +262,7 @@ cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.conssepalp(constraints, nusefulconss)
@@ -265,6 +273,7 @@ cdef SCIP_RETCODE PyConsSepasol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
SCIP_SOL* sol, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
@@ -276,6 +285,7 @@ cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfolp(constraints, nusefulconss, solinfeasible)
@@ -285,6 +295,7 @@ cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
@@ -296,6 +307,7 @@ cdef SCIP_RETCODE PyConsEnfops (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consenfops(constraints, nusefulconss, solinfeasible, objinfeasible)
@@ -306,6 +318,7 @@ cdef SCIP_RETCODE PyConsCheck (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
solution = Solution.create(scip, sol)
@@ -317,6 +330,7 @@ cdef SCIP_RETCODE PyConsProp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c
SCIP_PROPTIMING proptiming, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
result_dict = PyConshdlr.consprop(constraints, nusefulconss, nmarkedconss, proptiming)
@@ -330,6 +344,7 @@ cdef SCIP_RETCODE PyConsPresol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS**
int* ndelconss, int* naddconss, int* nupgdconss, int* nchgcoefs, int* nchgsides, SCIP_RESULT* result) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
# dictionary for input/output parameters
@@ -403,6 +418,7 @@ cdef SCIP_RETCODE PyConsDisable (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS*
cdef SCIP_RETCODE PyConsDelvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil:
PyConshdlr = getPyConshdlr(conshdlr)
cdef constraints = []
cdef int i
for i in range(nconss):
constraints.append(getPyCons(conss[i]))
PyConshdlr.consdelvars(constraints)
1 change: 1 addition & 0 deletions src/pyscipopt/cutsel.pxi
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ cdef SCIP_RETCODE PyCutselExitsol (SCIP* scip, SCIP_CUTSEL* cutsel) noexcept wit
cdef SCIP_RETCODE PyCutselSelect (SCIP* scip, SCIP_CUTSEL* cutsel, SCIP_ROW** cuts, int ncuts,
SCIP_ROW** forcedcuts, int nforcedcuts, SCIP_Bool root, int maxnselectedcuts,
int* nselectedcuts, SCIP_RESULT* result) noexcept with gil:
cdef int i
cdef SCIP_CUTSELDATA* cutseldata
cdef SCIP_ROW* scip_row
cutseldata = SCIPcutselGetData(cutsel)
24 changes: 23 additions & 1 deletion src/pyscipopt/lp.pxi
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ cdef class LP:
lb -- lower bound (default 0.0)
ub -- upper bound (default infinity)
"""
cdef int i
nnonz = len(entries)
DominikKamp marked this conversation as resolved.
Show resolved Hide resolved

Joao-Dionisio marked this conversation as resolved.
Show resolved Hide resolved
cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
@@ -95,7 +96,8 @@ cdef class LP:
lbs -- lower bounds (default 0.0)
ubs -- upper bounds (default infinity)
"""

cdef int i

ncols = len(entrieslist)
nnonz = sum(len(entries) for entries in entrieslist)

Joao-Dionisio marked this conversation as resolved.
Show resolved Hide resolved
@@ -158,6 +160,8 @@ cdef class LP:
lhs -- left-hand side of the row (default 0.0)
rhs -- right-hand side of the row (default infinity)
"""
cdef int i

beg = 0
nnonz = len(entries)

@@ -188,6 +192,8 @@ cdef class LP:
lhss -- left-hand side of the row (default 0.0)
rhss -- right-hand side of the row (default infinity)
"""
cdef int i

nrows = len(entrieslist)
nnonz = sum(len(entries) for entries in entrieslist)

@@ -232,6 +238,8 @@ cdef class LP:
firstcol -- first column (default 0)
lastcol -- last column (default ncols - 1)
"""
cdef int i

lastcol = lastcol if lastcol != None else self.ncols() - 1

if firstcol > lastcol:
@@ -261,6 +269,8 @@ cdef class LP:
firstrow -- first row (default 0)
lastrow -- last row (default nrows - 1)
"""
cdef int i

lastrow = lastrow if lastrow != None else self.nrows() - 1

if firstrow > lastrow:
@@ -363,6 +373,8 @@ cdef class LP:

def getPrimal(self):
"""Returns the primal solution of the last LP solve."""
cdef int i

ncols = self.ncols()
cdef SCIP_Real* c_primalsol = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, c_primalsol, NULL, NULL, NULL))
@@ -379,6 +391,8 @@ cdef class LP:

def getDual(self):
"""Returns the dual solution of the last LP solve."""
cdef int i

nrows = self.nrows()
cdef SCIP_Real* c_dualsol = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, NULL, c_dualsol, NULL, NULL))
@@ -395,6 +409,8 @@ cdef class LP:

def getPrimalRay(self):
"""Returns a primal ray if possible, None otherwise."""
cdef int i

if not SCIPlpiHasPrimalRay(self.lpi):
return None
ncols = self.ncols()
@@ -409,6 +425,8 @@ cdef class LP:

def getDualRay(self):
"""Returns a dual ray if possible, None otherwise."""
cdef int i

if not SCIPlpiHasDualRay(self.lpi):
return None
nrows = self.nrows()
@@ -429,6 +447,8 @@ cdef class LP:

def getRedcost(self):
"""Returns the reduced cost vector of the last LP solve."""
cdef int i

ncols = self.ncols()

cdef SCIP_Real* c_redcost = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
@@ -443,6 +463,8 @@ cdef class LP:

def getBasisInds(self):
"""Returns the indices of the basic columns and rows; index i >= 0 corresponds to column i, index i < 0 to row -i-1"""
cdef int i

nrows = self.nrows()
cdef int* c_binds = <int*> malloc(nrows * sizeof(int))

1 change: 1 addition & 0 deletions src/pyscipopt/reader.pxi
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@ cdef SCIP_RETCODE PyReaderWrite (SCIP* scip, SCIP_READER* reader, FILE* file,
SCIP_VAR** fixedvars, int nfixedvars, int startnvars,
SCIP_CONS** conss, int nconss, int maxnconss, int startnconss,
SCIP_Bool genericnames, SCIP_RESULT* result) noexcept with gil:
cdef int i
cdef SCIP_READERDATA* readerdata
readerdata = SCIPreaderGetData(reader)
cdef int fd = fileno(file)
87 changes: 77 additions & 10 deletions src/pyscipopt/scip.pxi

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions tests/test_event.py
Original file line number Diff line number Diff line change
@@ -82,8 +82,7 @@ def test_event():
s.addCons(quicksum(x[i] for i in range(100) if i%j==0) >= random.randint(10,100))

s.optimize()




def test_event_handler_callback():
m = Model()