Variable
Bases: BaseOperableBlock
A decision variable for an optimization model.
Tip
If lb or ub are a dimensioned object (e.g. an Expression), they will automatically be broadcasted to match the variable's dimensions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*indexing_sets
|
SetTypes | Iterable[SetTypes]
|
If no indexing_sets are provided, a single variable with no dimensions is created. Otherwise, a variable is created for each element in the Cartesian product of the indexing_sets (see Set for details on behaviour). |
()
|
vtype
|
VType | VTypeValue
|
The type of the variable. Can be either a VType enum or a string. Default is VType.CONTINUOUS. |
CONTINUOUS
|
lb
|
Operable | None
|
The lower bound for the variables. |
None
|
ub
|
Operable | None
|
The upper bound for the variables. |
None
|
equals
|
Operable | None
|
When specified, a variable is created for every label in |
None
|
Examples:
>>> import pandas as pd
>>> m = pf.Model()
>>> df = pd.DataFrame(
... {"dim1": [1, 1, 2, 2, 3, 3], "dim2": ["a", "b", "a", "b", "a", "b"]}
... )
>>> Variable(df)
<Variable 'unnamed' height=6>
┌──────┬──────┐
│ dim1 ┆ dim2 │
│ (3) ┆ (2) │
╞══════╪══════╡
│ 1 ┆ a │
│ 1 ┆ b │
│ 2 ┆ a │
│ 2 ┆ b │
│ 3 ┆ a │
│ 3 ┆ b │
└──────┴──────┘
Variables cannot be used until they're added to the model.
>>> m.constraint = Variable(df) <= 3
Traceback (most recent call last):
...
ValueError: Cannot use 'Variable' before it has been added to a model.
Instead, assign the variable to the model first:
>>> m.v
<Variable 'v' height=6>
┌──────┬──────┬──────────┐
│ dim1 ┆ dim2 ┆ variable │
│ (3) ┆ (2) ┆ │
╞══════╪══════╪══════════╡
│ 1 ┆ a ┆ v[1,a] │
│ 1 ┆ b ┆ v[1,b] │
│ 2 ┆ a ┆ v[2,a] │
│ 2 ┆ b ┆ v[2,b] │
│ 3 ┆ a ┆ v[3,a] │
│ 3 ┆ b ┆ v[3,b] │
└──────┴──────┴──────────┘
>>> m.v2 = Variable(df[["dim1"]])
Traceback (most recent call last):
...
ValueError: Duplicate rows found in input data.
>>> m.v3 = Variable(df[["dim1"]].drop_duplicates())
>>> m.v3
<Variable 'v3' height=3>
┌──────┬──────────┐
│ dim1 ┆ variable │
│ (3) ┆ │
╞══════╪══════════╡
│ 1 ┆ v3[1] │
│ 2 ┆ v3[2] │
│ 3 ┆ v3[3] │
└──────┴──────────┘
Methods:
| Name | Description |
|---|---|
next |
Creates an expression where the variable at each label is the next variable in the specified dimension. |
to_expr |
Converts the Variable to an Expression. |
Attributes:
| Name | Type | Description |
|---|---|---|
attr |
Container
|
Allows reading and writing variable attributes similarly to Model.attr. |
solution |
Retrieves a variable's optimal value after the model has been solved. |
|
vtype |
VType
|
|
Source code in pyoframe/_core.py
attr: Container
Allows reading and writing variable attributes similarly to Model.attr.
solution
Retrieves a variable's optimal value after the model has been solved.
Return type is a DataFrame if the variable has dimensions, otherwise it is a single value. Binary and integer variables are returned as integers.
Examples:
>>> m = pf.Model()
>>> m.var_continuous = pf.Variable({"dim1": [1, 2, 3]}, lb=5, ub=5)
>>> m.var_integer = pf.Variable(
... {"dim1": [1, 2, 3]}, lb=4.5, ub=5.5, vtype=pf.VType.INTEGER
... )
>>> m.var_dimensionless = pf.Variable(
... lb=4.5, ub=5.5, vtype=pf.VType.INTEGER
... )
>>> m.var_continuous.solution
Traceback (most recent call last):
...
RuntimeError: Failed to retrieve solution for variable. Are you sure the model has been solved?
>>> m.optimize()
>>> m.var_continuous.solution
shape: (3, 2)
┌──────┬──────────┐
│ dim1 ┆ solution │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════════╡
│ 1 ┆ 5.0 │
│ 2 ┆ 5.0 │
│ 3 ┆ 5.0 │
└──────┴──────────┘
>>> m.var_integer.solution
shape: (3, 2)
┌──────┬──────────┐
│ dim1 ┆ solution │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞══════╪══════════╡
│ 1 ┆ 5 │
│ 2 ┆ 5 │
│ 3 ┆ 5 │
└──────┴──────────┘
>>> m.var_dimensionless.solution
5
vtype: VType = VType(vtype)
next(dim: str, wrap_around: bool = False) -> Expression
Creates an expression where the variable at each label is the next variable in the specified dimension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dim
|
str
|
The dimension over which to shift the variable. |
required |
wrap_around
|
bool
|
If |
False
|
Examples:
>>> import pandas as pd
>>> time_dim = pd.DataFrame({"time": ["00:00", "06:00", "12:00", "18:00"]})
>>> space_dim = pd.DataFrame({"city": ["Toronto", "Berlin"]})
>>> m = pf.Model()
>>> m.bat_charge = pf.Variable(time_dim, space_dim)
>>> m.bat_flow = pf.Variable(time_dim, space_dim)
>>> # Fails because the dimensions are not the same
>>> m.bat_charge + m.bat_flow == m.bat_charge.next("time")
Traceback (most recent call last):
...
pyoframe._constants.PyoframeError: Cannot subtract the two expressions below because expression 1 has extra labels.
Expression 1: (bat_charge + bat_flow)
Expression 2: bat_charge.next(…)
Extra labels in expression 1:
┌───────┬─────────┐
│ time ┆ city │
╞═══════╪═════════╡
│ 18:00 ┆ Toronto │
│ 18:00 ┆ Berlin │
└───────┴─────────┘
Use .drop_extras() or .keep_extras() to indicate how the extra labels should be handled. Learn more at
https://bravos-power.github.io/pyoframe/latest/learn/concepts/addition
>>> (m.bat_charge + m.bat_flow).drop_extras() == m.bat_charge.next("time")
<Constraint 'unnamed' (linear) height=6 terms=18>
┌───────┬─────────┬────────────────────────────────────────────────────────────────────────────────┐
│ time ┆ city ┆ constraint │
│ (3) ┆ (2) ┆ │
╞═══════╪═════════╪════════════════════════════════════════════════════════════════════════════════╡
│ 00:00 ┆ Toronto ┆ bat_charge[00:00,Toronto] + bat_flow[00:00,Toronto] │
│ ┆ ┆ - bat_charge[06:00,Toronto] = 0 │
│ 00:00 ┆ Berlin ┆ bat_charge[00:00,Berlin] + bat_flow[00:00,Berlin] - bat_charge[06:00,Berlin] │
│ ┆ ┆ = 0 │
│ 06:00 ┆ Toronto ┆ bat_charge[06:00,Toronto] + bat_flow[06:00,Toronto] │
│ ┆ ┆ - bat_charge[12:00,Toronto] = 0 │
│ 06:00 ┆ Berlin ┆ bat_charge[06:00,Berlin] + bat_flow[06:00,Berlin] - bat_charge[12:00,Berlin] │
│ ┆ ┆ = 0 │
│ 12:00 ┆ Toronto ┆ bat_charge[12:00,Toronto] + bat_flow[12:00,Toronto] │
│ ┆ ┆ - bat_charge[18:00,Toronto] = 0 │
│ 12:00 ┆ Berlin ┆ bat_charge[12:00,Berlin] + bat_flow[12:00,Berlin] - bat_charge[18:00,Berlin] │
│ ┆ ┆ = 0 │
└───────┴─────────┴────────────────────────────────────────────────────────────────────────────────┘
>>> (m.bat_charge + m.bat_flow) == m.bat_charge.next(
... "time", wrap_around=True
... )
<Constraint 'unnamed' (linear) height=8 terms=24>
┌───────┬─────────┬────────────────────────────────────────────────────────────────────────────────┐
│ time ┆ city ┆ constraint │
│ (4) ┆ (2) ┆ │
╞═══════╪═════════╪════════════════════════════════════════════════════════════════════════════════╡
│ 00:00 ┆ Toronto ┆ bat_charge[00:00,Toronto] + bat_flow[00:00,Toronto] │
│ ┆ ┆ - bat_charge[06:00,Toronto] = 0 │
│ 00:00 ┆ Berlin ┆ bat_charge[00:00,Berlin] + bat_flow[00:00,Berlin] - bat_charge[06:00,Berlin] │
│ ┆ ┆ = 0 │
│ 06:00 ┆ Toronto ┆ bat_charge[06:00,Toronto] + bat_flow[06:00,Toronto] │
│ ┆ ┆ - bat_charge[12:00,Toronto] = 0 │
│ 06:00 ┆ Berlin ┆ bat_charge[06:00,Berlin] + bat_flow[06:00,Berlin] - bat_charge[12:00,Berlin] │
│ ┆ ┆ = 0 │
│ 12:00 ┆ Toronto ┆ bat_charge[12:00,Toronto] + bat_flow[12:00,Toronto] │
│ ┆ ┆ - bat_charge[18:00,Toronto] = 0 │
│ 12:00 ┆ Berlin ┆ bat_charge[12:00,Berlin] + bat_flow[12:00,Berlin] - bat_charge[18:00,Berlin] │
│ ┆ ┆ = 0 │
│ 18:00 ┆ Toronto ┆ bat_charge[18:00,Toronto] + bat_flow[18:00,Toronto] │
│ ┆ ┆ - bat_charge[00:00,Toronto] = 0 │
│ 18:00 ┆ Berlin ┆ bat_charge[18:00,Berlin] + bat_flow[18:00,Berlin] - bat_charge[00:00,Berlin] │
│ ┆ ┆ = 0 │
└───────┴─────────┴────────────────────────────────────────────────────────────────────────────────┘
Source code in pyoframe/_core.py
2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 | |
to_expr() -> Expression
Converts the Variable to an Expression.
Comments