Python 繪圖 3D:生產組合最佳化

圖表

資源固定下,生產最佳組合

效用:長褲=46 夾克=40 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=27250.00 棉=0.00 化纖=0.00 效用:長褲=45 夾克=46 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=28375.00 棉=0.00 化纖=0.00 效用:長褲=49 夾克=41 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=28625.00 棉=0.00 化纖=0.00 效用:長褲=39 夾克=39 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=24375.00 棉=0.00 化纖=0.00 效用:長褲=45 夾克=43 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=27625.00 棉=0.00 化纖=0.00 效用:長褲=56 夾克=28 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=28000.00 棉=0.00 化纖=0.00 效用:長褲=56 夾克=34 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=29500.00 棉=0.00 化纖=0.00 效用:長褲=39 夾克=40 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=24625.00 棉=0.00 化纖=0.00 效用:長褲=46 夾克=43 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=28000.00 棉=0.00 化纖=0.00 效用:長褲=38 夾克=38 限制:棉=750 化纖=1000 長褲=375 夾克=250 貢獻=23750.00 棉=0.00 化纖=0.00

效用固定下,生產最佳組合

效用:長褲=50 夾克=40 限制:棉=756 化纖=966 長褲=347 夾克=272 貢獻=28230.00 棉=1.00 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=820 化纖=975 長褲=322 夾克=331 貢獻=29340.00 棉=1.50 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=794 化纖=1082 長褲=415 夾克=252 貢獻=30830.00 棉=1.00 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=692 化纖=943 長褲=362 夾克=219 貢獻=26860.00 棉=1.50 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=797 化纖=948 長褲=313 夾克=322 貢獻=28530.00 棉=1.00 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=775 化纖=1062 長褲=409 夾克=244 貢獻=30210.00 棉=0.00 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=731 化纖=1109 長褲=467 夾克=175 貢獻=30350.00 棉=1.50 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=757 化纖=993 長褲=367 夾克=259 貢獻=28710.00 棉=1.50 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=693 化纖=873 長褲=309 夾克=255 貢獻=25650.00 棉=1.50 化纖=0.00 效用:長褲=50 夾克=40 限制:棉=737 化纖=972 長褲=361 夾克=250 貢獻=28050.00 棉=1.00 化纖=0.00

程式碼

# -*- coding: utf-8 -*- import numpy as np import math from pulp import * import uuid from matplotlib import rcParams from matplotlib import pyplot as plt import pylab from mpl_toolkits.mplot3d import Axes3D class Optimizer: PlotData = None def __init__(self): self.PlotData = [] def solve(self, nameOfProblem, benefitList, resourceList, noOutput=False): prob = LpProblem(nameOfProblem, LpMaximize) # 變數 pants = LpVariable("Pants", lowBound=0, cat='Integer') jacket = LpVariable("Jacket", lowBound=0, cat='Integer') # 目標 prob += benefitList[0] * pants + benefitList[1] * jacket # 限制 prob += pants + 1.5 * jacket <= resourceList[0] prob += 2 * pants + jacket <= resourceList[1] # 解算 prob.writeLP("%s.lp" % (nameOfProblem)) prob.solve() if not noOutput: print u"效用:長褲=%.0f\t夾克=%.0f" % ( benefitList[0], benefitList[1]) print u"限制:棉=%.0f\t化纖=%.0f" % ( resourceList[0], resourceList[1]) if prob.status == 1: # 解答物件 Pants = Jacket = None for v in prob.variables(): if v.name == 'Pants': Pants = v elif v.name == 'Jacket': Jacket = v outcome = value(prob.objective) if not noOutput: print u"\t長褲=%d\t夾克=%d\t貢獻=%.2f" % \ (Pants.varValue, Jacket.varValue, outcome) # 殘餘資源 cotton = resourceList[0] - \ (Pants.varValue + 1.5 * Jacket.varValue) polyester = resourceList[1] - \ (2 * Pants.varValue + Jacket.varValue) if not noOutput: print u"\t棉=%.2f\t化纖=%.2f" % (cotton, polyester) self.PlotData.append([ benefitList[0], benefitList[1], resourceList[0], resourceList[1], Pants.varValue, Jacket.varValue, outcome]) else: if not noOutput: print "\t%s" % (LpStatus[prob.status]) def genNorm(self, mu, sigma, sampleSize, cat=True): ret = np.random.normal(mu, sigma, sampleSize) for i in range(0, sampleSize): if cat: ret[i] = math.floor(ret[i]) else: ret[i] = math.ceil(ret[i]) return (ret) def printList(self, randomList): for i in randomList: print "%.0f" % (i) def plot3D(self, cat, fontName='Microsoft MHei'): titleChart = [[u"長褲", u"夾克", u"貢獻"], [u"棉", u"化纖", u"貢獻"]] AnalysisData = np.array(self.PlotData) rcParams['font.family'] = fontName # Linux 'NanumBarunGothic' fig = pylab.figure() ax = Axes3D(fig) ax.set_title(u"生產最佳組合圖") ax.set_xlabel(titleChart[cat][0]) ax.set_ylabel(titleChart[cat][1]) ax.set_zlabel(titleChart[cat][2]) pointSize = [] for i in range(0, len(AnalysisData)): if cat == 0: val = math.sqrt( (math.pow(AnalysisData[:, 0][i], 2) + math.pow(AnalysisData[:, 1][i], 2)) ) pointSize.append(val) ax.scatter(AnalysisData[:, 0], AnalysisData[:, 1], AnalysisData[:, 6], s=pointSize) else: val = math.sqrt( (math.pow(AnalysisData[:, 2][i], 2) + math.pow(AnalysisData[:, 3][i], 2)) ) pointSize.append(val) ax.scatter(AnalysisData[:, 2], AnalysisData[:, 3], AnalysisData[:, 6], s=pointSize) plt.show() def ResetPlotData(self): self.PlotData = None self.PlotData = [] def Simulation(self, benefitRandomList, resourceRandomList, wantPlot=False): sampleSize = cat = 0 solverID = ['Benefit', 'Constraints'] if len(benefitRandomList[0]) == 1: cat = 1 if cat == 0: sampleSize = len(benefitRandomList[0]) else: sampleSize = len(resourceRandomList[0]) for i in range(0, sampleSize): if cat == 0: self.solve( 'Opt-%s-%s' % (solverID[cat], uuid.uuid4()), [benefitRandomList[0][i], benefitRandomList[1][i]], [resourceRandomList[0][0], resourceRandomList[1][0]], not wantPlot) else: self.solve( 'Opt-%s-%s' % (solverID[cat], uuid.uuid4()), [benefitRandomList[0][0], benefitRandomList[1][0]], [resourceRandomList[0][i], resourceRandomList[1][i]], not wantPlot) if wantPlot: self.plot3D(cat) else: for sol in self.PlotData: print u"效用:長褲=%.0f\t夾克=%.0f" % ( sol[0], sol[1]) print u"限制:棉=%.0f\t化纖=%.0f" % ( sol[2], sol[3]) print u"綜效:長褲=%.0f\t夾克=%.0f\t效益=%.0f\n" % ( sol[4], sol[5], sol[6]) if __name__ == "__main__": optimizer = Optimizer() sampleSize = 10 benefitRandomList = [ optimizer.genNorm(50, 8, sampleSize), optimizer.genNorm(40, 6, sampleSize) ] resourceRandomList = [[750], [1000]] optimizer.Simulation(benefitRandomList, resourceRandomList, True) benefitRandomList = [[50], [40]] resourceRandomList = [ optimizer.genNorm(750, 43, sampleSize), optimizer.genNorm(1000, 76, sampleSize)] optimizer.Simulation(benefitRandomList, resourceRandomList, True) optimizer.ResetPlotData()