How to create a three depending percentage domains sums up to hundred

I’m having difficulty creating domains for something like this

A between 40% - 60%
B between 40% - 60%
C between 0% - 10%


Anyone having an idea on this?

There are three bounded variables (A, B, C) and one constraint ( A+B+C=100%) in your problem , so that leaves you with 2 degrees of freedom.

One way is to use “relative” inputs and remap them to the 0-100%, (basically removing the last constraint) but then you have to check afterwards if your 40-60% etc. conditions are satisfied.

This solved my problem mostly, Thanks a lot! But as you mentioned (have to check afterward if your 40-60% etc) in some highlighted values go beyond their ranges. Is there any way to automatically adjust the slider domains as they wanted to be in the range?

Heh, I knew that you wouldn’t be satisfied with that aspect of it :smile:

Well… I do have a WIP side project trying to make “responsive” sliders in arbitrary overconstrained situations exactly like this, involving some highly non-standard ways of using the Kangaroo solver.
Looks something like this in its current state, although much too fragile and resource-intensive at the moment:

But in your case it should be much simpler to hack together a python script that does it, since it only involves addition… let me see what I can do- (7.5 KB)

from Grasshopper.Kernel.Special import GH_NumberSlider

inputs = ghenv.Component.Params.Input
sliders = [inp.Sources[0] for inp in inputs]

values = [a, b, c]
total = sum(values)
new_values = [v / total for v in values]

for val, slider in zip(new_values , sliders):
1 Like

In this case, It doesn’t need sliders to be responsive like this. um… because I’m going to use the Galapagos or Opossum like solver to optimum values for sliders to check a model that I’m doing for my thesis (so I think otherwise it will be run in loops and will not respond or crash). It is better sliders are to be locked where they are going to exceed the ranges then if any other factor changes, it can adapt the next available range again

Oh I see - in that case you could maybe try this: (10.3 KB)

The Python component is just a bunch of ‘guard’ clauses, which cause errors in the component and invalidate the entire solution if the conditions are not met.
(The same thing can be done with native Expression and Sift components but I was lazy :slight_smile: )

a, b, c = abc
assert 0.4 < a < 0.6
assert 0.4 < b < 0.6
assert 0.0 < c < 0.1

From past experience, Galapagos / Oppossum should automatically avoid these parts of the solution space.

Edit: actually, since you’re already using a solver, couldn’t you directly add the penalty terms abs(a+b+c-1.00), etc. to minimize?

1 Like

Wow…That was exactly what I wanted. Thanks, You made my day! I think the model is going to disappear where no data is collected :laughing:, but it doesn’t matter if solver works.

[ Edit: actually, since you’re already using a solver, couldn’t you directly add the penalty terms abs(a+b+c-1.00), etc. to minimize?]
Yes but I’m using these percentages as inputs (built%, paved %, bare land%) and the create a model (urban) and run a thermal optimization using ladybug and use the solver to find the minimum/maximum values for the temperature change. I don’t know whether it’s possible to add penalty terms {like abs(a+b+c-1.00)} to opossum directly.

Hello @qythium

Sorry for bothering again, but I need your help again

I was using this slider guard you fixed for me, but this error shows up for some marginal values of the sliders. first i thought it wouldn’t be a problem but it gives me a error and simulation process stops. I’m stuck at the final simulation process of my thesis because of this error.

this is what’s inside of it

a, b, c = abc
assert 0.4 < a < 0.6
assert 0.4 < b < 0.6
assert 0.0 < c < 0.1

slider guard to sum up (4.7 KB)

Could you please add some code to prevent this? I’m very new to python, i tried adding some conditionals like above, but they don’t work as expected.

If output numbers exceed above conditions, it shows the error. What I want is to freeze it and still give the last output where errors occur and after values satisfied the number from by sliders again, then back to normal operations.



The assert statement does not change any outputs at all, it’s only purpose is to test for conditions and throw an exception otherwise. To make some sort of ‘clamping’ function you can try this:

a, b, c = abc
if "_abc" not in globals(): 
    # starting case (must be valid)
    assert 0.4 < a < 0.6
    assert 0.4 < b < 0.6
    assert 0.0 < c < 0.1
    _abc = list(abc)

if (0.4 < a < 0.6) and (0.4 < b < 0.6) and (0.0 < c < 0.1):
    _abc = list(abc) # store valid inputs
    a, b, c = _abc # revert to last working value

I don’t know how this will affect your solver, it may get confused after wandering into one of these infeasible regions since the outputs “plateau” off.

Alternatively (and I think this is the normal approach), just add a penalty term to the overall objective

1 Like

Thanks a lot!

This looks working fine. However, I should attach this to the simulation and try with the opossum solver to see how it affect.

By the way I don’t understand this ‘normal approach’. I get this simulation component means i should set my simulation there ( with the new python code at start), but what is this ‘k’ and how you decide it’s value? Also, doesn’t adding this ‘R’ takes the optimized value far away from what it should be?