Intelligent-Sourcing / create_optimization_problem.py
Krishna Kumar S
Update create_optimization_problem.py
97b3cae
from pulp import *
import pandas as pd
from read_data import load_excel_data
def create_sourcing_problem(weightage_dict, priority_df, warehouse_df, order_df, cost_df, distance_df, days_df):
"""
Creates and returns a linear programming problem for intelligent sourcing optimization.
Parameters:
weightage_dict (dict): Dictionary containing weightages for cost, priority, distance, and days.
priority_df (DataFrame): DataFrame containing priority values for each warehouse.
warehouse_df (DataFrame): DataFrame containing stock availability for each warehouse.
order_df (DataFrame): DataFrame containing order quantities for each product.
cost_df (DataFrame): DataFrame containing cost values.
distance_df (DataFrame): DataFrame containing distance values.
days_df (DataFrame): DataFrame containing expected delivery days.
Returns:
LpProblem: Linear programming problem formulated for sourcing optimization.
Warehouses, Products, Stock, Priority, Orders, Quantity
"""
def min_max_scale(df, column):
min_val = df[column].min()
max_val = df[column].max()
df[column] = (df[column] - min_val) / (max_val - min_val)
return df
# Extract weightages
weightage_Cost = weightage_dict["Cost"]
weightage_Priority = weightage_dict["Priority"]
weightage_distance = weightage_dict["Distance"]
weightage_days = weightage_dict["Days"]
# Normalize data
priority_df = min_max_scale(priority_df, "Priority")
cost_df = min_max_scale(cost_df, "Cost")
distance_df = min_max_scale(distance_df, "Distance")
days_df = min_max_scale(days_df, "Days")
# Create dictionaries for optimization
Warehouses = warehouse_df['Warehouse'].tolist()
Products = warehouse_df.columns[1:]
Stock = makeDict([Warehouses, Products], warehouse_df.drop('Warehouse', axis=1).values, default=0)
Priority = makeDict([Warehouses], priority_df.drop('Warehouse', axis=1).values.reshape(len(Warehouses)), default=0)
Orders = order_df['Order'].tolist()
Quantity = makeDict([Orders, Products], order_df.drop('Order', axis=1).values, default=0)
cost_values = cost_df["Cost"].values.reshape(len(Warehouses), len(Orders), len(Products))
cost = makeDict([Warehouses, Orders, Products], cost_values, default=0)
distance_values = distance_df["Distance"].values.reshape(len(Warehouses), len(Orders), len(Products))
distance = makeDict([Warehouses, Orders, Products], distance_values, default=0)
days_values = days_df["Days"].values.reshape(len(Warehouses), len(Orders), len(Products))
days = makeDict([Warehouses, Orders, Products], days_values, default=0)
# Define variables and routes
routes = [(w, o, s) for w in Warehouses for o in Orders for s in Products]
Variable = LpVariable.dicts("Route", (Warehouses, Orders, Products), 0, None, LpInteger)
# Create optimization problem
prob = LpProblem("Sourcing_Problem", LpMaximize)
# Objective function
prob += lpSum(
Variable[w][o][p] * (
(weightage_Cost * -cost[w][o][p]) +
(weightage_Priority * -Priority[w]) +
(weightage_distance * -distance[w][o][p]) +
(weightage_days * -days[w][o][p])
)
for (w, o, p) in routes
), "Sum_of_Costs"
# Stock Constraints
for w in Warehouses:
for p in Products:
prob += lpSum([Variable[w][o][p] for o in Orders]) <= Stock[w][p], f"Stock_Constraint_{p}_in_{w}"
# Order Constraints
for o in Orders:
for p in Products:
prob += lpSum([Variable[w][o][p] for w in Warehouses]) == Quantity[o][p], f"Order_Fulfillment_{p}_to_{o}"
return prob, Warehouses, Products, Stock, Priority, Orders, Quantity, Variable
if __name__ == "__main__":
filepath = 'Intelligent_Sourcing.xlsx' # Example file path
weightage_dict, priority_df, warehouse_df, order_df, cost_df, distance_df, days_df, = load_excel_data(filepath)
prob, Warehouses, Products, Stock, Priority, Orders, Quantity, Variable = create_sourcing_problem(weightage_dict, priority_df, warehouse_df, order_df, cost_df, distance_df, days_df)
print(prob.objective)