I am trying to solve a problem (in pyspark/ python) where I need to find two distinct values to allocate, and how to allocate them in a network of stores.
The two distinct values can only be integer values and constrained within a lower and upper bound. For each such distinct value pair, say 4 and 8, each store can get either 4 or 8 giving a total of 2n different ways of allocation if there are n stores (n is close to 1000).
The objective function is a complex one and uses predictive models to give the impact of a particular value pair corresponding to its allocation in the network.
I was hoping if I could create a cost function of the form:
Cost = f( variant1, variant2, store_1_variant, store_2_variant, ..., store_n_variant)
where
variant1 = 4
(integer, constrained within a max value)variant2 = 8
(integer, constrained within a max value)store_1_variant, ..., store_n_variant
are binary [0,1] to suggest whether they receivevariant_1
or not (not receivingvariant1
would mean receivingvariant2
)
I could solve for the n + 2 parameters that minimize the cost (there is another constraint that needs to keep in check the impact of a certain allocation)
I have looked at various combinatorial optimisation techniques but none that seem to allow me a user defined function as a cost function.
I have no prior experience in to this area so any direction/ assistance is appreciated.
Edit
To add some information on the current form of cost function, continuing with the example of two variants being 4 and 8 with say 5 stores, f(4, 8, 0, 1, 1, 0, 0)
will have an associated cost of the form
a*s11*(s12/8)b + a*s21*(s22/4)b + a*s31*(s32/4)b + a*s41*(s42/8)b + a*s51*(s52/8)b
where s11 and s12 are store level metrics for store 1 and so on.
Parameters a and b are regressed coefficients from historic data, but this is just a good starting point and will eventually evolve into a more complex functional form (might be predictions from an ML algorithm)
Constraints:
variant1 <= k1
variant2 >= k1 and <= k2
(s13/8) + (s23/4) + (s33/4) + (s43/8) + (s53/8) should lie between [ (0.95/k1) * (s13 + s23 + s33+ s43+ s53),
(1.05/k1) * (s13 + s23 + s33+ s43+ s53) ] (5% deviation)
where k1, k2, variant1 and variant2 are integers