版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
現(xiàn)代庫存管理:模型、算法與Python實(shí)現(xiàn)第15章承諾服務(wù)模型15.1承諾服務(wù)模型的需求規(guī)劃問題
15.1承諾服務(wù)模型的需求規(guī)劃問題
15.2需求上界的構(gòu)造與計(jì)算
15.2需求上界的構(gòu)造與計(jì)算
15.2需求上界的構(gòu)造與計(jì)算例:以下圖的生產(chǎn)裝配網(wǎng)絡(luò)為對象,計(jì)算給定服務(wù)水平為0.95的情況下,每個(gè)節(jié)點(diǎn)的需求上界#定義數(shù)據(jù)存儲路徑
data_dir=
'../../data/tree_example/'
#讀取網(wǎng)絡(luò)的節(jié)點(diǎn)數(shù)據(jù)
node_df=pd.read_csv(data_dir+
'assembly_node_df.csv')
#讀取網(wǎng)絡(luò)的邊數(shù)據(jù)
edge_df=pd.read_csv(data_dir+
'assembly_edge_df.csv')
#讀取網(wǎng)絡(luò)的需求數(shù)據(jù)
demand_df=pd.read_csv(data_dir+
'assembly_demand_df.csv')15.2需求上界的構(gòu)造與計(jì)算例:數(shù)據(jù)概況節(jié)點(diǎn)信息表’node_df’:’lt’:節(jié)點(diǎn)的單級提前期’hc’:單位持貨成本’sla’:對客戶承諾的服務(wù)時(shí)間node_idlthcsla0C180.4685565NaN1B111.994935NaN2C270.271441NaN3C330.632656NaN4B280.861130NaN5A33.7657402.0邊信息表’edge_df’:’predecessor’:上游節(jié)點(diǎn)’successor’:下游節(jié)點(diǎn)’quantity’:生產(chǎn)配比predecessorsuccessorquantity0C1B111B1A12C2B123C3B214B2A1需求信息表’demand_df’:只有節(jié)點(diǎn)A為需求節(jié)點(diǎn),mean為14.558117,std為2.89212915.2需求上界的構(gòu)造與計(jì)算假設(shè)庫存共享效應(yīng)系數(shù)為2,服務(wù)水平系數(shù)取標(biāo)準(zhǔn)正態(tài)分布的0.95分位數(shù)。相當(dāng)于假設(shè)需求服從正態(tài)分布,同時(shí)模型僅覆蓋0.95分位數(shù)以下的需求波動(dòng)
pooling_factor=
2
tau=
0.9515.2需求上界的構(gòu)造與計(jì)算具體代碼如下:#調(diào)用第10章確定上游節(jié)點(diǎn)的函數(shù)得到每個(gè)節(jié)點(diǎn)的上游節(jié)點(diǎn)列表
pred_dict=find_predecessors_dict(edges=edge_df[['predecessor',
'successor']].values)
#生產(chǎn)配比
qty_dict={(pred,succ):qtyforpred,succ,qtyinedge_df.values}
#需求節(jié)點(diǎn)的需求及標(biāo)準(zhǔn)差
mu_dict=dict(zip(demand_df['node_id'],demand_df['mean']))
sigma_dict=dict(zip(demand_df['node_id'],demand_df['std']))
#各節(jié)點(diǎn)自身需求所對應(yīng)的需求波動(dòng)系數(shù)
ksigma_dict={node:0
fornodeinnode_df['node_id']}
ksigma_dict.update({node:norm.ppf(tau)*sigma
fornode,sigmainsigma_dict.items()})
#初始化涉及到向下傳遞的字典
network_mu_dict={node:0
fornodeinnode_df['node_id']}
#首先將需求節(jié)點(diǎn)的信息加入到字典中
network_mu_dict.update({node:mufornode,muinmu_dict.items()})
constant_dict={node:v**pooling_factorfornode,vinksigma_dict.items()}15.2需求上界的構(gòu)造與計(jì)算具體代碼如下:#將網(wǎng)絡(luò)的邊反向
reverse_edges=[(j,i)fori,jin
edge_df[['predecessor','successor']].values]
#計(jì)算拓?fù)渑判?/p>
ts=TopologicalSort(reverse_edges)
reverse_topo_sort=ts()
fornodeinreverse_topo_sort:
#如果節(jié)點(diǎn)有上游節(jié)點(diǎn),則將自身的需求信息傳遞給上游節(jié)點(diǎn)
iflen(pred_dict[node])>
0:
forpredinpred_dict[node]:
constant_dict[pred]+=(qty_dict[pred,node]**pooling_factor)\
*constant_dict[node]
network_mu_dict[pred]+=qty_dict[pred,node]*network_mu_dict[
node]
#在全部節(jié)點(diǎn)傳遞完成后,計(jì)算需求波動(dòng)系數(shù)
volatility_constant_dict={node:np.power(v,1
/pooling_factor)
fornode,vinconstant_dict.items()}
volatility_constant_df=pd.DataFrame.from_dict(
volatility_constant_dict,orient='index').reset_index().rename(
columns={'index':'node_id',0:'volatility_constant'})
network_mu_df=pd.DataFrame.from_dict(
network_mu_dict,orient='index').reset_index().rename(
columns={'index':'node_id',0:'mean'})15.2需求上界的構(gòu)造與計(jì)算具體代碼如下:lt_dict=dict(zip(node_df['node_id'],node_df['lt']))
cum_lt_dict=cal_cum_lt(edge_df[['predecessor','successor']].values,lt_dict)
cum_lt_df=pd.DataFrame.from_dict(
cum_lt_dict,orient='index').reset_index().rename(
columns={'index':'node_id',0:'cum_lt'})
node_df=node_df.merge(cum_lt_df,on='node_id',how='left')
print(node_df)#定義離散化的時(shí)間顆粒度
time_unit=
1
#根據(jù)節(jié)點(diǎn)和對應(yīng)的累計(jì)提前期,生成index
node_list=node_df['node_id'].tolist()
idx=[(node,ct)fornodeinnode_list
forctinnp.arange(0,cum_lt_dict[node]+time_unit,time_unit)]
idx=pd.MultiIndex.from_tuples(idx,names=['node_id','time'])
demand_bound_df=pd.DataFrame(index=idx).reset_index()
demand_bound_df=demand_bound_df.merge(
volatility_constant_df,on=['node_id'],how='left')
demand_bound_df=demand_bound_df.merge(
network_mu_df,on=['node_id'],how='left')
#根據(jù)對應(yīng)的CT,計(jì)算對應(yīng)的安全庫存量,以及需求上界
demand_bound_df['ss_qty']=demand_bound_df['volatility_constant']*np.power(
demand_bound_df['time'],1
/pooling_factor)
demand_bound_df['demand_bound']=demand_bound_df['mean']*demand_bound_df[
'time']+demand_bound_df['ss_qty']
print(demand_bound_df.head())15.2需求上界的構(gòu)造與計(jì)算結(jié)果如下:node_idtimevolatility_constantmeanss_qtydemand_bound0C104.75712914.558170.0000000.0000001C114.75712914.558174.75712919.3152472C124.75712914.558176.72759735.8438323C134.75712914.558178.23959051.9139424C144.75712914.558179.51425867.74672815.2需求上界的構(gòu)造與計(jì)算不同服務(wù)時(shí)間下的策略及成本比較:
根據(jù)計(jì)算得到的demand_bound_df,查找出每個(gè)節(jié)點(diǎn)不同覆蓋時(shí)間的安全庫存量,計(jì)算出總庫存成本,接下來考慮三種比較有代表性的策略:只在最下游設(shè)置安全庫存。該策略將安全庫存全部前置到需求節(jié)點(diǎn),即只持有成品庫存。其好處是將所有節(jié)點(diǎn)安全庫存的覆蓋時(shí)間全部匯聚在需求節(jié)點(diǎn),這樣可以最大化安全庫存在“時(shí)間維度”的共享效應(yīng)。其劣勢是完全忽視了安全庫存在“空間”維度的共享效應(yīng)按照單級的方法設(shè)置安全庫存。該策略下,每個(gè)節(jié)點(diǎn)都根據(jù)自身的提前期按照單級的方式計(jì)算安全庫存。其好處是計(jì)算簡單,但它完全沒有考慮到網(wǎng)絡(luò)中安全庫存的共享效應(yīng),也忽略了節(jié)點(diǎn)之間持貨成本的差異,沒有對安全庫存進(jìn)行全網(wǎng)絡(luò)優(yōu)化網(wǎng)絡(luò)最優(yōu)的安全庫存。該策略通過優(yōu)化所有節(jié)點(diǎn)的服務(wù)時(shí)間,在保證需求節(jié)點(diǎn)的承諾服務(wù)時(shí)間的條件下,充分挖掘網(wǎng)絡(luò)中安全庫存“空間維度”和“時(shí)間維度”的共享效應(yīng),最小化網(wǎng)絡(luò)的總安全庫存成本15.2需求上界的構(gòu)造與計(jì)算不同服務(wù)時(shí)間下的策略及成本比較:只在最下游設(shè)置安全庫存:前面計(jì)算過,節(jié)點(diǎn)A的累計(jì)提前期為14天,它的承諾服務(wù)時(shí)間為2天,如果只在節(jié)點(diǎn)A上設(shè)置安全庫存,它的覆蓋時(shí)間CT=14-2=12天,其他節(jié)點(diǎn)的覆蓋時(shí)間都為0,經(jīng)計(jì)算該策略的安全庫存成本為62.06使用單級的方法設(shè)置安全庫存:在該策略下,需求節(jié)點(diǎn)A的覆蓋時(shí)間等于自身提前期減去其sla,其他節(jié)點(diǎn)的覆蓋時(shí)間都是自身提前期,該策略的安全庫存總成本為57.34網(wǎng)絡(luò)最優(yōu)的安全庫存策略:本章的后續(xù)內(nèi)容將介紹如何優(yōu)化承諾服務(wù)模型。這里先直接給出該網(wǎng)絡(luò)下每個(gè)節(jié)點(diǎn)的最優(yōu)覆蓋時(shí)間:{’B2’:10,’B1’:0,’C1’:8,’C2’:7,’A’:2,’C3’:0}。根據(jù)給出的最優(yōu)覆蓋時(shí)間,可以得到最優(yōu)的安全庫存策略及其成本51.43可以看出,相比于前兩種方法,最優(yōu)的安全庫存策略能夠顯著降低庫存成本15.3承諾服務(wù)模型的優(yōu)化算法動(dòng)態(tài)規(guī)劃算法:例:對下圖樹網(wǎng)絡(luò)中的節(jié)點(diǎn)進(jìn)行排序步驟2可能出現(xiàn)多種選擇,因此得到的排序可能不唯一
得到一組符合要求的排序:[’D1’,’D2’,’C2’,’A1’,’A2’,’C1’,’B’]那么該樹網(wǎng)絡(luò)中每個(gè)節(jié)點(diǎn)對應(yīng)的排序標(biāo)記為:{’A1’:4,’A2’:5,’B’:7,’C1’:6,’C2’:3,’D1’:1,’D2’:2}15.3承諾服務(wù)模型的優(yōu)化算法動(dòng)態(tài)規(guī)劃算法:
A1B{A1}A2B{A2}B\{A1,A2,C1,C2}C1B{C1,D1,D2}C2B{C2}D1C1{D1}D2C1{D2}15.3承諾服務(wù)模型的優(yōu)化算法動(dòng)態(tài)規(guī)劃算法:
15.3承諾服務(wù)模型的優(yōu)化算法求解樹網(wǎng)絡(luò)上的最優(yōu)成本:
15.3承諾服務(wù)模型的優(yōu)化算法求解樹網(wǎng)絡(luò)上的最優(yōu)成本:
15.3承諾服務(wù)模型的優(yōu)化算法基于分段線性函數(shù)近似的混合整數(shù)規(guī)劃算法:
15.3承諾服務(wù)模型的優(yōu)化算法基于分段線性函數(shù)近似的混合整數(shù)規(guī)劃算法:
15.3承諾服務(wù)模型的優(yōu)化算法基于分段線性函數(shù)近似的混合整數(shù)規(guī)劃算法:安全庫存量的分段線性近似結(jié)構(gòu)圖:15.3承諾服務(wù)模型的優(yōu)化算法基于分段線性函數(shù)近似的混合整數(shù)規(guī)劃算法:基于分段線性近似后的目標(biāo)函數(shù)帶入到承諾服務(wù)模型中,得到近似后的優(yōu)化模型::
現(xiàn)代庫存管理:模型、算法與Python實(shí)現(xiàn)第16章某食品企業(yè)Z的分銷網(wǎng)絡(luò)庫存優(yōu)化實(shí)戰(zhàn)16.1背景介紹企業(yè)Z是一家大型國際食品制造商:公司在中國建成了三級供應(yīng)網(wǎng)絡(luò),有一個(gè)工廠,南北兩個(gè)區(qū)域大倉,北方區(qū)域大倉下轄三個(gè)分銷中心,南方區(qū)域大倉下轄五個(gè)分銷中心,由分銷中心向各區(qū)域的客戶進(jìn)行履約目前公司供應(yīng)網(wǎng)絡(luò)的庫存管理主要采用單級的策略,每個(gè)倉采用覆蓋自身提前期的目標(biāo)庫存策略來管理庫存企業(yè)的發(fā)展趨勢和轉(zhuǎn)型需求:搭建了一套智慧供應(yīng)鏈管理系統(tǒng),將數(shù)據(jù)、算法和人工協(xié)作有機(jī)結(jié)合,加強(qiáng)供應(yīng)網(wǎng)絡(luò)的全局協(xié)同能力旨在研發(fā)一套分銷網(wǎng)絡(luò)的全局安全庫存優(yōu)化模型與算法,嵌入到其供應(yīng)鏈管理系統(tǒng)當(dāng)中16.1背景介紹挑選公司旗下的7個(gè)核心SKU,以這7個(gè)SKU的數(shù)據(jù)來探究如下兩個(gè)問題:從全局優(yōu)化的角度,這7個(gè)SKU的安全庫存應(yīng)該分別布局在哪些倉,以及相應(yīng)的量應(yīng)該是多少?全局優(yōu)化后的安全庫存策略相比于當(dāng)前策略,能否顯著降低總安全庫存成本?研究方法步驟:將Z公司的分銷網(wǎng)絡(luò)建立成一個(gè)樹網(wǎng)絡(luò)對網(wǎng)絡(luò)進(jìn)行分析并建立相應(yīng)的承諾服務(wù)模型利用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)的安全庫存策略并分析其價(jià)值16.2數(shù)據(jù)導(dǎo)入及預(yù)處理#導(dǎo)入網(wǎng)絡(luò)分析包
importnetworkxasnx
#導(dǎo)入數(shù)據(jù)分析包
importnumpyasnp
importpandasaspd
importmatplotlib.pyplotasplt
fromcollectionsimportdefaultdict
#導(dǎo)入第14章介紹過的幾個(gè)算法
fromchapter14_network_basicimportfind_predecessors_dict,find_successors_dict,\
cal_cum_lt,cal_demand_bound
importwarnings
warnings.filterwarnings('ignore')#定義數(shù)據(jù)路徑
data_dir=
'../../data/food/'
#讀取分銷網(wǎng)絡(luò)的邊數(shù)據(jù)
edge_df=pd.read_csv(data_dir+
'edge_data.csv')
#讀取各SKU的生產(chǎn)時(shí)間數(shù)據(jù)
production_time_df=pd.read_csv(data_dir+
'production_time_data.csv')
#讀取各節(jié)點(diǎn)的特征數(shù)據(jù)
feature_df=pd.read_csv(data_dir+
'feature_data.csv')
#讀取需求節(jié)點(diǎn)(DC)的需求數(shù)據(jù)
demand_df=pd.read_csv(data_dir+
'demand_data.csv')16.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集概況:edge_df表:分銷網(wǎng)絡(luò)的邊信息表’predecessor’:上游節(jié)點(diǎn)’successor’:下游節(jié)點(diǎn)’transport_time’:從上游節(jié)點(diǎn)到下游節(jié)點(diǎn)所需運(yùn)輸時(shí)間’quantity’:配比在分銷網(wǎng)絡(luò)中上下游只是運(yùn)輸傳送關(guān)系,配比均為1predecessorsuccessortransport_timequantity0F000RDC001311F000RDC002212RDC001DC004113RDC001DC008214RDC001DC010315RDC002DC003116RDC002DC005217RDC002DC007118RDC002DC006319RDC002DC0092116.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集概況:利用NetworkX,對Z企業(yè)的分銷網(wǎng)絡(luò)進(jìn)行可視化展示:16.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集概況:production_time_df表:7個(gè)SKU的生產(chǎn)時(shí)間sku_idproduction_time0SKU00031SKU00132SKU00213SKU00314SKU00425SKU00536SKU006316.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集概況:feature_df表:各個(gè)SKU在各節(jié)點(diǎn)(工廠,RDC和DC)的持貨成本’hc’:持貨成本’sla’:對客戶承諾的服務(wù)時(shí)間’unit_id’:一個(gè)節(jié)點(diǎn)與一個(gè)SKU的組合node_idsku_idhcslaunit_id0DC003SKU0000.841DC003_SKU0001DC004SKU0000.871DC004_SKU0002DC005SKU0000.881DC005_SKU0003DC006SKU0000.884DC006_SKU0004DC007SKU0000.894DC007_SKU00016.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集概況:demand_df表:從歷史銷量數(shù)據(jù)中統(tǒng)計(jì)得到的各SKU在各個(gè)需求節(jié)點(diǎn)(各個(gè)DC)的需求均值和標(biāo)準(zhǔn)差node_idsku_idmeanstdunit_id0DC003SKU000108.767138146.382985DC003_SKU0001DC003SKU00191.416757142.366810DC003_SKU0012DC003SKU002129.607221209.291639DC003_SKU0023DC003SKU00397.410929174.465898DC003_SKU0034DC003SKU00492.281828139.159005DC003_SKU00416.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集預(yù)處理:以SKU’SKU000’為例將’SKU000’的相關(guān)數(shù)據(jù)提取出來,并進(jìn)行預(yù)處理,計(jì)算出每個(gè)節(jié)點(diǎn)的累計(jì)提前期計(jì)算每個(gè)節(jié)點(diǎn)覆蓋時(shí)間的需求上界及安全庫存量,計(jì)算周期服務(wù)水平為0.95對應(yīng)的需求上界將后續(xù)要反復(fù)使用的數(shù)據(jù)轉(zhuǎn)換成字典格式數(shù)據(jù)集預(yù)處理代碼如下:sku=
'SKU000'
#將sku對應(yīng)的需求信息提取出來
sku_demand_df=demand_df[demand_df['sku_id']==sku]
#分銷網(wǎng)絡(luò)的配比均為1
qty_dict={(pred,succ):qforpred,succ,qin
edge_df[['predecessor','successor','quantity']].values}
16.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集預(yù)處理代碼:#根據(jù)sku對應(yīng)的生產(chǎn)加工時(shí)間,計(jì)算每個(gè)節(jié)點(diǎn)的累計(jì)提前期
sku_production_time=int(production_time_df[
production_time_df['sku_id']==sku][
'production_time'])
lt_dict=dict(zip(edge_df['successor'],edge_df['transport_time']))
lt_dict.update({'F000':sku_production_time})
lt_df=pd.DataFrame.from_dict(
lt_dict,orient='index').reset_index().rename(
columns={'index':'node_id',0:'lt'})
cum_lt_dict=cal_cum_lt(edge_df[['predecessor','successor']].values,lt_dict)
cum_lt_df=pd.DataFrame.from_dict(
cum_lt_dict,orient='index').reset_index().rename(
columns={'index':'node_id',0:'cum_lt'})
#將sku對應(yīng)的節(jié)點(diǎn)屬性表讀取出來,并將提前期與累計(jì)提前期合并到一張表上,方便分析
sku_node_df=feature_df[feature_df['sku_id']==sku]
sku_node_df=sku_node_df.merge(lt_df,on='node_id',how='left')
sku_node_df=sku_node_df.merge(cum_lt_df,on='node_id',how='left')
print(sku_node_df)16.2數(shù)據(jù)導(dǎo)入及預(yù)處理數(shù)據(jù)集預(yù)處理代碼:#累計(jì)提前期
cum_lt_dict=dict(zip(sku_node_df['node_id'],sku_node_df['cum_lt']))
#提前期
lt_dict=dict(zip(sku_node_df['node_id'],sku_node_df['lt']))
#每個(gè)節(jié)點(diǎn)對應(yīng)覆蓋時(shí)間的安全庫存量
ss_ct_dict={(node,time):ssfornode,time,ssin
sku_demand_bound_df[['node_id','time','ss_qty']].values}
#持貨成本
hc_dict=dict(zip(sku_node_df['node_id'],sku_node_df['hc']))
#sla
sla_df=sku_node_df[sku_node_df['sla'].notna()]
sla_dict=dict(zip(sla_df['node_id'],sla_df['sla']))#將sku對應(yīng)的節(jié)點(diǎn)屬性表讀取出來,并將提前期與累計(jì)提前期合并到一張表上,方便分析
sku_node_df=feature_df[feature_df['sku_id']==sku]
sku_node_df=sku_node_df.merge(lt_df,on='node_id',how='left')
sku_node_df=sku_node_df.merge(cum_lt_df,on='node_id',how='left')
print(sku_node_df)16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略對網(wǎng)絡(luò)中的節(jié)點(diǎn)進(jìn)行排序:找到滿足除了根節(jié)點(diǎn)之外,每個(gè)節(jié)點(diǎn)至多有一個(gè)相鄰節(jié)點(diǎn)在該節(jié)點(diǎn)之后的序列defsort(graph):
#將圖轉(zhuǎn)化成無向圖
un_di_graph=graph.to_undirected()
#計(jì)算圖中節(jié)點(diǎn)總數(shù)
nodes_num=len(un_di_graph.nodes())
sorted_list=[]
#如果還有節(jié)點(diǎn)未被加入排序,則繼續(xù)
whilelen(sorted_list)<nodes_num:
#調(diào)用NetworkX計(jì)算節(jié)點(diǎn)的度數(shù)
degree_dict={node:vfornode,vinun_di_graph.degree()}
#將最多只有一個(gè)節(jié)點(diǎn)與其相鄰的節(jié)點(diǎn)加入排序
border_nodes=[nodefornode,degreeindegree_dict.items()if
degree<=
1]
sorted_list.extend(border_nodes)
#從圖中移除已排序的節(jié)點(diǎn)
un_di_graph.remove_nodes_from(border_nodes)
returnsorted_list
sorted_list=sort(graph)
print(sorted_list)16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
defget_parent_dict(graph,sorted_list):
un_di_graph=graph.to_undirected()
#找到每個(gè)節(jié)點(diǎn)相鄰的節(jié)點(diǎn)集合
neighbors_dict={node:list(un_di_graph.neighbors(node))
fornodeinun_di_graph.nodes()}
#對節(jié)點(diǎn)進(jìn)行標(biāo)號,方便查詢排序先后
labeled_dict={node:ifori,nodeinenumerate(sorted_list)}
parent_dict={}
fornodeinsorted_list:
#對于每個(gè)節(jié)點(diǎn),用c表示在該節(jié)點(diǎn)之后的相鄰節(jié)點(diǎn)
c=
0
forneighborinneighbors_dict[node]:
iflabeled_dict[neighbor]>labeled_dict[node]:
c+=
1
#找到在該節(jié)點(diǎn)之后的相鄰節(jié)點(diǎn)后,將其記錄
parent_dict[node]=neighbor
#如果超過1,說明排序有誤
ifc>
1:
raise
Exception('wronglabel')
returnparent_dict
parent_dict=get_parent_dict(graph,sorted_list)16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略判斷每個(gè)節(jié)點(diǎn)應(yīng)該使用哪一類成本函數(shù):定義函數(shù)classif_node用于判斷節(jié)點(diǎn)應(yīng)當(dāng)使用哪種成本函數(shù),并記錄每個(gè)節(jié)點(diǎn)的子樹信息defclassify_node(graph,edge_df,sorted_list):
#定義上下游字典
pred_dict=find_predecessors_dict(
edges=edge_df[['predecessor','successor']].values)
succ_dict=find_successors_dict(
edges=edge_df[['predecessor','successor']].values)
un_di_graph=graph.to_undirected()
neighbors_dict={node:list(un_di_graph.neighbors(node))
fornodeinun_di_graph.nodes()}
labeled_dict={node:ifori,nodeinenumerate(sorted_list)}
to_eva_f_list=[]
to_eva_g_list=[]
fornodeinsorted_list:
forneighborinneighbors_dict[node]:
iflabeled_dict[neighbor]>labeled_dict[node]:
ifneighborinsucc_dict[node]:
#如果p(j)在節(jié)點(diǎn)j下游,則將節(jié)點(diǎn)標(biāo)記為使用f成本函數(shù)
to_eva_f_list.append(node)
16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略判斷每個(gè)節(jié)點(diǎn)應(yīng)該使用哪一類成本函數(shù):定義函數(shù)classif_node用于判斷節(jié)點(diǎn)應(yīng)當(dāng)使用哪種成本函數(shù),并記錄每個(gè)節(jié)點(diǎn)的子樹信息elifneighborinpred_dict[node]:
#如果p(j)在節(jié)點(diǎn)j上游,則將節(jié)點(diǎn)標(biāo)記為使用g成本函數(shù)
to_eva_g_list.append(node)
else:
raise
Exception('wrong')
#記錄子樹信息
sub_pred_dict={node:[pforpinpred_dict[node]
iflabeled_dict[p]<labeled_dict[node]]
fornodeinsorted_list}
sub_succ_dict={node:[sforsinsucc_dict[node]
iflabeled_dict[s]<labeled_dict[node]]
fornodeinsorted_list}
returnto_eva_f_list,to_eva_g_list,sub_pred_dict,sub_succ_dict
to_eva_f_list,to_eva_g_list,sub_pred_dict,sub_succ_dict=classify_node(
graph,edge_df,sorted_list)16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略數(shù)據(jù)準(zhǔn)備并初始化動(dòng)態(tài)規(guī)劃表:代碼如下S_index={
node:np.arange(0,min(sla_dict.get(node,9999),cum_lt_dict[node])+
1)
fornodeinsorted_list}
SI_index={node:np.arange(0,cum_lt_dict[node]-lt_dict[node]+
1)
fornodeinsorted_list}
CT_index={node:np.arange(0,cum_lt_dict[node]+
1)fornodeinsorted_list}on_hand_cost={(node,CT):hc_dict[node]*ss_ct_dict[node,CT]
fornodeinsorted_listforCTinCT_index[node]}#cost_record記錄出每個(gè)節(jié)點(diǎn),每種策略組合(S,SI)下的成本
cost_record=defaultdict(dict)
#f_cost記錄在給定S的情況下,p(j)在節(jié)點(diǎn)下游的節(jié)點(diǎn)的子樹上的最小庫存成本
f_cost={(node,S):-float('inf')fornodeinto_eva_f_listforSin
S_index[node]}
#f_argmin記錄f_cost的最小庫存成本所對應(yīng)的SI
f_argmin={(node,S):-float('inf')fornodeinto_eva_f_listforSin
S_index[node]}
#g_cost記錄在給定SI的情況下,p(j)在節(jié)點(diǎn)上游的節(jié)點(diǎn)的子樹上的最小庫存成本
g_cost={(node,SI):-float('inf')fornodeinto_eva_g_listforSIin
SI_index[node]}
#g_argmin記錄g_cost的最小庫存成本所對應(yīng)的S
g_argmin={(node,SI):-float('inf')fornodeinto_eva_g_listforSIin
SI_index[node]}16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
defevaluate_f(node,S):
#測試全部可能的SI
to_test_SI=np.arange(max(0,S-lt_dict[node]),
cum_lt_dict[node]-lt_dict[node]+
1)
forSIinto_test_SI:
#計(jì)算當(dāng)前策略組合下的覆蓋時(shí)間
CT=SI+lt_dict[node]-S
#計(jì)算當(dāng)前策略組合下的庫存成本
#首先是自身庫存成本
cost_record[node][S,SI]=on_hand_cost[node,CT]
#如果節(jié)點(diǎn)有上游節(jié)點(diǎn),那么需要加總上游節(jié)點(diǎn)子樹對應(yīng)的成本
iflen(sub_pred_dict[node])>
0:
forpredinsub_pred_dict[node]:
cost_record[node][S,SI]+=min(
[f_cost[pred,s]forsinS_index[pred]ifs<=SI])
#如果節(jié)點(diǎn)有下游節(jié)點(diǎn),那么需要加總下游節(jié)點(diǎn)子樹對應(yīng)的成本
iflen(sub_succ_dict[node])>
0:
forsuccinsub_succ_dict[node]:
cost_record[node][S,SI]+=min(
[g_cost[succ,si]forsiinSI_index[succ]ifsi>=S])
#找到給定S情況下的最優(yōu)的SI
cost_SI_dict={si:cost_record[node][S,si]forsiinto_test_SI}
best_SI=min(cost_SI_dict,key=cost_SI_dict.get)
#將成本記錄到f_cost,將最優(yōu)的SI記錄到f_argmin
f_cost[node,S]=cost_SI_dict[best_SI]
f_argmin[node,S]=best_SI16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
defevaluate_g(node,SI):
#測試全部可能的S
to_test_S=np.arange(0,min(sla_dict.get(node,9999),
SI+lt_dict[node])+
1)
forSinto_test_S:
#計(jì)算當(dāng)前策略組合下的覆蓋時(shí)間
CT=SI+lt_dict[node]-S
#計(jì)算當(dāng)前策略組合下的庫存成本
#首先是自身庫存成本
cost_record[node][S,SI]=on_hand_cost[node,CT]
#如果節(jié)點(diǎn)有上游節(jié)點(diǎn),那么需要加總上游節(jié)點(diǎn)子樹對應(yīng)的成本
iflen(sub_pred_dict[node])>
0:
forpredinsub_pred_dict[node]:
cost_record[node][S,SI]+=min(
[f_cost[pred,s]forsinS_index[pred]ifs<=SI])
#如果節(jié)點(diǎn)有下游節(jié)點(diǎn),那么需要加總下游節(jié)點(diǎn)子樹對應(yīng)的成本
iflen(sub_succ_dict[node])>
0:
forsuccinsub_succ_dict[node]:
cost_record[node][S,SI]+=min(
[g_cost[succ,si]forsiinSI_index[succ]ifsi>=S])
#找到給定SI情況下的最優(yōu)的S
cost_S_dict={s:cost_record[node][s,SI]forsinto_test_S}
best_S=min(cost_S_dict,key=cost_S_dict.get)
#將成本記錄到g_cost,將最優(yōu)的S記錄到g_argmin
g_cost[node,SI]=cost_S_dict[best_S]
g_argmin[node,SI]=best_S16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略根據(jù)排序,遍歷計(jì)算最優(yōu)成本#遍歷節(jié)點(diǎn),除了最后一個(gè)節(jié)點(diǎn)外
fornodeinsorted_list[:-1]:
#如果p(j)在節(jié)點(diǎn)下游,則對于所有可能的S,計(jì)算f函數(shù)
ifnodeinto_eva_f_list:
forSinS_index[node]:
evaluate_f(node,S)
#如果p(j)在節(jié)點(diǎn)上游,則對于所有可能的S,計(jì)算g函數(shù)
ifnodeinto_eva_g_list:
forSIinSI_index[node]:
evaluate_g(node,SI)
#對于排序中最后一個(gè)節(jié)點(diǎn),對于所有可能的SI,計(jì)算g函數(shù)
end_node=sorted_list[-1]
forSIinSI_index[end_node]:
evaluate_g(end_node,SI)16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略
end_g_cost_dict={si:g_cost[end_node,si]forsiinSI_index[end_node]}
end_node_SI=min(end_g_cost_dict,key=end_g_cost_dict.get)
end_node_S=g_argmin[end_node,end_node_SI]16.3應(yīng)用動(dòng)態(tài)規(guī)劃算法求解最優(yōu)策略使用回溯法找到最優(yōu)策略:#定義最優(yōu)策略字典
opt_sol={'S':{},'SI':{},'CT':{}}
#將最后一個(gè)節(jié)點(diǎn)的最優(yōu)值存貯在最優(yōu)策略中
opt_sol['SI'][end_node]=end_node_SI
opt_sol['S'][end_node]=end_no
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 課題申報(bào)參考:金代民族交往交流交融的考古學(xué)觀察
- 課題申報(bào)參考:減稅降費(fèi)政策實(shí)施效果評估和策略優(yōu)化研究
- 二零二五版環(huán)保項(xiàng)目臨時(shí)工勞動(dòng)合同4篇
- 基于2025年度計(jì)劃的環(huán)保項(xiàng)目合作協(xié)議3篇
- 2025年智能水電表更換與數(shù)據(jù)采集服務(wù)合同4篇
- 2025年度個(gè)人退房協(xié)議書范本(適用于商業(yè)地產(chǎn))4篇
- 二零二五版建筑工程公司資質(zhì)借用與施工監(jiān)督服務(wù)協(xié)議3篇
- 二零二五年度商業(yè)綜合體場地租賃合同范本6篇
- 專利授權(quán)事務(wù)全權(quán)委托合同書版B版
- 2025年度排水溝施工安全協(xié)議書范本
- GB/T 45107-2024表土剝離及其再利用技術(shù)要求
- 2024-2025學(xué)年八年級上學(xué)期1月期末物理試題(含答案)
- 商場電氣設(shè)備維護(hù)勞務(wù)合同
- 2023年國家公務(wù)員錄用考試《行測》真題(行政執(zhí)法)及答案解析
- 2024智慧醫(yī)療數(shù)據(jù)字典標(biāo)準(zhǔn)值域代碼
- 年產(chǎn)12萬噸裝配式智能鋼結(jié)構(gòu)項(xiàng)目可行性研究報(bào)告模板-立項(xiàng)備案
- 【獨(dú)家揭秘】2024年企業(yè)微信年費(fèi)全解析:9大行業(yè)收費(fèi)標(biāo)準(zhǔn)一覽
- 醫(yī)療器械經(jīng)銷商會議
- 《±1100kV特高壓直流換流變壓器使用技術(shù)條件》
- 1-1 擁抱夢想:就這樣埋下一顆種子【2022中考作文最熱8主題押題24道 構(gòu)思點(diǎn)撥+范文點(diǎn)評】
- 《風(fēng)電場項(xiàng)目經(jīng)濟(jì)評價(jià)規(guī)范》(NB-T 31085-2016)
評論
0/150
提交評論