This repository has been archived by the owner on Jan 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nonlinear constrained optimization chapter added (#6)
* Create Nonlinear_constrained_optimization.md * added chapter * Update Nonlinear_constrained_optimization.md * Update Nonlinear_constrained_optimization.md * Added bounds properly * Added question * Added page * renamed file * Update nonlinear_constrained_optimization_example.ipynb * Update nonlinear_constrained_optimization_example.ipynb * update * Update nonlinear_constrained_optimization_example.ipynb * Update nonlinear_constrained_optimization_example.ipynb * Test with html directly on page * add iframe * Update nonlinear_constrained_optimization_example.ipynb * added units * Finalized chapter * Update block.html
- Loading branch information
1 parent
0cd0e7f
commit c507941
Showing
7 changed files
with
1,102 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Find the optimum solution yourself!</title> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js"></script> | ||
<style> | ||
.slider { | ||
display: block; | ||
margin-bottom: 10px; | ||
width: 100%; | ||
} | ||
.slider-container { | ||
display: grid; | ||
grid-template-columns: repeat(3, 1fr); | ||
grid-gap: 10px; | ||
width: 100%; | ||
} | ||
.output { | ||
margin-top: 20px; | ||
padding: 10px; | ||
border: 1px solid #ccc; | ||
border-radius: 5px; | ||
background-color: #f9f9f9; | ||
} | ||
.output p { | ||
margin: 5px 0; | ||
} | ||
.output .emoji { | ||
font-size: 20px; | ||
margin-right: 5px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="sliderContainer" class="slider-container"></div> | ||
<div id="outputContainer" class="output"></div> | ||
|
||
<script> | ||
function func(x) { | ||
var vol = x[0] * x[1] * x[2]; | ||
return vol; | ||
} | ||
|
||
function nonlinconfun(x) { | ||
var c1 = 0.8 - x[0] * x[1]; | ||
var c2 = 0.8 - x[0] * x[2]; | ||
var c3 = 0.8 - x[1] * x[2]; | ||
var c4 = 3000 - 2500 * x[0] * x[1] * x[2]; | ||
return [c1, c2, c3, c4]; | ||
} | ||
|
||
function eval() { | ||
var x_1 = parseFloat(document.getElementById("x_1").value); | ||
var x_2 = parseFloat(document.getElementById("x_2").value); | ||
var x_3 = parseFloat(document.getElementById("x_3").value); | ||
var x = [x_1, x_2, x_3]; | ||
|
||
var output = document.getElementById("outputContainer"); | ||
output.innerHTML = ""; | ||
|
||
var vol = func(x); | ||
output.innerHTML += "<p><strong><span style='font-size: 24px;'>Objective function: " + vol.toFixed(3) + " m<sup>3</sup></span></strong></p>"; | ||
|
||
var constraints = nonlinconfun(x); | ||
for (var i = 0; i < constraints.length; i++) { | ||
if (i === 3) { | ||
if (constraints[i] < 0) { | ||
output.innerHTML += "<p><span class='emoji'>👍</span> Constraint function " + (i + 1) + ": " + constraints[i].toFixed(0) + " kg</p>"; | ||
} else { | ||
output.innerHTML += "<p><span class='emoji'>👎</span> Constraint function " + (i + 1) + ": " + constraints[i].toFixed(0) + " kg</p>"; | ||
} | ||
} else { | ||
if (constraints[i] < 0) { | ||
output.innerHTML += "<p><span class='emoji'>👍</span> Constraint function " + (i + 1) + ": " + constraints[i].toFixed(2) + " m<sup>2</sup></p>"; | ||
} else { | ||
output.innerHTML += "<p><span class='emoji'>👎</span> Constraint function " + (i + 1) + ": " + constraints[i].toFixed(2) + " m<sup>2</sup></p>"; | ||
} | ||
} | ||
} | ||
} | ||
var sliderContainer = document.getElementById("sliderContainer"); | ||
var sliders = [ | ||
{ id: "x_1", min: 0, max: 5, value: 2, step: 0.01, description: "x<sub>1</sub>" }, | ||
{ id: "x_2", min: 0, max: 5, value: 2, step: 0.01, description: "x<sub>2</sub>" }, | ||
{ id: "x_3", min: 0, max: 5, value: 2, step: 0.01, description: "x<sub>3</sub>" } | ||
]; | ||
|
||
sliders.forEach(function(slider) { | ||
var input = document.createElement("input"); | ||
input.type = "range"; | ||
input.min = slider.min; | ||
input.max = slider.max; | ||
input.value = slider.value; | ||
input.step = slider.step; | ||
input.id = slider.id; | ||
input.oninput = function() { | ||
document.getElementById(slider.id + "_value").textContent = this.value + " m"; | ||
eval(); | ||
}; | ||
input.classList.add("slider"); | ||
|
||
var label = document.createElement("label"); | ||
label.innerHTML = slider.description; | ||
label.setAttribute("for", slider.id); | ||
label.style.textAlign = "right"; | ||
|
||
var valueDisplay = document.createElement("span"); // Create a span element for value display | ||
valueDisplay.id = slider.id + "_value"; // Set the id for value display | ||
valueDisplay.textContent = slider.value + " m"; // Set the initial value | ||
|
||
sliderContainer.appendChild(label); | ||
sliderContainer.appendChild(input); | ||
sliderContainer.appendChild(valueDisplay); // Append the value display element | ||
}); | ||
|
||
var outputContainer = document.getElementById("outputContainer"); | ||
var button = document.createElement("button"); | ||
button.innerHTML = "Evaluate"; | ||
button.onclick = eval; | ||
outputContainer.appendChild(button); | ||
|
||
// Call func with initial values | ||
eval(); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Nonlinear constrained optimization | ||
|
||
In this chapter, we'll cover how to apply `scipy.optimize.minimize` to nonlinear constrained optimization problems. As a reminder, nonlinear constrained optimization considers: | ||
|
||
```{math} | ||
:label: nonlinear_constrained_optimization | ||
\eqalign{ | ||
& \mathop {\min }\limits_x f\left( x \right) \cr | ||
& {\text{such that}} & {{g}_j}\left( x \right) \le 0 & j = 1,m \cr | ||
& & {h_k}\left( x \right) = 0 & k = 1,p \cr | ||
& & x_i^l \le {x_i} \le x_i^u & i = 1,n \cr} | ||
``` | ||
with: | ||
- $f\left(x\right)$, the linear or nonlinear objective function. | ||
- $x$, the $n$ design variables | ||
- $g_j\left(x\right)$, the $m$ linear or nonlinear inequality constraints | ||
- $h_k\left(x\right)$, the $p$ linear or nonlinear inequality constraints | ||
- $x_k^l$ and $x_k^u$, the $n$ low er and upper bounds of the design variable | ||
|
||
## Method | ||
For linear programs, we can use the function `scipy.optimize.minimize` again. The documentation of this function is available here: | ||
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html. In this course we'll cover only the relevant parts. | ||
|
||
For unconstrained optimization we need to run at least `scipy.optimize.minimize(fun, x0, bounds, constraints, ...)` with: | ||
- `fun`, the function representing the objective function $f\left(x\right)$ to be minimized. `fun` is a callable. The `scipy.optimize.minimize` function takes care of defining and inputting our design variable $x$. | ||
- `x0`, the initial guess for our design variable $x$. It needs to be a `ndarray` with length $n$ | ||
- `Bounds`: A sequence of $i$ `(min, max)` pairs for each element in $x$, defining the minimum $x_i^l$ and maximum values $x_i^u$ of that decision variable. `None` is used to specify no bound. | ||
- `constraints`, a single or a list of constraint objective either being: | ||
- `scipy.optimize.LinearConstraint` | ||
- `scipy.optimize.NonlinearConstraint` | ||
|
||
:::{card} Test yourself | ||
<iframe src="https://tudelft.h5p.com/content/1292254710251972777/embed" aria-label="Need for x0" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script> | ||
::: | ||
|
||
As you can see, the constraints are stored in an object `scipy.optimize.LinearConstraint` and/or `scipy.optimize.NonlinearConstraint`. These function have the following input, for `scipy.optimize.NonlinearConstraint(fun, lb, ub, ...)`: | ||
- `fun`, the function representing the constraint function $g\left(x\right)$ or $h\left(x\right)$ to be minimized. Again, `fun` is a callable. The `scipy.optimize.minimize` function takes care of defining and inputting our design variable $x$. | ||
- `lb` and `ub`, two arrays containing the lower- and upper bounds for each of the constraint functions $g\left(x\right)$. This lower bound can be `-np.inf` or `np.inf` to represent one-sides constraints. If the lower- and upper bound are set to the same value, an equality function is modelled. | ||
|
||
For linear constraints, the constraint function is stored in a matrix again: `scipy.optimize.NonlinearConstraint(A, lb, ub, ...)`: | ||
- `A`, a twodimensional numpy array with the $n$ coefficient of the $m$ linear inequality constraints matrix ${A_{ub}}$. | ||
- `lb` and `ub` as for `scipy.optimize.NonlinearConstraint` | ||
|
||
Please note that unlike with linear constraints optimization, the right-hand-side of the constraints are not stored in an upper bound vector, but defined with `lb` and `ub`. | ||
|
||
|
||
:::{card} Test yourself | ||
<iframe src="https://tudelft.h5p.com/content/1292253866845965907/embed" aria-label="Nonlinear constrained optimization method" width="1088" height="637" frameborder="0" allowfullscreen="allowfullscreen" allow="autoplay *; geolocation *; microphone *; camera *; midi *; encrypted-media *"></iframe><script src="https://tudelft.h5p.com/js/h5p-resizer.js" charset="UTF-8"></script> | ||
::: | ||
|
||
The function `scipy.optimize.linprog` outputs an object `scipy.optimize.OptimizeResult` similar as `scipy.optimize.minimize` explained for [unconstrained optimization](method_unconstrained). | ||
|
||
## Questions, discussions and comments | ||
<script src="https://utteranc.es/client.js" | ||
repo="TeachBooks/engineering-systems-optimization" | ||
issue-term="title" | ||
theme="github-light" | ||
crossorigin="anonymous" | ||
async> | ||
</script> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.