#!/usr/bin/python # encoding: utf-8 """ @author: @contact: zhangcdnuli@163.com @file: 最優解.py @time: 2020/7/14 14:12 """ """ 做推廣方案其實是運籌學中的求最優解問題,運用運籌學的知識可以制定出最佳的投放方案。 如果這個月老闆給你1千萬的推廣預算,讓你給分配到各個管道和品類,要確認分配比例,可以讓這1千萬的效果最大化。 已知條件,該企業有4個主要管道,分別是電商站、某音、某度和線下。 電商站不能少於1百萬的投入,投入產出比(ROI)是1.5 某音不能高於3百萬的投入,投入產出比是2 某度不能少於2百萬的投入,投入產出比是0.7 線下不能低於1百萬的投入,投入產出比是0.1 共有5個主要品類,分別為服裝、家電、百貨、美妝和餐飲具 服裝不能少於100萬的投入,ROI是1.2 家電不能高於300萬的投入,ROI是2 百貨不能少於100萬的投入,ROI是1.4 美妝不能高於350萬的投入,ROI是1.5 餐飲不能少於50萬的投入,ROI是0.8 請把1千萬的推廣預算合理地分配到各個管道和品類 要明確到某個品類要在某個管道中投放多少預算。 """ from scipy.optimize import linprog """ 管道投入分佈 max z = 1.5X_1 + 2X_2 + 0.7X_3 + 0.1X_4 X_1 + X_2 + X_3 + X_4 = 1000 X_1 >= 100 X_2 <= 300 X_3 >= 200 X_4 >= 100 """ c1 = [-1.5,-2,-0.7,-0.1] A_eq1 = [[1,1,1,1]] b_eq1 = [1000] x1 = (100,1000) x2 = (0,300) x3 = (200,1000) x4 = (100,1000) res1 = linprog(c1,A_eq=A_eq1,b_eq=b_eq1,bounds=(x1,x2,x3,x4)) # 獲取全部x的值 x = res1.get('x') # 管道投產最大值 fun1 = abs(round(res1.get('fun'))) # 電商站投入份額 x_1 = round(x[0]) # 某音投入份額 x_2 = round(x[1]) # 某度投入份額 x_3 = round(x[2]) # 線下投入份額 x_4 = round(x[3]) print('品類投產最大值:',fun1) print('電商站投入份額:',x_1) print('某音投入份額:',x_2) print('某度投入份額:',x_3) print('線下投入份額:',x_4) print('===================================================================') """ 品類投入分佈 max z = 1.2Y_1 + 2Y_2 + 1.4Y_3 + 1.5Y_4 + 0.8Y_5 Y_1 + Y_2 + Y_3 + Y_4 + Y_5 = 1000 Y_1 >= 100 Y_2 <= 300 Y_3 >= 100 Y_4 <= 350 Y_5 >= 50 """ c2 = [-1.2,-2,-1.4,-1.5,-0.8] A_eq2 = [[1,1,1,1,1]] b_eq2 = [1000] y1 = (100,1000) y2 = (0,300) y3 = (100,1000) y4 = (0,350) y5 = (50,1000) res2 = linprog(c2,A_eq=A_eq2,b_eq=b_eq2,bounds=(y1,y2,y3,y4,y5)) # 獲取全部y的值 y = res2.get('x') # 品類投產最大值 fun2 = abs(round(res2.get('fun'))) # 服裝投入份額 y_1 = round(y[0]) # 家電投入份額 y_2 = round(y[1]) # 百貨投入份額 y_3 = round(y[2]) # 美妝投入份額 y_4 = round(y[3]) # 餐飲投入份額 y_5 = round(y[4]) print('品類投產最大值:',fun2) print('服裝投入份額:',y_1) print('家電投入份額:',y_2) print('百貨投入份額:',y_3) print('美妝投入份額:',y_4) print('餐飲投入份額:',y_5) print('===================================================================') # 獲取最小值 def least(num1,num2): lea = 0 if num1 <= num2 : lea = num1 else: lea = num2 return lea """ 合併管道和品類的投入份額 獲取每個品類在各個管道投入的份額 Max z = 1.8a1 + 2a2 + 0.84a3 + 0.12a4 + 3b1 + 4b2 + 1.4b3 + 0.2b4 + 2.1c1 + 2.8c2 + 0.98c3 + 0.14c4 + 2.25d1 + 3d2 + 1.05d3 + 0.15d4 + 1.2e1 + 1.6e2 + 0.56e3 + 0.08e4 a1 + a2 + a3 + a4 = 100 b1 + b2 + b3 + b4 = 300 c1 + c2 + c3 + c4 = 200 d1 + d2 + d3 + d4 = 350 e1 + e2 + e3 + e4 = 50 a1 + b1 + c1 + d1 + e1 = 400 a2 + b2 + c2 + d2 + e2 = 300 a3 + b3 + c3 + d3 + e3 = 200 a4 + b4 + c4 + d4 + e4 = 100 """ c = [-1.8,-2,-0.84,-0.12,-3,-4,-1.4,-0.2,-2.1,-2.8,-0.98,-0.14,-2.25,-3,-1.05,-0.15,-1.2,-1.6,-0.56,-0.08] cc = [1.8,2,0.84,0.12,3,4,1.4,0.2,2.1,2.8,0.98,0.14,2.25,3,1.05,0.15,1.2,1.6,0.56,0.08] A = [ [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1], [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0], [0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0], [0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0], [0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1] ] b = [y_1,y_2,y_3,y_4,y_5,x_1,x_2,x_3,x_4] a1 = (0,least(x_1,y_1)) a2 = (0,least(x_2,y_1)) a3 = (0,least(x_3,y_1)) a4 = (0,least(x_4,y_1)) b1 = (0,least(x_1,y_2)) b2 = (0,least(x_2,y_2)) b3 = (0,least(x_3,y_2)) b4 = (0,least(x_4,y_2)) c1 = (0,least(x_1,y_3)) c2 = (0,least(x_2,y_3)) c3 = (0,least(x_3,y_3)) c4 = (0,least(x_4,y_3)) d1 = (0,least(x_1,y_4)) d2 = (0,least(x_2,y_4)) d3 = (0,least(x_3,y_4)) d4 = (0,least(x_4,y_4)) e1 = (0,least(x_1,y_5)) e2 = (0,least(x_2,y_5)) e3 = (0,least(x_3,y_5)) e4 = (0,least(x_4,y_5)) res = linprog(c, A_eq=A, b_eq=b, bounds=(a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4,e1,e2,e3,e4)) z = res.get('x') # 個品類在各個管道投入的份額的投產最大值 fun = abs(round(res.get('fun'))) # 服裝電商站投入份額 a_1 = round(z[0]) # 服裝某音投入份額 a_2 = round(z[1]) # 服裝某度投入份額 a_3 = round(z[2]) # 服裝線下投入份額 a_4 = round(z[3]) # 家電電商站投入份額 b_1 = round(z[4]) # 家電某音投入份額 b_2 = round(z[5]) # 家電某度投入份額 b_3 = round(z[6]) # 家電線下投入份額 b_4 = round(z[7]) # 百貨電商站投入份額 c_1 = round(z[8]) # 百貨某音投入份額 c_2 = round(z[9]) # 百貨某度投入份額 c_3 = round(z[10]) # 百貨線下投入份額 c_4 = round(z[11]) # 美妝電商站投入份額 d_1 = round(z[12]) # 美妝某音投入份額 d_2 = round(z[13]) # 美妝某度投入份額 d_3 = round(z[14]) # 美妝線下投入份額 d_4 = round(z[15]) # 餐飲電商站投入份額 e_1 = round(z[16]) # 餐飲某音投入份額 e_2 = round(z[17]) # 餐飲某度投入份額 e_3 = round(z[18]) # 餐飲線下投入份額 e_4 = round(z[19]) print('每個品類在各個管道投入的份額的投產最大值為:',fun) print('服裝投入份額管道分佈') print('電商站投入份額:',a_1,'某音投入份額:',a_2,'某度投入份額:',a_3,'線下投入份額:',a_4) print('家電投入份額管道分佈') print('電商站投入份額:',b_1,'某音投入份額:',b_2,'某度投入份額:',b_3,'線下投入份額:',b_4) print('百貨投入份額管道分佈') print('電商站投入份額:',c_1,'某音投入份額:',c_2,'某度投入份額:',c_3,'線下投入份額:',c_4) print('美妝投入份額管道分佈') print('電商站投入份額:',d_1,'某音投入份額:',d_2,'某度投入份額:',d_3,'線下投入份額:',d_4) print('餐飲投入份額管道分佈') print('電商站投入份額:',e_1,'某音投入份額:',e_2,'某度投入份額:',e_3,'線下投入份額:',e_4)