diff --git a/bonemarketsolver/solve.py b/bonemarketsolver/solve.py index 0aae1f5..65b42cf 100644 --- a/bonemarketsolver/solve.py +++ b/bonemarketsolver/solve.py @@ -22,6 +22,7 @@ from .data.torsos import Torso # This multiplier is applied to the profit margin to avoid losing precision due to rounding. PROFIT_MARGIN_MULTIPLIER = 10000000 +ATTRIBUTE_MULTIPLIER = 10000000 # This is the highest number of attribute to calculate fractional exponents for. MAXIMUM_ATTRIBUTE = 100 @@ -197,21 +198,36 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.Add(tentacles == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.tentacles for action in actions.keys()])) # Amalgamy calculation + multiplied_amalgamy = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied amalgamy') + model.Add(multiplied_amalgamy == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.amalgamy*ATTRIBUTE_MULTIPLIER) for action in actions.keys()])) amalgamy = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'amalgamy') - model.Add(amalgamy == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.amalgamy for action in actions.keys()])) + model.AddDivisionEquality(amalgamy, multiplied_amalgamy, ATTRIBUTE_MULTIPLIER) + + del multiplied_amalgamy # Antiquity calculation + multiplied_antiquity = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied antiquity') + model.Add(multiplied_antiquity == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.antiquity*ATTRIBUTE_MULTIPLIER) for action in actions.keys()])) antiquity = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'antiquity') - model.Add(antiquity == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.antiquity for action in actions.keys()])) + model.AddDivisionEquality(antiquity, multiplied_antiquity, ATTRIBUTE_MULTIPLIER) + + del multiplied_antiquity # Menace calculation + multiplied_menace = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied menace') + model.Add(multiplied_menace == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.menace*ATTRIBUTE_MULTIPLIER) for action in actions.keys()])) menace = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'menace') - model.Add(menace == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.menace for action in actions.keys()])) + model.AddDivisionEquality(menace, multiplied_menace, ATTRIBUTE_MULTIPLIER) + + del multiplied_menace # Implausibility calculation + multiplied_implausibility = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied implausibility') + model.Add(multiplied_implausibility == cp_model.LinearExpr.ScalProd(actions.values(), [int(action.value.implausibility*ATTRIBUTE_MULTIPLIER) for action in actions.keys()])) implausibility = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'implausibility') - model.Add(implausibility == cp_model.LinearExpr.ScalProd(actions.values(), [action.value.implausibility for action in actions.keys()])) + model.AddDivisionEquality(implausibility, multiplied_implausibility, ATTRIBUTE_MULTIPLIER) + del multiplied_implausibility # Counter-church calculation # Calculate amount of Counter-church from Holy Relics of the Thigh of Saint Fiacre @@ -1204,16 +1220,16 @@ def Solve(shadowy_level, bone_market_fluctuations = None, zoological_mania = Non model.Add(net_profit == total_revenue - cost) # This is necessary to preserve some degree of precision after dividing - multiplied_net_profit = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'multiplied net profit') + multiplied_net_profit = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'multiplied net profit') model.AddMultiplicationEquality(multiplied_net_profit, [net_profit, PROFIT_MARGIN_MULTIPLIER]) - absolute_multiplied_net_profit = model.NewIntVar(0, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'absolute multiplied net profit') + absolute_multiplied_net_profit = model.NewIntVar(0, cp_model.INT32_MAX, 'absolute multiplied net profit') model.AddAbsEquality(absolute_multiplied_net_profit, multiplied_net_profit) - absolute_profit_margin = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'absolute profit margin') + absolute_profit_margin = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'absolute profit margin') model.AddDivisionEquality(absolute_profit_margin, absolute_multiplied_net_profit, total_revenue) - profit_margin = model.NewIntVar(cp_model.INT32_MIN*PROFIT_MARGIN_MULTIPLIER, cp_model.INT32_MAX*PROFIT_MARGIN_MULTIPLIER, 'profit margin') + profit_margin = model.NewIntVar(cp_model.INT32_MIN, cp_model.INT32_MAX, 'profit margin') positive_net_profit = model.NewIntermediateBoolVar('positive net profit', net_profit, cp_model.Domain.FromFlatIntervals([0, cp_model.INT_MAX])) model.Add(profit_margin == absolute_profit_margin).OnlyEnforceIf(positive_net_profit)