API Reference¶
Bipartite Matching¶
The following mods can be imported from gurobi_optimods.bipartite_matching
:
- maximum_bipartite_matching(graph, nodes1, nodes2, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve a maximum cardinality bipartite matching problem on the given graph.
- Parameters:
- graph
spmatrix
orGraph
orDataFrame
A graph, specified either as a scipy.sparse adjacency matrix, networkx graph, or pandas dataframe.
- nodes1
ndarray
orstr
Nodes in the first bipartite set. If
graph
is a scipy sparse matrix,nodes1
must be a numpy array. Ifgraph
is a pandas dataframe,nodes1
must be a column name. Ifgraph
is a networkx graph,nodes1
must be a list.- nodes2
ndarray
orstr
Nodes in the second bipartite set. If
graph
is a scipy sparse matrix,nodes2
must be a numpy array. Ifgraph
is a pandas dataframe,nodes2
must be a column name. Ifgraph
is a networkx graph,nodes2
must be a list.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- graph
- Returns:
Line Optimization in Public Transportation Networks¶
The following mods can be imported from gurobi_optimods.line_optimization
:
- line_optimization(node_data, edge_data, line_data, linepath_data, demand_data, frequencies, shortest_paths=True, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the line planning problem.
- Parameters:
- node_data
DataFrame
DataFrame with information on the nodes/stations. The frame must include “source”.
- edge_data
DataFrame
DataFrame with edges / connections between stations and associated attributes. The frame must include “source”, “target”, and “time”
- demand_data
DataFrame
DataFrame with node/station demand information. It must include “source”, “target”, and “demand”. The demand value must be non-negative.
- line_data
DataFrame
DataFrame with general line information. It must include “linename”, “capacity”, “fix_cost”, and “operating_cost”.
- linepath_data
DataFrame
DataFrame with information on the line routes/paths. It must include “linename”, “edge_source”, and “edge_target”.
- frequency: List
List with possible frequencies: How often the line can be operated in the considered time horizon.
- shortest_pathsbool
Parameter to choose the strategy. Default value is true and strategy 1 is used, i.e., passengers travel along shortest paths. Set to False if all possible paths are allowed. In that case, a multi-objective approach is used to first minimize line operating cost and then minimize passengers travel time.
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- node_data
- Returns:
tuple
Cost of the optimal line concept (line frequency)
list of line-frequency tuples (optimal line concept)
Maximum Flow¶
The following mods can be imported from gurobi_optimods.max_flow
:
- max_flow(graph, source, sink, **kwargs)¶
Solve the maximum flow problem for a given graph.
- Parameters:
- graph
spmatrix
orGraph
orDataFrame
A graph, specified either as a scipy.sparse adjacency matrix, networkx graph, or pandas dataframe. These contain the capacity for each edge. In the networkx (pandas dataframe) case, we expect the edge attribute (column name)
capacity
. Please see the example in the documentation.- source
int
orstr
The source (or origin) node for the maximum flow.
- sink
int
orstr
The sink (or destination) node for the maximum flow.
- graph
- Returns:
Metro Map: Computing an Octilinear Graph Representation¶
The following mods can be imported from gurobi_optimods.metromap
:
- metromap(graph, linepath_data=None, include_planarity=True, penalty_edge_directions=1, penalty_line_bends=1, penalty_distance=1, improve_lp=True, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
- Compute a metromap drawing, i.e., an octilinear network representation
considering the origin geographical data if available given as geographic position of the nodes
- Parameters:
- graph
Graph
networkx graph with node attribute ‘pos’ being a tuple of x- and y-coordinate
- linepath_data
DataFrame
DataFrame with information on the line routes/paths. It must include “linename”, “edge_source”, and “edge_target”. This data frame could also be empty
- include_planaritybool
parameter to turn off the consideration of planarity constraints
- penalty_edge_directions
float
weight for original direction part in the objective, default is 1
- penalty_line_bends
float
weight for line-bend part in the objective, default is 1
- penalty_distance
float
weight for distance part in the objective, default is 1
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- graph
- Returns:
tuple
networkx graph with node property pos_oct representing the x and y coordinates of the octilinear representation
Python dict for direction for each edge (needed for plotting)
Minimum Cost Flow¶
The following mods can be imported from gurobi_optimods.min_cost_flow
:
- min_cost_flow_networkx(G, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the minimum cost flow problem for a given graph.
- Parameters:
- G
DiGraph
Graph with edge attributes
capacity
andcost
, as well as node attributesdemand
.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- G
- Returns:
tuple
Cost of the minimum cost flow (float), a subgraph of the original graph specifying the flow
- min_cost_flow_pandas(arc_data, demand_data, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the minimum cost flow problem for a given graph.
The inputs adhere to the following structure:
arc_data = pd.DataFrame( [ {"from": 0, "to": 1, "capacity": 16, "cost": 0}, {"from": 1, "to": 2, "capacity": 10, "cost": 0}, ] ).set_index(["from", "to"]) demand_data = pd.DataFrame( [{"node": 0, "demand": -1}, {"node": 2, "demand": 1}] ).set_index("node")
- Parameters:
- arc_data
DataFrame
DataFrame with graph and respective attributes. These must include
"from"
,"to"
nodes used as index as well as"capacity"
, and"cost"
columns.- demand_data
DataFrame
DataFrame with node demand information. These must include indexed by
"node"
, and include the"demand"
column. This value can be positive (requesting flow) or negative (supplying flow).- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- arc_data
- Returns:
tuple
Cost of the minimum cost flow (float), dictionary indexed by edges with non-zero flow in the solution (Series)
- min_cost_flow_scipy(G, capacities, costs, demands, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the minimum cost flow problem for a given graph.
- Parameters:
- G
spmatrix
Adjacency matrix of the graph.
- capacities
spmatrix
Matrix containing capacities for each edge.
- costs
spmatrix
Matrix containing costs for each edge.
- demands
ndarray
Array containing the demand for each node.
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- G
- Returns:
tuple
Cost of the minimum cost flow (float), dictionary indexed by edges with non-zero flow in the solution (spmatrix)
Minimum Cut¶
The following mods can be imported from gurobi_optimods.min_cut
:
- class MinCutResult(cut_value, partition, cutset)¶
Solution to a Minimum-cut problem.
- Attributes:
- cut: float
Cut value of the minimum cut.
- partition: tuple with sets
Partition of size 2 with cut sets.
- cutset: set of tuple
Cutset with edges.
- min_cut(graph, source, sink, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the minimum cut problem for a given graph.
- Parameters:
- graph
spmatrix
orGraph
orDataFrame
A graph, specified either as a scipy.sparse adjacency matrix, networkx graph, or pandas dataframe. These contain the capacity for each edge. In the networkx (pandas dataframe) case, we expect the edge attribute (column name)
capacity
. Please see the example in the documentation.- source
int
orstr
The source (or origin) node for the cutset.
- sink
int
orstr
The sink (or destination) node for the cutset.
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- graph
- Returns:
- min_cut_result:
MinCutResult
A dataclass containing the cut value, and set of nodes and edges in the minimum cut.
- min_cut_result:
Maximum Weighted Independent Set/Clique¶
The following mods can be imported from gurobi_optimods.mwis
:
- class MWISResult(x, f)¶
Data class representing the maximum weighted independent set (clique) and its weight
- maximum_weighted_clique(graph, weights, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Find a set of fully connected vertices with maximum weighted sum.
- Parameters:
- graph
spmatrix
orGraph
orDataFrame
A graph, specified as a scipy.sparse upper triangular adjacency matrix with zero diagonals, a networkx graph, or a pandas dataframe. The pandas dataframe must include edge information in two columns named as
"node1"
and"node2"
.- weights
ndarray
ofDataFrame
Vertex weights. If
graph
is a scipy.sparse matrix or a networkx graph,weights
must be a numpy array. Ifgraph
is a pandas dataframe graph,weights
must be a dataframe too. The weights dataframe must include the weight information in a column named"weights"
and must be indexed by vertex number.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- graph
- Returns:
MWISResult
A data class representing the maximum weighted clique array and its weight.
- maximum_weighted_independent_set(graph, weights, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Find a set of mutually non-adjacent vertices with maximum weighted sum.
- Parameters:
- graph
spmatrix
orGraph
orDataFrame
A graph, specified as a scipy.sparse upper triangular adjacency matrix with zero diagonals, a networkx graph, or a pandas dataframe. The pandas dataframe must include edge information in two columns named as
"node1"
and"node2"
.- weights
ndarray
orDataFrame
Vertex weights. If
graph
is a scipy.sparse matrix or a networkx graph,weights
must be a numpy array. Ifgraph
is a pandas dataframe graph,weights
must be a dataframe too. The weights dataframe must include the weight information in a column named"weights"
and must be indexed by vertex number.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- graph
- Returns:
MWISResult
A data class representing the maximum weighted independent set array and its weight.
Optimal Power Flow¶
The following mods can be imported from gurobi_optimods.opf
:
- compute_violations(case, voltages, polar=False, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Constructs an OPF model from given case data and computes a violation dictionary out of given voltage values.
If a voltage solution is present, e.g., from an external computation, this function can be used to check whether the given voltage solution is indeed feasible for the AC optimization model. Usually, if the violations are not too big, one can use the voltage solution for further calculations.
Returns a violation dictionary following MATPOWER notation which holds all case data and additional violation fields. The additional fields are
violation["bus"][i]["Vmviol"]
for voltage magnitude violation at bus iviolation["bus"][i]["Pviol"]
for real injection violation at bus iviolation["bus"][i]["Qviol"]
for reactive injection violation at bus iviolation["branch"][i]["limitviol"]
for limit violation at branch i
The violation dictionary can be used to generate a violations figure with the
generate_opf_violations_figure
function- Parameters:
- case
dict
Dictionary holding case data
- voltages
dict
Dictionary holding bus input voltage data
- polar: bool, optional
If True, use polar formulation when checking violations, defaults to False
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- case
- Returns:
dict
Case dictionary following MATPOWER notation with additional violations fields
- read_case_matpower(file_path)¶
Read in a MATPOWER case file.
The file must contain a MATPOWER version 2 ‘mpc’ struct.
- solution_plot(case, coords, solution)¶
Reads the given case and returns a plotly figure object. Ideally the solution has been computed by the
solve_opf
function- Parameters:
- Returns:
plotly.graph_objects.Figure
A plotly figure object displaying the solution. The plot can be displaged by calling
figure.show()
.
- solve_opf(case, opftype='AC', branch_switching=False, min_active_branches=0.9, use_mip_start=False, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Constructs an OPF model from given data and solves it with Gurobi. Returns a result dictionary following MATPOWER notation. The additional and possibly altered fields are
result["success"]
1 if at least one feasible solution has been found, 0 otherwiseresult["et"]
time spent for optimizationresult["f"]
solution objective valueresult["bus"][i]["Vm"]
for voltage magnitude value at bus iresult["bus"][i]["Va"]
for voltage angle value at bus iresult["bus"][i]["mu"]
for shadow prices of balance constraints at bus i (only available for DC without branchswitching)result["gen"][i]["Pg"]
for real power injection at generator iresult["gen"][i]["Qg"]
for reactive power injection at generator iresult["branch"][i]["Pf"]
for real power injected into “from” end of branch at branch iresult["branch"][i]["Pt"]
for real power injected into “to” end of branch at branch iresult["branch"][i]["Qf"]
for reactive power injected into “from” end of branch at branch i (AC only)result["branch"][i]["Qt"]
for reactive power injected into “from” end of branch at branch i (AC only)result["branch"][i]["switching"]
states whether a branch i is turned on or off in the final solution
- Parameters:
- case
dict
Dictionary holding case data
- opftype
str
Desired OPF model type. One of
AC
,ACrelax
, orDC
- branch_switchingbool, optional
If set to True, enables branch switching.
- min_active_branches
float
, optional Defines the minimum number of branches that must be turned on when branch switching is active, i.e. the minimum number of turned on branches is equal to
numbranches * min_active_branches
. Has no effect ifbranchswitching
is set to False.- use_mip_startbool, optional
(Advanced) If set to True, try various MIP starts for branch switching models. Has no effect if
branchswitching
is set to False. For DC models, this setting is ignored, and the mip start is always used.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- case
- Returns:
dict
Case dictionary following MATPOWER notation with additional result fields
- violation_plot(case, coords, violations)¶
Reads the given case and returns a plotly figure object of provided violations. Ideally the violations have been computed by the
compute_violations
function- Parameters:
- Returns:
plotly.graph_objects.Figure
A plotly figure object highlighting violations in the solution. The plot can be displaged by calling
figure.show()
.
Mean-Variance Portfolio¶
The following mods can be imported from gurobi_optimods.portfolio
:
- class MeanVariancePortfolio(mu, cov_matrix=None, cov_factors=None)¶
Optimal mean-variance portfolio solver.
Instantiate an object of
MeanVariancePortfolio
for given covariance matrix and return vector. UseMeanVariancePortfolio.efficient_portfolio()
to solve for efficient portfolios with given parameters.- Parameters:
- mu1-d
ndarray
Vector of expected returns for each asset
- cov_matrix2-d
ndarray
Covariance matrix \(\Sigma\)
- cov_factors
tuple
ofndarray
Covariance factors that constitute \(\Sigma = B K B^T + diag(d)\).
cov_factors[0]
: (n, k) ndarray \(B\)cov_factors[1]
: (k, k) ndarray \(K\), SPDcov_factors[2]
: (n,) ndarray \(d\), nonnegative
- mu1-d
- Raises:
LinAlgError
If the matrix K is not positive definite
- efficient_portfolio(gamma, max_trades=None, max_positions=None, fees_buy=None, fees_sell=None, costs_buy=None, costs_sell=None, min_long=None, min_short=None, max_total_short=0.0, initial_holdings=None, rf_return=None, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Compute efficient portfolio for given parameters
- Parameters:
- gamma
float
>= 0 Risk aversion cofficient for balancing risk and return; the resulting objective functions is \(\mu^T x - 0.5 \gamma x^T \Sigma x\)
- max_trades
int
>= 0, optional Upper limit on the number of trades
- max_positions
int
>= 0, optional Upper limit on the number of open positions
- fees_buy
float
orndarray
>= 0, optional Fixed-charge fee for each buy transaction, relative to total portfolio value
- fees_sell
float
orndarray
>= 0, optional Fixed-charge fee for each sell transaction, relative to total portfolio value
- costs_buy
float
orndarray
>= 0, optional Variable transaction costs for each buy transaction, relative to trade value
- costs_sell
float
orndarray
>= 0, optional Variable transaction costs for each sell transaction, relative to trade value
- min_long
float
>= 0, optional Lower bound on the volume on a traded long position, relative to total portfolio value
- min_short
float
>= 0, optional Lower bound on the volume on a traded short position, relative to total portfolio value
- max_total_short
float
>= 0, optional Maximum total short positions, relative to total investment.
- initial_holdings1-d
ndarray
, optional Initial portfolio holdings (sum needs to be <= 1)
- rf_return
float
, optional Include a risk-free asset having return rate
rf_return
.- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- gamma
- Returns:
- mvp_result
PortfolioResult
A dataclass containing the efficient portfolio, along with auxiliary information:
mvp_result.x
: The portfolio vector \(x\)mvp_result.risk
: The estimated risk \(x^T \Sigma x\) of the portfoliomvp_result.return
: The estimated return \(\mu^T x\) of the portfoliomvp.x_rf
relative investment in the risk-free asset. Present only ifrf_return
was non-None on input
Some combinations of requested portfolio features may rule out all possible portfolios. In this corner case the value
None
is returned.
- mvp_result
Notes
Refer to Enforcing more portfolio features for a detailed discussion of all parameters.
- class PortfolioResult(x, ret, risk, x_rf=None)¶
Data class representing computed portfolios.
- Attributes:
Quadratic Unconstrained Binary Optimization (QUBO)¶
The following mods can be imported from gurobi_optimods.qubo
:
- class QuboResult(solution, objective_value)¶
Solution to a QUBO problem.
- solve_qubo(coeff_matrix, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve a quadratic unconstrained binary optimization (QUBO) problem, i.e., minimize quadratic function \(x'Qx\) defined by coefficient matrix \(Q\) over a binary decision variable vector \(x\)
- Parameters:
- coeff_matrix
spmatrix
Quadratic coefficient matrix
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- coeff_matrix
- Returns:
QuboResult
A dataclass containing a 0/1 solution array and its objective value
Regression¶
The following mods can be imported from gurobi_optimods.regression
:
- class LADRegression¶
Least absolute deviations (L1-norm) regressor
- fit(X_train, y_train, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Fit the model to training data.
- Parameters:
- X_train
ndarray
Training set feature values
- y_train
ndarray
Training set output values
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- X_train
- class SharpeRatioResult(x, sharpe_ratio, ret, risk)¶
Data class representing the portfolio that maximizes the Sharpe ratio.
- max_sharpe_ratio(cov_matrix, mu, rf_rate=0, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve the problem of finding a portfolio that maximizes the Sharpe ratio.
- Parameters:
- cov_matrix
ndarray
orDataFrame
2D positive-semidefinite variance-covariance matrix \(\Sigma\)
- mu
ndarray
orSeries
Expected return rates \(\mu\)
- rf_rate
float
>= 0, optional Non-negative risk-free rate of return (defaults to
0
)- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- cov_matrix
- Returns:
- result
SharpeRatioResult
A data class representing the portfolio that maximizes the Sharpe ratio:
result.x
: The relative portfolio allocations \(x\)result.sharpe_ratio
: The Sharpe ratio of the portfolioresult.ret
: The estimated return \(\mu^T x\) of the portfolioresult.risk
: The estimated risk \(x^T \Sigma x\) of the portfolio
- result
Workforce Scheduling¶
The following mods can be imported from gurobi_optimods.workforce
:
- solve_workforce_scheduling(availability, shift_requirements, worker_limits, preferences=None, rolling_limits=False, *, verbose=True, logfile=None, time_limit=None, solver_params=None)¶
Solve a workforce scheduling model.
- Parameters:
- availability
DataFrame
Dataframe with columns ‘Worker’ and ‘Shift’ defining all allowable worker-shift combinations. The ‘Preference’ column optionally assigns a preference value to the given combination.
- shift_requirements
DataFrame
Dataframe with columns ‘Shift’ and ‘Required’ specifying the number of staff required for every shift.
- worker_limits
DataFrame
Dataframe with columns ‘Worker’, ‘MinShifts’, and ‘MaxShifts’ specifying the maximum and minimum number of shifts each worker may be assigned in the schedule.
- preferences
str
, optional The name of a column in the availability dataframe containing preference values. If provided, the mod returns a schedule which maximises the sum of preference values of assigned shifts.
- rolling_limitsbool
Whether to enforce worker shift limits on a rolling window basis. If True, worker_limits must contain an additional ‘Window’ column specifying the rolling window for each worker.
- verbosebool, optional
verbose=False
suppresses all console output- logfile
str
, optional Write all mod output to the given file path
- time_limit
float
Solver time limit in seconds (default no limit)
- solver_params
dict
, optional Gurobi parameters to be passed to the solver
- availability
- Returns:
DataFrame
Shift assignments as a subset of the availability dataframe
- Raises:
ValueError
If a feasible set of shift assignments cannot be constructed from the input data