Skip to content

Commit

Permalink
Merge pull request #914 from scipopt/dominiks_comments_for_docs
Browse files Browse the repository at this point in the history
Add comments from dominik
  • Loading branch information
mmghannam authored Oct 11, 2024
2 parents 4979c99 + 0ca4f65 commit 38fb332
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 80 deletions.
90 changes: 45 additions & 45 deletions docs/tutorials/constypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,29 @@ To create a standard linear or non-linear constraint use the command:
# Non-linear constraint
nonlinear_cons = scip.addCons(x * y + z == 1, name="nonlinear_cons")
What is a Row?
================
In a similar fashion to Variables with columns, see :doc:`this page </tutorials/vartypes>`,
constraints bring up an interesting feature of SCIP when used in the context of an LP.
The context of an LP here means that we are after the LP relaxation of the optimization problem
at some node. Is the constraint even in the LP?
When you solve an optimization problm with SCIP, the problem is first transformed. This process is
called presolve, and is done to accelerate the subsequent solving process. Therefore a constraint
that was originally created may have been transformed entirely, as the original variables that
featured in the constraint have also been changed. Additionally, maybe the constraint was found to be redundant,
i.e., trivially true, and was removed. The constraint is also much more general
than necessary, containing information that is not strictly necessary for solving the LP,
and may not even be representable by linear constraints.
Therefore, when representing a constraint in an LP, we use Row objects.
Be warned however, that this is not necessarily a simple one-to-one matching. Some more complicated
constraints may either have no Row representation in the LP or have multiple such rows
necessary to best represent it in the LP. For a standard linear constraint the Row
that represents the constraint in the LP can be found with the code:
Quicksum
========

.. code-block:: python
It is very common that when constructing constraints one wants to use the inbuilt ``sum`` function
in Python. For example, consider the common scenario where we have a set of binary variables.

row = scip.getRowLinear(linear_cons)
.. code-block:: python
.. note:: Remember that such a Row representation refers only to the latest LP, and is
best queried when access to the current LP is clear, e.g. when branching.
x = [scip.addVar(vtype='B', name=f"x_{i}") for i in range(1000)]
From a Row object one can easily obtain information about the current LP. Some quick examples are
the lhs, rhs, constant shift, the columns with non-zero coefficient values, the matching
coefficient values, and the constraint handler that created the Row.
A standard constraint in this example may be that exactly one binary variable can be active.
To sum these varaibles we recommend using the custom ``quicksum`` function, as it avoids
intermediate data structure and adds terms inplace. For example:

.. code-block:: python
lhs = row.getLhs()
rhs = row.getRhs()
constant = row.getConstant()
cols = row.getCols()
vals = row.getVals()
origin_cons_name = row.getConsOriginConshdlrtype()
scip.addCons(quicksum(x[i] for i in range(1000)) == 1, name="sum_cons")
.. note:: While this is often unnecessary for smaller models, for larger models it can have a substantial
improvement on time spent in model construction.

.. note:: For ``prod`` there also exists an equivalent ``quickprod`` function.

Constraint Information
======================
Expand Down Expand Up @@ -156,25 +139,42 @@ An example of such a constraint handler
is presented in the lazy constraint tutorial for modelling the subtour elimination
constraints :doc:`here </tutorials/lazycons>`

Quicksum
========
What is a Row?
================

It is very common that when constructing constraints one wants to use the inbuilt ``sum`` function
in Python. For example, consider the common scenario where we have a set of binary variables.
In a similar fashion to Variables with columns, see :doc:`this page </tutorials/vartypes>`,
constraints bring up an interesting feature of SCIP when used in the context of an LP.
The context of an LP here means that we are after the LP relaxation of the optimization problem
at some node. Is the constraint even in the LP?
When you solve an optimization problm with SCIP, the problem is first transformed. This process is
called presolve, and is done to accelerate the subsequent solving process. Therefore a constraint
that was originally created may have been transformed entirely, as the original variables that
featured in the constraint have also been changed. Additionally, maybe the constraint was found to be redundant,
i.e., trivially true, and was removed. The constraint is also much more general
than necessary, containing information that is not strictly necessary for solving the LP,
and may not even be representable by linear constraints.
Therefore, when representing a constraint in an LP, we use Row objects.
Be warned however, that this is not necessarily a simple one-to-one matching. Some more complicated
constraints may either have no Row representation in the LP or have multiple such rows
necessary to best represent it in the LP. For a standard linear constraint the Row
that represents the constraint in the LP can be found with the code:

.. code-block:: python
x = [scip.addVar(vtype='B', name=f"x_{i}") for i in range(1000)]
A standard constraint in this example may be that exactly one binary variable can be active.
To sum these varaibles we recommend using the custom ``quicksum`` function, as it avoids
intermediate data structure and adds terms inplace. For example:
row = scip.getRowLinear(linear_cons)
.. code-block:: python
.. note:: Remember that such a Row representation refers only to the latest LP, and is
best queried when access to the current LP is clear, e.g. when branching.

scip.addCons(quicksum(x[i] for i in range(1000)) == 1, name="sum_cons")
From a Row object one can easily obtain information about the current LP. Some quick examples are
the lhs, rhs, constant shift, the columns with non-zero coefficient values, the matching
coefficient values, and the constraint handler that created the Row.

.. note:: While this is often unnecessary for smaller models, for larger models it can have a substantial
improvement on time spent in model construction.
.. code-block:: python
.. note:: For ``prod`` there also exists an equivalent ``quickprod`` function.
lhs = row.getLhs()
rhs = row.getRhs()
constant = row.getConstant()
cols = row.getCols()
vals = row.getVals()
origin_cons_name = row.getConsOriginConshdlrtype()
6 changes: 3 additions & 3 deletions docs/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ more detailed information see `this page <https://www.scipopt.org/doc/html/index
:caption: Contents:

model
logfile
expressions
readwrite
vartypes
constypes
expressions
readwrite
logfile
branchrule
cutselector
separator
Expand Down
65 changes: 33 additions & 32 deletions docs/tutorials/vartypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,39 @@ For the following let us assume that a Model object is available, which is creat

.. contents:: Contents

Variable Types
===============

SCIP has four different types of variables:

.. list-table:: Variable Types
:widths: 25 25 25
:align: center
:header-rows: 1

* - Variable Type
- Abbreviation
- Description
* - Continuous
- C
- A continuous variable belonging to the reals with some lower and upper bound
* - Integer
- I
- An integer variable unable to take fractional values in a solution with some lower and upper bound
* - Binary
- B
- A variable restricted to the values 0 or 1.
* - Implicit Integer
- M
- A variable that is continuous but can be inferred to be integer in any valid solution

The variable type can be queried from the Variable object.

.. code-block:: python
x = scip.addVar(vtype='C', name='x')
assert x.vtype() == "CONTINUOUS"
Dictionary of Variables
=========================

Expand Down Expand Up @@ -95,38 +128,6 @@ Given a Model object, all added variables can be retrieved with the function:
scip_vars = scip.getVars()
Variable Types
=================

SCIP has four different types of variables:

.. list-table:: Variable Types
:widths: 25 25 25
:align: center
:header-rows: 1

* - Variable Type
- Abbreviation
- Description
* - Continuous
- C
- A continuous variable belonging to the reals with some lower and upper bound
* - Integer
- I
- An integer variable unable to take fractional values in a solution with some lower and upper bound
* - Binary
- B
- A variable restricted to the values 0 or 1.
* - Implicit Integer
- M
- A variable that is continuous but can be inferred to be integer in any valid solution

The variable type can be queried from the Variable object.

.. code-block:: python
x = scip.addVar(vtype='C', name='x')
assert x.vtype() == "CONTINUOUS"
Variable Information
=======================
Expand Down

0 comments on commit 38fb332

Please sign in to comment.