Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:21 pm
What do you want to happen if:
Code: Select all
WeightedAlternativesOf scope = All alternatives = [
Weighted weight = 3 condition = Ship
Weighted weight = 1 condition = Or [Ship Fighter]
]
My current suggestion would be this being illegal because of overlapping candidates. (If the counts of evaluated subconditions add up being higher than the count of scope, the implementation is able to spot a bad script and print and log an error message. Also )
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:21 pm
Code: Select all
WeightedNumberOf number = 1 [
weight = 3 condition = Ship
weight = 1 condition = Or [Ship Fighter]
]
with equal numbers of ships and fighters in the universe?
For WeightedNumberOf this would not be illegal. I would it expect it to be the same as:
Code: Select all
WeightedNumberOf number = 1 [
weight = 4 condition = Ship
weight = 1 condition = Fighter
]
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:21 pm
WeightedAlternativesOf evaluates to a set of matches from the chosen subcondition.
[...]
Probabilities for taking n random candidates directly from WeightedAlternativesOf will not be the same as WeightedNumberOf number = n; the candidates will all be from the chosen subcondition for WeightedAlternativesOf while they can be different for WeightedNumberOf.
I assume you mean that all the matches of WeightedAlternativesOf are guaranteed to be chosen so that there is (at least) one of the subconditions that all the returned matches match. So with
Code: Select all
WeightedAlternativesOf scope = All alternatives = [
Weighted weight = 3 condition = Ship
Weighted weight = 1 condition = Fighter
]
if you added a number = 3 parameter to the WeightedAlternativesOf example above, and there were 2 ships and 6 fighters in the universe, it would have a 50% chance of matching 2 ships and a 50% chance of matching 3 fighters?
Basically yes. But one could instead wrap WeightedAlternativesOf in a RandomNumberOf number = 3 for the same result.
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:21 pm
don't see how you can avoid matching all the subconditions if you want to weight the probabilities of picking between subconditions with how many candidates match those subconditions.
Well, it is possible. If you know you have 100 candidates, you can e.g. roll a 100 sided dice. If you roll a 1, you can take the first subcondition with a match and do not need to know anything about the other subconditions.
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:21 pm
Also note that WeightedNumberOf lends itself better to per-object weight (as given in my initial example).
Weighted random pick could probably be implemented as a new sorting mode for SortedNumberOf, where the value determined per-object is used as a weight for random selection instead of for donig actual sorting. It might be inefficient to calculate the value of the sort key for each object instead of each subcondition, but it could work.
in my example calculation is simple (just looking up structure) and the scope restricted (only combatants, not the whole universe); this is not different from evaluating an object dependent valueref in e.g. a condition; i also guess the invariance checking we have can be used to speed up calculation in case the sort key is not object dependent.
I think WeightedNumberOf cant take any meaningful shortcuts anyway having to evaluate all subconditions on all objects in scope, assigning a weight and picking, so the feature does not come at extra cost (if ).
edit; some more detail on sampling without replacement: Ok, i think the probabilities are fine if you do dependent picks, as the probabilities change each time you pick/remove a sample (especially on low populations). So depending on implementation picking multiple samples could be costly. If you do a naive single "random" sort based on weight and take the first N samples the probabilities get skewed. As example if you pick 2 samples out of A,B,C with probabilities pA=0.5, pB=0.3, pC=0.2 the dependent probability of p(B|A) is 0.6, not 0.3.
If you are ok with wrong probabilities we probably get an efficient pretty straightforward implementation. For a correct one I guess we either have to stick to integer weights or we would need some library.
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:43 pm
If working as intended, I think the results would be the same.
Ok, I misinterpreted how the *NumberOf work. If I get it right it considers all matches and non_matches and rolls independently of that and when looking in MATCHES only keeps results in the end which were already in matches. So if the outer condition does not match the inner condition, you will have a chance of choosing a outer-condition non_match in the *NumberOf even if there are candidates which both match the inner and the outer condition.
So in the case I gave it probably does not return any matches - only if the highest structure ships are also the lowest structure ships and the two rolls choose the same ship. So if you have a single ship there will be a guaranteed result; if you have two ships with different structure you get a match in 50% of the cases. Here it is again:
Code: Select all
And [
MaximumNumberOf number = 2 sortkey = LocalCandidate.Structure condition = [[YOUR_SHIP]]
MinimumNumberOf number = 1 sortkey = LocalCandidate.Structure condition = [[YOUR_SHIP]]
]
So basically it does not make much sense to wrap a *NumberOf in an And condition for functional reasons - unless you want to the wrapping condition to create no results at all in some cases using weird probabilities. For restricting the possible matches without ignoring valid matches one needs to put the And condition inside the *NumberOf.
Geoff the Medio wrote: ↑Fri Dec 03, 2021 10:43 pm
Is there a reason what you want to do with WeightedAlternativesOf (or WeightedNumberOf) can't do the same?
Probably just don't see much benefit from commutativity if one has to wrap everything inside the *NumberOf (or *AlternativesOf). Makes the implementation harder to read and get right for sure.
I need to come up with the total count of alternatives for *AlternativesOf that is what is special/different from the current *NumberOf in order to get probabilities right.
If have that number early, I can skip a lot of unnecessary calculations.
I guess I rename the scope parameter to e.g. alternatives and not pull from universe but from matches and non_matches instead. Then I have the total count and I do not have to filter for shared conditions multiple times.
Any code or patches in anything posted here is released under the CC and GPL licences in use for the FO project.
Look, ma... four combat bouts!