Working with parameters¶
Note that the sole purpose of parameters is to change its value later and see how it would impact the model and its solution. When the value of a parameter changes, the model will be updated automatically. If the value of a parameter never changes, it is better to get rid of it for the sake of efficiency. However, you may still want to use it for more meaningful representation of the model.
Creating parameters¶
It is very simple to create parameters. Let’s illustrate with an interactive Python session:
>>> from pymprog import *
>>> k = par('k', [2, 3, 4])
>>> type(k)
<type 'list'>
>>> k[1]
(k[1]:3)
There is one important property of parameter creation: the original indexing of the raw values you passed in remains unchanged for the created parameters. Let’s continue with this live illustration:
>>> p = par('P', {'east':0, 'west':2, 'south':3, 'north':1})
>>> type(p)
<type 'dict'>
>>> p['east']
(P['east']:0)
From these examples we see that the function par(...) can create parameters according to the index scheme of the value argument. It is nice to use help(par) to find out the following information:
Arguments:
name(required): a str for the name of the parameter(s).
val(default 0): may take the following types of values:
1. a single value in (int, long, float)
-> a single parameter with the given name a value.
2. a list/tuple of values -> a list of parameters,
with names indicating the position index.
3. a dict of values -> a dict of parameters,
with names indicating the key index into the dict.
4. an iterable of values -> same as type 2.
The cool thing about it is that it is recursive:
>>> r = [{(3,4):3, (1,2):4}, 5]
>>> R = par('R', r)
>>> R
[{(1, 2): (R[0][1,2]:4), (3, 4): (R[0][3,4]:3)}, (R[1]:5)]
>>> r[0][3,4]
3
>>> R[0][3,4]
(R[0][3,4]:3)
>>> r[1]
5
>>> R[1]
(R[1]:5)
Finally, you may define several parameters in one call:
>>> par('x, y', 3, 5)
[(x:3), (y:5)]
>>> a, b, c = par('a,b,c', 3, (5,2))
>>> a, b, c
((a:3), [(b[0]:5), (b[1]:2)], (c:0))
Folks, that’s pretty much there is to it!
Changing the value¶
From a user’s point of view, changing the value of a parameter is very, very simple, you just do something like this:
>>> p.value = new_value
Since now you are already an insider to PyMathProg, we’d like to share with you the things done on the backstage for this value change to take effect throughout the entire model. When this value change happens, all related elements that depend on this value are informed of this change. These elements will then request the model for update. The model would simply queque up the requests until the last moment when the update is needed. This is done for the sake of performance, for updating too eagerly would endup updating one elements several times if several related parameters changes over time. Sometimes updating could be quite expensive. This approach is known as lazy update.
There are two distinct kinds of situations where updates are needed:
- the time before solving the model: all the elements in the model that needs update must be updated.
- the time when a the value/property of an element is requested, such as in an interactive session when an object is represented to the user. In this case only the requested element is updated (if needed).
An example for value change¶
Here is a small example to show the effect of value changes. Sensitivity report is also provided for you to evaluate the result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | from pymprog import *
begin('trader')
x = var('x', 3)
c = par('c', [100, 300, 50])
b = par('b', [93000, 101, 201])
maximize(sum(c[i]*x[i] for i in range(3)), 'Profit')
300*x[0] + 1200*x[1] + 120*x[2] <= b[0]
0.5*x[0] + x[1] + 0.5*x[2] <= b[1]
solve()
sensitivity()
b[1].value += 1
solve()
end()
|
If you run this code, the output would be something like this:
GLPK Simplex Optimizer, v4.60
2 rows, 3 columns, 6 non-zeros
* 0: obj = -0.000000000e+00 inf = 0.000e+00 (3)
* 2: obj = 2.560000000e+04 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND
PyMathProg 1.0 Sensitivity Report Created: 2016/12/10 Sat 15:01PM
================================================================================
Variable Activity Dual.Value Obj.Coef Range.From Range.Till
--------------------------------------------------------------------------------
*x[0] 94 0 100 87.5 150
*x[1] 54 0 300 200 366.667
x[2] 0 -20 50 -inf 70
================================================================================
================================================================================
Constraint Activity Dual.Value Lower.Bnd Upper.Bnd RangeLower RangeUpper
--------------------------------------------------------------------------------
R1 93000 0.166667 -inf 93000 60600 121200
R2 101 100 -inf 101 77.5 155
================================================================================
GLPK Simplex Optimizer, v4.60
2 rows, 3 columns, 6 non-zeros
* 2: obj = 2.570000000e+04 inf = 0.000e+00 (0)
OPTIMAL LP SOLUTION FOUND