Skip to content

Instantly share code, notes, and snippets.

@luthfianto
Created December 9, 2019 17:21
Show Gist options
  • Save luthfianto/695696933c4af2f1745c1865d5f155e0 to your computer and use it in GitHub Desktop.
Save luthfianto/695696933c4af2f1745c1865d5f155e0 to your computer and use it in GitHub Desktop.
DF_COLUMN_NAME_DEALER = "Group Dealer Code"
## Formula
def f_RS_n(stock_nm1, distplan_n, target_n, target_np1):
def f_stock_n(stock_nm1, distplan_n, target_n):
return stock_nm1 + distplan_n - target_n
def _RS_n(stock_n, target_np1):
return stock_n / np.where(target_np1==0,1, target_np1)
return _RS_n(f_stock_n(stock_nm1, distplan_n, target_n), target_np1)
def f_RSSP_fullfilment(distplan_n, RSSP_n):
return distplan_n / np.where(RSSP_n==0,1, RSSP_n)
def f_OS_length_n(OS_nm1, SPK_n, distplan_n, target_np1):
def _f_OS_length_n(OS_n, target_np1):
return OS_n / np.where(target_np1==0,1, target_np1)
def _f_OS_n(OS_nm1, SPK_n, distplan_n):
return OS_nm1 + SPK_n - distplan_n
OS_n = _f_OS_n(OS_nm1, SPK_n, distplan_n)
return _f_OS_length_n(OS_n, target_np1)
def f_Target_fulfillment_n(stock_nm1, distplan_n, target_n):
return (stock_nm1 + distplan_n)/np.where(target_n==0,1, target_n)
"""
if distplan_n summed, it would be distplan - alloc = 0, because x-x = 0
Sum RightHand. Scalar is okay
"""
def loss_RS(distplan_n, alloc, df, ByQty, goal = 'national'):
# Get series
stock_nm1_series = df["SRBy" + ByQty ]
target_n_series = df["TBy" + ByQty ]
target_np1_series = df["TBy" + ByQty +"P1" ]
# Get values of series
stock_nm1 = stock_nm1_series.values
target_n = target_n_series.values
target_np1 = target_np1_series.values
# y_pred
left = f_RS_n(stock_nm1, distplan_n, target_n, target_np1)
if goal == 'national':
# No-need to groupby
pass
elif goal == 'area':
# Group series by Area
stock_nm1 = stock_nm1_series.groupby('Area')
target_n_series = target_n_series.groupby('Area')
target_np1_series = target_np1_series.groupby('Area')
elif goal == 'dealer':
# Group series by Dealer
stock_nm1 = stock_nm1_series.groupby(DF_COLUMN_NAME_DEALER)
target_n_series = target_n_series.groupby(DF_COLUMN_NAME_DEALER)
target_np1_series = target_np1_series.groupby(DF_COLUMN_NAME_DEALER)
# Get from parameter
if type(goal) != str:
right = goal
else:
# Use previously (un/)aggregated values
stock_nm1 = stock_nm1_series.values
target_n = target_n_series.values
target_np1 = target_np1_series.values
right = f_RS_n(stock_nm1.sum(), alloc.sum(), target_n.sum(), target_np1.sum())
return left - right
def loss_RSSP_fulfillment(distplan_n, alloc, df, ByQty, goal = 'national'):
RSSP_series = df["RSSP"]
RSSP = RSSP_series.values
left = f_RSSP_fullfilment(distplan_n, RSSP)
right =f_RSSP_fullfilment(alloc.sum(), RSSP.sum())
if goal == 'national':
# No-need to groupby
pass
elif goal == 'area':
# Group series by Area
RSSP_series = RSSP_series.groupby('Area')
elif goal == 'dealer':
# Group series by Dealer
RSSP_series = RSSP_series.groupby(DF_COLUMN_NAME_DEALER)
# Get from parameter
if type(goal) != str:
right = goal
else:
# Use previously (un/)aggregated values
RSSP = RSSP_series.values
right = f_RSSP_fullfilment(alloc.sum(), RSSP.sum())
return left - right
def loss_Target_fulfillment_n(distplan_n, alloc, df, ByQty, goal = 'national'):
stock_nm1_series = df["SRBy" + ByQty ]
target_n_series = df["TBy" + ByQty ]
stock_nm1 = stock_nm1_series.values
target_n = target_n_series.values
if goal == 'national':
# No-need to groupby
pass
elif goal == 'area':
# Group series by Area
stock_nm1_series = stock_nm1_series.groupby('Area')
target_n_series = target_n_series.groupby('Area')
elif goal == 'dealer':
# Group series by Dealer
stock_nm1_series = stock_nm1_series.groupby(DF_COLUMN_NAME_DEALER)
target_n_series = target_n_series.groupby(DF_COLUMN_NAME_DEALER)
# Get from parameter
if type(goal) != str:
right = goal
else:
# Use previously (un/)aggregated values
stock_nm1 = stock_nm1_series.values
target_n = target_n_series.values
right = f_Target_fulfillment_n(stock_nm1.sum(), alloc.sum(), target_n.sum())
return left - right
class CostManager:
_loss_functions = {
"RS": loss_RS,
"RSSPFulfillment": loss_RSSP_fulfillment,
"TargetFulfillment": loss_Target_fulfillment_n,
"OSLength": loss_Target_fulfillment_n,
}
def __init__(self, df, allocation_series, cp_variable):
self._df = df
self._allocation_series = allocation_series
self._cx_var_distplan = cp_variable
# print("========")
# print(self._cx_var_distplan)
# print(self._cx_var_distplan.shape)
# print("========")
def _get_costs(self, selected_objectives):
cost_list = []
for obj in selected_objectives:
print(obj)
by = obj.get("by")
if by:
ByQty = by + "Qty"
else:
ByQty=None
goal = obj.get("goal") or "national"
cost = self._loss_functions[obj["type"]](
self._cx_var_distplan, self._allocation_series.sum(), self._df, ByQty, goal
)
cost_list.append(cost)
return cost_list
def _sumrank_cost_list(self, cost_list, cost_weights):
acc_cost = 0
for idx in range(len(cost_list)):
curr_cost = cost_list[idx]
if cost_weights:
curr_weight = cost_weights[idx]
else:
curr_weight = 1 / (1 + idx)
# acc_cost = acc_cost + curr_weight * cp.sum_squares(cp.square(curr_cost))
acc_cost = acc_cost + curr_weight * cp.sum_squares(curr_cost)
return acc_cost
def compute_cost(self, selected_objectives, objectives_weights=None):
if objectives_weights:
assert len(objectives_weights) == len(selected_objectives), (len(objectives_weights), len(selected_objectives))
cost_list = self._get_costs(selected_objectives)
acc_cost = self._sumrank_cost_list(cost_list, objectives_weights)
return acc_cost
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment