Page 1 of 1
Subset of multiple subsets
Posted: Tue Aug 16, 2022 1:39 pm
by mkbonde
Dear GAMS forum
I regularly run into an issue where we have a set structure in which a set is a subset of two different sets which are both subsets of the same super set, for example:
Code: Select all
sets
abc /a, b, c/
ab[abc] /a, b/
a[abc] /a/
ac[abc] /a, c/
c[abc] /c/
;
The problem is when I define a variable over ab, in this case, but want to use the sub-sub-set:
Code: Select all
parameter foo[ab], bar[ac];
foo[a] = 1;
**** $171
**** 171 Domain violation for set
Note that defining a[ab] instead of a[abc] does not help, as I instead get an error here:
We currently get around this issue by defining variables on the superset (abc), but this makes the definitions less clear and gives us extra dollar-conditions.
Is there a way of turning off domain checking errors of the above kind? While still checking for errors like the following:
Code: Select all
foo[c] = 1;
**** $171
**** 171 Domain violation for set
where an element is used, which is not contained in the set.
Best regards,
Martin
Re: Subset of multiple subsets
Posted: Wed Aug 17, 2022 11:55 am
by Fred
Hi Martin,
While there are ways to turn off domain checking (e.g. via
$onUni), this won't help here because the following domain violation would then also be accepted.
Since all subsets are based on the same superset, you could use the symbol's domain explicitly but then take only a subset of it:
Code: Select all
parameter foo[ab], bar[ac];
foo[ab(a)] = 1;
bar[ac(a)] = 1;
If you consistently use the symbol's domain
will not throw an error but since ab(c) is empty, no assignment will be made.
This is not as compact as your notation but in the end it should give you the records you want (foo('a')=1 and bar('a')=1).
I hope this helps!
Fred
Re: Subset of multiple subsets
Posted: Wed Aug 17, 2022 3:03 pm
by dirkse
Martin,
The situation you describe has appeared in practice a few times, but fortunately not so often. I usually take the approach of declaring subsets, parameters and variables over the larger set, like this:
Code: Select all
sets
abc /a, b, c/
ab[abc] /a, b/
a[abc] /a/
ac[abc] /a, c/
c[abc] /c/
;
parameter
foo[abc] 'really ab'
bar[abc] 'really ac'
;
foo[a] = 1;
bar[a] = 1;
* but this now becomes acceptable, and you do not want it:
foo[c] = 7;
The problem is that the domain checking is incomplete, so the GAMS compilation-time checks are not as extensive as they could be.
You mentioned that this approach leads to extra dollar-conditions. What dollar-conditions do you put in?
-Steve
Re: Subset of multiple subsets
Posted: Wed Aug 17, 2022 3:21 pm
by bussieck
Martin,
This won't work with referential integrity/domain checking. The domains build a tree:
and you either put a under ab or ac but not under both. You can avoid GAMS domain checking by doing controlled a $on/offUni (see
https://www.gams.com/40/docs/UG_DollarC ... ARonoffuni) but I am not recommending this:
Code: Select all
sets
abc /a, b, c/
ab[abc] /a, b/
a[abc] /a/
ac[abc] /a, c/
c[abc] /c/
;
parameter foo[ab], bar[ac];
$onUni
foo[a] = 1;
bar[c] = 1;
$offUni
display foo, bar;
I usually don't use subsets as domain sets (in such a case). I understand that we loose some clarity by defining everything under abc, but why do you need extra dollar constraints?
-Michael
Re: Subset of multiple subsets
Posted: Wed Aug 17, 2022 3:56 pm
by mkbonde
Thank you for the replies and explanation.
@Fred I did not know about the
superset(subset) syntax (only the other way around) - that could be very useful!
You are all right that there are no extra dollar conditions if I just define everything over the superset (except those stemming from interaction with our own macro processing extensions).
When I choose to define my variable over a subset though, I get extra dollar conditions as in this example:
Code: Select all
sets
abc /a, b, c/
ab[abc] /a, b/
a[abc] /a/
;
variable foo[ab];
equation E_foo;
E_foo[ab]$(a[ab]).. foo[ab] =E= 1;
compared with
which results in a domain error here.
I suppose the "one parent only" is an integral part of the domain checking process, but wanted to check if there was a way of explicitly assigning multiple "parents" to one set.