Dashを用いた配送計画のGUI

実行環境

以下から実行すればDashのGUIが動く。

フォルダ名をfolderで指定して、その直下に customer.csv, vehicle.csv, cost.csvを置く。

cost.csvがない場合には、直線距離で代用

GUIを用いないテストは、

obj, model = solve(max_cpu = 1)
print(obj)
check_feasibility(model)
save_route(model)

とする。

実行環境は JupyterLab (Mac). Jupyter Notebook (Windows)、もしくは Dashを用いて(ローカル)サーバーで実行

https://github.com/plotly/jupyterlab-dash (Mac)

https://pypi.org/project/jupyter-plotly-dash/ (Windows)

実行には、以下のパッケージが必要(METRO以外は全てpipでインストール可能)

JupyterLabを使用している場合には、コンソールで以下を実行(npmを入れていない場合には、それも入れる。)

jupyter labextension install @jupyterlab/plotly-extension

そこにあるPythonのファイル群と実行ファイルvrp_d_1m1_t-Macはダウンロード後に

chmod +x vrp_d_1m1_t-Mac

と実行パーミッションを追加

地図の利用にはmapboxのtokenが必要 https://www.mapbox.com/

Django上でDashを動かしたい場合には、 https://pypi.org/project/django-plotly-dash/

必要なパッケージのインポート

準備

データをcsvファイルから読み込み、準備をする。

distance関数

distance[source]

distance(origin, destination)

2地点間の直線距離を計算するための関数

make_cost[source]

make_cost(CustDic, cost_per_km=100.0, km_per_hour=40.0)

費用データフレームを生成する関数

cost_df = make_cost(CustDic, cost_per_km = 100., km_per_hour = 40.)
cost_df.to_csv("cost.csv")  

prepare_data[source]

prepare_data(cust_df, vehicle_df)

準備を行う関数

# 準備
cust_df = pd.read_csv("customer.csv", index_col=0,
                   dtype={"zipcode": str})
#cust_df = pd.read_csv(folder+"customer.csv", index_col=0,
#                   dtype={"zipcode": str})
vehicle_df = pd.read_csv("vehicle.csv", index_col=0)
# 費用テーブルがフォルダ内にある場合には、cost_flagをTrueにしておく。
try:
    cost_df = pd.read_csv(folder+"cost.csv", index_col=0)
    cost_flag = True
except:
    cost_flag = False
CustDic, VehiDic, start, early, late, early_vehicle, late_vehicle, ratio, width = prepare_data(cust_df, vehicle_df)

time_shift関数

トラックの発時刻を、時間枠を破らない範囲で遅らせる関数

time_shift[source]

time_shift(model, CustDic, VehiDic, start, early_vehicle, late_vehicle)

各トラックの発時刻を時間枠を破らない限りなるべく後ろにずらす関数

solve関数

最適化を実行し、目的関数値とモデルオブジェクトを返す。

solve[source]

solve(CustDic, VehiDic, cust_df, early, late, early_vehicle, late_vehicle, start, cost_df=None, max_cpu=10, tw_penalty='inf')

最適化を実行する関数 Arguments: max_cpu:最大計算時間 tw_penelty: 時間枠逸脱のペナルティ distance_weight ...

solveの実行例

obj, model = solve(CustDic, VehiDic, cust_df,  early, late, early_vehicle, late_vehicle, start, cost_df, max_cpu=10, tw_penalty="inf")
print(obj)
Feasbiel solution is not found
52010999.92

lower_bound関数

ビンパッキング問題を解くことによる下界計算の関数

lower_bound[source]

lower_bound(cust_df, vehicle_df)

ビンパッキング問題を解くことによるトラック台数の下界の算出

顧客データフレームcustから、重量(容量)、積み下ろし量、積み込み量の4種類の下界を計算する。 トラックの積載量上限(重量、容量)の平均値をビンのサイズとし、アイテムのサイズを積み下ろし(積み込み)量とする。

返値は、4種類の下界のリスト(順に、重量・積み込み、容量・積み込み、重量・積み下ろし、容量・積み下ろし)

lower_boundの使用例

lower_bound(cust_df, vehicle_df)
[3, 9, 1, 1]

check_feasibility関数

需要量(現在は、重量のみ)の実行可能性の判定を行う。

check_feasibility[source]

check_feasibility(model, VehiDic)

実行可能性の判定関数 トラックの辞書VehiDicとモデルオブジェクトに格納されているルート・顧客情報を用いる。 重量のみで判定し、積載量を超過している場合には、出力する。

check_feasibilityの使用例

Falseが返れば実行不能、Trueが返れば実行可能。

check_feasibility(model, VehiDic)
True

make_route関数

ルートのデータフレームを生成する。

make_route_df[source]

make_route_df(v, model, CustDic, start)

モデルmodelとトラック名(IDの文字列)を与えると、ルートのデータフレームを返す関数

make_route_df("0", model, CustDic, start)
index name early late arrival departure distance weight(1) weight(2) maxVehicle
0 0 0: 早稲田工務店(depot) 08:00:00 21:20:00 - 15:22:52 0 320 -0 -
1 1 9: デザイナーズコレチオーネ 原宿店 1999-09-28 10:20:00 1999-09-28 15:30:00 15:30:00 15:54:00 7.12 -320 6.6 11
2 2 0: 早稲田工務店 (return) 08:00:00 21:20:00 16:01:07 - 14.25 0 0 -

save_route関数

全てのルートのデータを保存

save_route[source]

save_route(model, CustDic, VehiDic)

全てのルートのデータフレームを生成し、csvファイルに保管する関数

save_route(model, CustDic, VehiDic)

make_time_window_fig関数

時間枠やビンパッキング問題の下界から、時刻ごとの必要なトラック数を可視化する関数

返値はPlotlyの図オブジェクト

make_time_window_fig[source]

make_time_window_fig(cust_df, early, late, vehicle_df, early_vehicle, late_vehicle)

時間枠やビンパッキング問題の下界から、時刻ごとの必要なトラック数を可視化する関数 返値はPlotlyの図オブジェクト

fig_showの使用例

fig = make_time_window_fig(cust_df, early, late, vehicle_df, early_vehicle, late_vehicle)
#fig.show();
#plotly.offline.plot(fig);
Image("../figure/make_time_window.png")

make_histgram関数

make_histgram[source]

make_histgram(cust_df)

顧客の重量と容量のヒストグラムを生成する関数 負の値は積み込み量、正の値は積み降ろし量を表す。

make_histgramの使用例

fig = make_histgram(cust_df)
#fig.show();
#plotly.offline.plot(fig);
Image("../figure/make_histgram.png")

make_fig関数

地図上に全てのルートを描画する関数。返値は図オブジェクト。

make_fig[source]

make_fig(model, cust_df, CustDic, ratio, width)

ルートを地図上に描画する関数

make_figの使用例

fig = make_fig(model, cust_df, CustDic, ratio, width)
#plotly.offline.plot(fig);
Image("../figure/make_fig.png")

make_fig_route関数

1つのルート(データフレームで与える)を地図上に描画する関数

make_fig_route[source]

make_fig_route(route_df, CustDic, ratio, width)

1つのルート(データフレームで与える)を地図上に描画する関数

route_df = make_route_df("0", model, CustDic,start)
fig = make_fig_route(route_df, CustDic, ratio, width)
#plotly.offline.plot(fig);
Image("../figure/make_fig_route.png")