Ah, tricky to formulate with such equations. Hmm both price and the payout is inconvenient, I guess that makes it non linear which the method I suggested isn't really made for but the solver I mentioned might be able to do that, I have seen that it has a way to basically add an if then for instance https://developers.google.com/optimization/cp/channeling?hl=en . I am not quite sure how the in game mechanic works exactly based on the wiki. Does the price at which you buy it matter for the profit? Like if you buy it for the price of 100k with 19 score and then increase you score to 20 do you get 50k profit? How man Givini points can you get during this? That the reward could change after buying the investment is annoying.
Hmm for profit this should work: Give the base investment a value of 25k. Then add an extra profit variable where the profit is the difference between the profit stages and it can only take those values so: 25k (25>50), 75k (>100),125k, 50k.175k
model.NewIntVarFromDomain(cp_model.Domain.FromValues([0,25000,75000,125000,175000]), 'extraprofit1') (extraprofit1= extraprofit from givini points in that period.) (I am using this https://gitcode.net/mirrors/google/or-tools/-/blob/b37d9c786b69128f3505f15beca09e89bf078a89/ortools/sat/doc/integer_arithmetic.md?from_codechina=yes to look up functions)
This should always take the max value it can because it is free. So we need conditions (for every phase) to make it so that they can only be "bought" if the base investment has been bought and the score is high enough. The solver has an OnlyEnforceIf condition to apply a condition only if something is true. but I am unsure whether that can handle complex conditions.
Well I suppose it doesn't need to. You can make for each phase an extra variable that indicate whether the base investment has been bought in that round, like for round 2 model.Add(a1 +a2 == bought2) where ai is buying the investment in round 1 and bought 2 means it is bought in round 2. then you can add for each round a conditional condition model.Add(extraprofit2 == 0).OnlyEnforceIf(bought2.Not()) that means it can only be above 0 if it has been bought.
As for limiting the value based on the score hmm the ranges after the first are always 10 long and the difference is always 50k after the first 25k step that allows this:
model.Add(extraprofit1 <= (givini points at end of round 1)*5000-75000) at 20 points this is 25000 at 30 75000 and so on. so for givini points you just need to take what you already have and make a list of all investments that add points and add them.
For price, well one way is to just make them separate investments, ensure only one can be bought and only if the Givini score is right. Another (edit: that is better) is to do basically the opposite of what I suggested with the profit. 5 extra cost variables. They can take the values 0/-100k/-200k/-300k/-400k and some Givini point based condition forces that to be lower but only applies if it has been bought in the current round. But the first point step is smaller so I will use two conditions. So basically for the funded variant
model.Add(extracost1 <= (givini points)*-10000+50000).OnlyEnforceIf(a1)
That should switch at 25/35/55 to -200/-300/-400
and model.Add(extracost1 <= (givini points)*-5000).OnlyEnforceIf(a1) ensures the switch at 25 points. (edit: note that this should be the givini point at the beginning of the round if I am interpreting how it works correctly. Because you would buy it before buying something that makes it more exspensive.) (Edit actually I got the values wrong for this one , have to change the offset so that it passes the previous value at the time it should change to the next.)