simmer
ドローンによるワクチン配送のシミュレーションを構築しています。シミュレーション部分までの疑似コードは次のとおりです。
- ワクチンが必要な場所を表す、地理内の N 個の「需要地点」を生成します。データフレームにします。到着時間をデータフレーム列として追加します。優先度列を追加 - 早い者勝ち。
- kmeans クラスタリングを使用して、地理上の K 個のドローン ステーションの場所を見つける
- 各ドローン ステーションから各需要地点までの移動時間を表す N x K 行列を生成します
シミュレーションでは、ワクチンの配達は到着、ドローンはリソース (サーバー容量 1、無限のキュー容量) です。シミュレーションでこのリソース選択ロジックを使用したい:
- 到着したら、どのドローンが利用可能かを判断します。それらの中で、移動時間マトリックスによって決定される最短の移動時間を持つドローンを選択します。
- すべてのドローンが現在使用されている場合、新しい到着者は共通のキューに入れられます。ドローンが利用可能になるたびに、共通キューへの到着が優先され、キューでの最も古い到着が最優先されます。これは、最寄りのドローン ステーションからワクチンが配達されないことを意味する場合があります。
seize_selected
選択したドローンが到着したら、timeout
移動時間、次にrelease_selected
そのドローン。
simmer パッケージ (または代替) でリソースをディスパッチするときにルーティング ロジックを使用するのロジックを適応させようとしていますが、期待どおりに機能しません。
どんな助けでも大歓迎です。ここで私にとって本当にトリッキーな部分は、到着を共通のキューに入れ、利用可能な最速のドローンを選択することです。
私の現在のシミュレーションコードは次のとおりです。
delivery_env <- simmer()
delivery_traj <- trajectory("delivery") %>%
set_attribute(c("min_drone_index", "min_drone_delay"), function() {
# find available resources
server_count <- numeric(drone_count)
for (i in 1:length(server_count)){server_count[i] <- get_server_count(delivery_env, paste0("drone", i)) }
#find index of minimum travel time, inclusive of server_count
#since the capacity of each drone is 1, we want to find the drones
#that have server_count == 1 and set them "very very far away" from the deliverypoint
#so the ranking system puts them last
#identify row of traveltime_matrix that corresponds to the delivery point
#in traveltime_matrix, rows are vaccines, columns are drones
k <- get_attribute(delivery_env, "arrival_index_index1")
traveltime_vec <- traveltime_matrix[k, ]
#make the currently-occupied drones, "very very far away"
traveltime_vec[which(server_count==1)] <- traveltime_vec[which(server_count==1)]+ 9999999999
#identify a single value for the minimum distance - more than 1 drone index may be the minimum
#identify closest available. randomly sample if more than 1 is closest
k <- which.min(traveltime_vec)
min_drone_index <- sample(k,1)
#the drone (resource) is seized for 2x the one-way travel time, plus time on the ground.
min_drone_delay <- 2*traveltime_vec[min_drone_index] + delivery_ontheground_time_minutes
# take the nearest available resource.
return(c(min_drone_index, min_drone_delay))
}) %>%
simmer::select(function() paste0("drone", get_attribute(delivery_env, "min_drone_index"))) %>%
seize_selected() %>%
timeout_from_attribute("min_drone_delay") %>%
release_selected() %>%
#release("drone") %>%
log_("Delivery Finished")
delivery_env <-
simmer("drone") %>%
add_resource(name= paste0("drone",seq(1,drone_count,1)), capacity=1) %>%
add_dataframe(name_prefix='delivery',trajectory = delivery_traj, data=pointsdf,mon=2,batch=50,col_priority="priority",
col_time = "absolute_time", time ="absolute",col_attributes = c("longitude","latitude","arrival_index_index1","arrival_index_index0"))
sim_out <- delivery_env %>% run()