コア

SCMOPTは様々なシステム(モジュール)を有機的に結合したものである.ここでは,様々なモジュールで使用する共通部品を定義する.

グラフクラス SCMGraph

サプライ・チェインのためのグラフクラス

SCMGraphクラスは,networkXの有向グラフクラスDiGraphから派生したものであり,以下のメソッドが追加されている.

  • random_directed_tree(n=1, seed=None): ランダムな有向木を生成する.引数は点数n(既定値1)と擬似乱数の種seed(既定値None).
  • layered_network(num_in_layer=None, p=0.5, seed=None): ランダムな層型の有向グラフを生成する. 引数num_in_layerは,各層内の点数を入れたリストで既定値は[1,1],pは枝の発生確率で既定値は0.5,seedは擬似乱数の種である.
  • layout(): 有向グラフを描画する際の座標を返す関数.返値は点の名称をキーとし,点のx,y座標を値とした辞書.
  • down_order(): 閉路を含まない有向グラフに対して,供給地点側から需要地点側の順番で点を返すジェネレータ関数.
  • up_order(): 閉路を含まない有向グラフに対して,需要地点側から供給地点側の順番で点を返すジェネレータ関数.
  • dp_order(): 有向木に対して,葉から順番に点を生成するジェネレータ関数. 安全在庫配置問題に対する動的最適化で用いる.
  • bfs(start): 点startを開始点として,広がり優先探索で点を生成するジェネレータ関数.
  • find_ancestors(): 各点から到達可能な点の集合(自分自身を含む)を保持するリスト.点の順序はup_orderとする.

source

SCMGraph

 SCMGraph (incoming_graph_data=None, **attr)

SCMGraph is a class of directed graph with edge weight that can be any object. I just use the functions such as in_degree, out_degree, successors, predecessors, in_edges_iter, out_edges_iter. So it is convertible to any graph class that can access the adjacent nodes more quickly.

G = SCMGraph()
G.layered_network(num_in_layer=[3, 2, 3], p=0.4, seed=123)
pos = G.layout()
nx.draw(G, pos=pos, with_labels=True, node_color="Yellow")

温室化ガス排出量

生産部門では,電力,蒸気に対して原単位が設定されている.

廃棄に対しても,物別に原単位が設定されている.

調達に対しては,調達費用に対して原単位が設定されている.

輸送部門:

輸送手段 \(CO_2\) (gCO2/トンキロ)
鉄道 22
船舶 39
航空 1490

トラックに対しては,燃料使用量を以下の式で計算してから算出する.

  • y:輸送トンキロ当たり燃料使用量(l)
  • x:積載率(%)
  • z:最大積載量(kg)

ガソリン車: ln y=2.67-0.927 ln (x/100)-0.648 ln z

ディーゼル車: ln y=2.71-0.812 ln (x/100)-0.654 ln z

ただし,積載率10%未満の場合は、積載率10%の時の値を用いる.なお、表記「ln」は自然対数(eを底とする対数)

\(CO_2\)排出量は,上で求めた燃料使用量に以下の値を乗じて計算する.

 単位発熱量(GJ/kl)×排出係数(tCO2/GJ) = 34.6 × 0.0183 = 2.322 (tCO2/kl)


source

co2

 co2 (capacity, rate=0.5, diesel=False)

引数: - capacity:積載重量(kg) - rate: 積載率 (0<rate<=1.0) - diesel: ディーゼル車の場合 True, ガソリン車の場合 False 返値: - fuel: トンキロあたりの燃料使用量(リットル) - co2: CO2排出量(g)

日付時刻もしくは時刻型の差を計算して,秒を返す関数 time_delta

引数:

  • finish: 終了時刻を表す日付時刻型(もしくは時刻型)
  • start: 開始時刻を表す日付時刻型(もしくは時刻型)

返り値:

  • 時刻の差(秒)

source

time_delta

 time_delta (finish, start)

日付時刻もしくは時刻型の差を計算して,秒を返す関数

time_deltaの使用例

print( time_delta( dt.datetime(2020,1,2,10,0), dt.datetime(2020,1,1,0,0)) )
print( time_delta( dt.time(10,0), dt.time(11,0)) )
print( time_delta( dt.time(12,0), dt.time(6,0)) )
122400
-3600
21600

日付時刻(もしくは時刻)型に指定した時間(秒)を加えた時刻を返す関数 add_seconds

引数 - start: 開始時刻を表す日付時刻型(もしくは時刻型) - seconds: 時間(秒)

返値: - 指定した時間だけすすめた(日付)時刻


source

add_seconds

 add_seconds (start, seconds)

add_secondsの使用例

print( add_seconds( dt.datetime(2020,1,1,10,0), 1000) )
print( add_seconds( dt.time(10,0), 1000) )
2020-01-01 10:16
10:16

地点(顧客)間の距離と移動時間の計算関数 compute_durations

OSRMを必要とする.

引数: - cust_df: 顧客データフレーム(名称と緯度・経度情報をもつデータフレーム) - plnt_df: 工場データフレーム(オプション;既定値 None) - toll: 有料道路が使用可のときTrue(既定値 True) - ferry: フェリーが使用可のときTrue(既定値 True) (TODO: OSRMの前処理時に,car.luaファイルを以下を修正する必要がある.)

excludable = Sequence {
        Set {'toll'},
        Set {'motorway'},
        Set {'ferry'}, 
        Set {'ferry', 'toll'})
    },
  • host: ホスト名;既定値は “localhost”

返値: - durations: 地点間の移動時間(計算に失敗した場合には大きな数字が入っている.) - distances: 地点間の道路距離(計算に失敗した場合には大きな数字が入っている.) - node_df: 点のデータフレーム(顧客もしくは顧客と工場を結合したもの)


source

compute_durations

 compute_durations (cust_df, plnt_df=None, toll=True, host='localhost')

compute_durations関数の使用例

cust_df = pd.read_csv(folder+"cust.csv")
durations,  distances, node_df = compute_durations(cust_df, toll=False, host=host)
print(sum(durations[0]))
3730084.0

地点間の距離と移動時間のデータフレームを生成する関数 make_time_df

引数: - node_df: 点のデータフレーム(顧客もしくは顧客と工場を結合したもの) - durations: 地点間の移動時間(計算に失敗した場合には大きな数字が入っている.) - distances: 地点間の道路距離(計算に失敗した場合には大きな数字が入っている.)

返値: - time_df: 発地,着地,移動時間(秒),道路距離(m)を入れたデータフレーム


source

make_time_df

 make_time_df (node_df, durations, distances)

make_time_df関数の使用例

time_df =  make_time_df(node_df, durations, distances)
time_df.head()
from_node from_name to_node to_name time distance
0 0 札幌市 0 札幌市 0 0
1 0 札幌市 1 青森市 23883 425746
2 0 札幌市 2 盛岡市 28264 545192
3 0 札幌市 3 仙台市 38347 754593
4 0 札幌市 4 秋田市 31425 608789

time_dfからdurationsとdistancesを生成する関数 make_durations

上で作成した time_df から,移動時間と移動距離を生成する.

引数: - time_df: 移動時間と道路距離を保持するデータフレーム

返値: - durations: 移動時間行列 - distances: 道路距離行列


source

make_durations

 make_durations (time_df)

make_durations関数の使用例

time_df = pd.read_csv(folder + "melos/time.csv")
durations, distances = make_durations(time_df)
distances
array([[      0.,  427015.,  546453., ..., 2247148., 2288685., 3080358.],
       [ 426987.,       0.,  183876., ..., 1815653., 1857189., 2648863.],
       [ 546501.,  183838.,       0., ..., 1736609., 1778145., 2569819.],
       ...,
       [2247483., 1814532., 1736893., ...,       0.,  132654.,  924327.],
       [2293427., 1860476., 1782837., ...,  134850.,       0.,  795782.],
       [3083057., 2650105., 2572466., ...,  924479.,  795964.,       0.]])