Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to get an objective function? I want to maximize/minimize stuff. #5

Open
gruijter opened this issue Jan 4, 2024 · 8 comments
Open

Comments

@gruijter
Copy link

gruijter commented Jan 4, 2024

I am trying to model a home battery solution, where I want to optimize profit from buying/selling energy.
The result should charge the battery on cheap hours, and sell it on expensive hours, given the constraints.

The battery has a minimum and maximum capacity (SOC: 0 ... 5 kWh)
The charging / discharging speed has a minimum and a maximum (load: -2 ... 2 kW)
The energy prices vary per hour, and are known 24 hours in advance. (price[1] .... price[24])

What I am able to do is model the SOC and LOAD constraints. And I can model the profit.hour[n] = load.hour[n] x price.hour[n].
The total profit (objective function) would be profit.hour[1] + profit.hour[2] + ..... + profit.hour[24]

But now the big issue: How do I optimize to get maximum profit? (or alternatively minimize for cost)? I would like to see for each hour what the optimum load should be.

@gruijter
Copy link
Author

Bump. Anyone here that can provide feedback? Thx!

@trusktr
Copy link
Member

trusktr commented Jan 25, 2024

Hello! Sorry for the lag!

Interesting problem. Its a matter of expressing everything you need in Variables, and running it multiple times for the for each set of conditions. Have you tried a working example?

Here's live CodePen showing how to update input values and get new results: https://codepen.io/trusktr/pen/abMLVxa?editors=1010

@gruijter
Copy link
Author

Thx for replying!
I'm lost though, but maybe kiwi is not what I need. I'm looking for a linear solver. A linear solver would normally have an objective function for which the solution is maximized or minimized under the given contraints.

Now when you say 'running it multiple times for the for each set of conditions', what do you mean by each set of conditions? The contraints are fixed, and the time series data (price per hour for the coming 24 hours) is also fixed. The input power and power duration per hour is what I'm looking for. Over a 24 hour period there are billions*billions of combinations that could be tried. Such a 'brute force' is exactly what I want to avoid (and is actually not computable on normal PC's).

@trusktr
Copy link
Member

trusktr commented Jan 25, 2024

I'm not very familiar with this space, as I'm using Kiwi via lume/autolayout as a high level layout system for UI. But I found this as a starting point:

https://developers.google.com/optimization/lp/lp_example

@trusktr
Copy link
Member

trusktr commented Jan 25, 2024

I looked over the docs and code to get more familiar with kiwi, and found that this,

// Create edit variables
var left = new kiwi.Variable()
var width = new kiwi.Variable()
solver.addEditVariable(left, kiwi.Strength.strong)
solver.addEditVariable(width, kiwi.Strength.strong)
solver.suggestValue(left, 100)
solver.suggestValue(width, 400)

// Create and add a constraint
var right = new kiwi.Variable()
solver.addConstraint(new kiwi.Constraint(new kiwi.Expression([-1, right], left, width), kiwi.Operator.Eq))

// Solve the constraints
solver.updateVariables()

is basically the constraint -1*right + left + width = 0 and it solves for right given values for left and width.

Based on that, we should be able to model an example like the one in the previous linked LP example, and then start to think about what your equations are to try that out, if possible (not familiar with your problem or if it is even doable).

@gruijter
Copy link
Author

Mmh. Thx for that insight! But dtill not easy for me to grasp the concept, since there will be multiple constraints, and I dont see how you can maximize or minimize a variable.

@trusktr
Copy link
Member

trusktr commented Jan 26, 2024

I'm trying to understand as well (I forked this repo to get https://GitHub.com/Lume/autolayout updated to fit in well with Lume TypeScript build, native ES Modules, etc, in order to finally implement the <lume-autolayout> element for UI layouts, but I never knew what was going on under the hood with Kiwi).

Kiwi is based on Cassowary, and I found this nice doc:

https://cassowary.readthedocs.io/_/downloads/en/latest/pdf/

It describes that Cassowary is for solving linear programs and finding max/min of objective functions at the very top, but then the rest of the document no longer mentions objective function.

The doc, however, does a good job explaining how to use the Cassowary library, which is very similar to Kiwi (API shape differs a little bit, but the abilities are the same). It seems that, among those examples, is an objective function being minimized or maximized, and it seems we just have to learn to recognize what that objective function is from that example.

If that's the case that it is right there in front of our eyes in that doc (maybe not explicitly pointed out, let's find out), then I'd like to clearly document that here in Kiwi. It would be nice to also make a working example of that quadrilateral demo with Kiwi.

Does that doc help you?

@chrisvander
Copy link

I believe what you would do is define a weak constraint where you have an objective function equal 0. The weak constraint will be violated, and the algorithm should incrementally allow higher. I'm going to attempt this myself, and see if that (or a better constraint) allows for effective minimization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants