#hokudaihitachi20191a. [hokudai_hitachi2019_1_a]Problem A
[hokudai_hitachi2019_1_a]Problem A
問題概要
- 問題のねらい: 本プログラミングコンテストは、買い物支援(配達)サービスの最適化をテーマとしている。本サービスを利用する顧客はそれぞれ異なる品物をお店に注文する(顧客からの注文には固有のが割り振られる)。お店が利用できる車は一台のため、配達中に注文された商品については、お店に戻ってその商品を車に積んでから、顧客のもと商品を届けなければならない。
- 得点: 最適化の目的は、制限時間 の間に「できるだけ多くの」商品を「できるだけ早く」顧客に届けることである。なお、注文は時刻 から時刻 の間に発生する可能性がある。
- 諸制約: 本コンテストでは、車に積むことのできる商品の数に制限はない。ただし、ある注文に対応する商品をお店まで取りに行き、車に積めるのは、その商品が注文された以降の時刻に限る ことに注意せよ。
- 問題 A: この問題においては、注文が発生する時刻及び、注文がどの頂点で発生したかなど、注文に関する情報が事前に与えられる。
- 問題 B: この問題においては、事前に注文に関する情報は与えられず、全ての注文は配達中にオンラインで発生する。
時間・空間について
- 時間: は を満たす整数時刻であるとし、各 において、あなたは時刻 から にかけての行動を決定しなければならない。
- 空間: 単純かつ無向であるグラフ を考える。ここで は頂点集合、 は辺集合である。車の移動・注文の発生はすべて、このグラフ内で起こるものとする。
- 店および顧客の位置: それぞれの頂点 は から までで番号付けられている。頂点 は店がある頂点であるとし、 は顧客がいる頂点であるとする。
- 道路: それぞれの辺 は、頂点 と頂点 を直接結ぶ道路であるとする。辺には整数距離が定められており、これを と表記する。
- グラフの生成方法: 地図を表すグラフは、後述のアルゴリズムによってランダムに生成される。
グラフ の生成について すべてのテストケースにおいて、与えられるグラフ は以下のアルゴリズムによって生成される。
- 入力:, , (最大次数)
- 頂点(店舗+顧客)の生成方法:
- はじめに、 を満たす最大の非負整数 を見つける(ただし、 も非負整数とする)。
- 次に、 を満たす座標平面上の全ての格子点に対して、点 をプロットする。
- 各点の座標を とずらす。ここで は dx, dy \\in \[0, 1\] を満たす一様ランダムな実数である。つまり、移動後の座標は(x + dx, y + dy)\\in \[0,R\] \\times \[0,R\]を満たす。
- 残りの 個の点それぞれについて、座標 ( の一様ランダムな実数) を定めてプロットする。
- 各点に対して、からまでの番号をランダムに割り振る。番号を割り振られた頂点を店舗とする。
- 高速道路の作成方法:
- 頂点間をつなぐ道路のうち、まず高速道路を作成する。生成した頂点集合 に対して、完全グラフ を生成する。各頂点ペア に対する頂点間のユークリッド距離を、完全グラフにおける辺の重み と定める。
- 次に、完全グラフ に対して、最小全域木 を生成する。最小全域木の 本の辺がグラフ の高速道路網となる。これらの辺の重み を $d_{u,v} \\leftarrow \\lceil 2 \\times W_{u, v} \\rceil$ と定める。
- 残りの道路の作成方法:
- (高速道路以外の)残りの 本の道路は、次の手順で本ずつ生成される。
- を更新する。
- グラフGの辺でつながっていない, のペアの内、の最小を与えるペアをつなぐ辺をグラフGに加える。
- 選ばれた辺の重み を $d_{u,v} \\leftarrow \\lceil 4 \\times W_{u, v} \\rceil$ と定める。
- ここで のベースは頂点間のユークリッド距離だが、低い次数の頂点が選ばれやすくなるように、また、できる限り道の交差を避けるため、斜め方向よりも縦横方向の道が選ばれやすくなるように を定める。以下に の計算方法の詳細を示す。
- 各頂点 の次数 を計算する。次数 は をいずれかの端点に含むグラフ の辺の本数である。
- 各頂点 の色を、頂点の初めの(ずらす前の)座標 をもとに、下記のように定める。まずは 個の頂点のうち、 個の頂点に対し、
- が偶数の場合 :
- が奇数の場合 :
- と定める。残りの 個の頂点には、ランダムにもしくはの色を割り当てる。
- ファクター を以下のように定める:
- と が同じ場合:
- と が異なる場合:
- ファクター を以下のように定める:
- の場合:
- の場合:
- を以下のように計算する。:
- $\\mathrm{cost}(u,v) = W_{u,v}\\times \\mathrm{degree}(u) \\times \\mathrm{degree}(v) \\times f(u,v) \\times g(u) \\times g(v)$.
- (高速道路以外の)残りの 本の道路は、次の手順で本ずつ生成される。
- 各顧客の注文頻度の決定方法:
- まず、各頂点 に注文頻度 を割り当てる。
- 店舗の注文頻度をに初期化する: .
- 顧客の注文頻度をに初期化する:
- 以下、注文頻度の顧客を定める。そのためにまず、座標平面上の \[R/4,3R/4\]\\times\[R/4,3R/4\] の領域内に一様ランダムに1点、中心点 をプロットする(c=(c_x,c_y)\\in \[R/4,3R/4\]\\times\[R/4,3R/4\])。次に全ての顧客 に対して以下の処理を行う:
- $\\mathrm{EuclideanDistance}(c,u)\\le R/8 + \\mathrm{uniformRandom}\[0,R/8\]$ の場合、 とする。
車の位置と移動について
配達には車を利用する必要がある。車の位置は次に示すように二種類に分類される。
- 車の位置: 以下の二種類に分類される。
- 頂点 上にいる場合
- 辺 上にいる場合。より具体的に言えば、 から の方向に だけ離れている場合である
また、毎時刻 において、あなたは以下に示すとおりに車を操作できる。
-
車の移動: あなたが取れる行動は以下の二種類である。
stay
: 移動せずその場にとどまるmove w
: の方向に向かって距離 だけ進む
move w
を選択するとき、 は以下の条件を満たさなければならない。これらの条件を満たさない場合はWA
(Wrong Answer) となることに注意せよ。- は を満たす頂点である
- 車が頂点 上にいる場合、頂点対 がグラフの辺集合に含まれていなければならない。すなわち、 でなければならない
- 車が辺 上にいる場合、 または でなければならない
注文・配達等について
- 注文: それぞれの注文は「注文 ID」「配達先 」「注文が発生した時刻 」の三種類の情報を持つ。詳しくは、後述の入力フォーマットを参照のこと。
- 注文発生について: 顧客からの新しい注文は、$0 \\leq t \\leq T_{\\mathrm{last}} = 0.95 \\times T_{\\max}$ を満たす時刻 において確率 で発生する。それぞれの頂点には注文頻度 が定められており、注文が発生するときにその配送先が頂点 となる確率は である。詳しくは以下の疑似コードまたはサンプルコードを参考のこと。
注文発生について
-
入力: 注文が発生しうる時刻の最大値 と、時刻ごとの注文発生確率を表す関数 .
-
初期化:
-
各時間ステップ で以下を実行する:
- 実数 r \\in \\left\[ 0,1 \\right\] を一様ランダムに生成する
- の場合:
- 1つの頂点 () を、それぞれの頂点に割り当てられた頻度 で重み付けをしてランダムに選択する
- 注文を発生させる。ここで注文は(注文ID, 注文時間 , (お届け先の)頂点番号 )を含む。
- 上記以外 ( ) の場合: 注文は発生しない
-
時刻ごとの注文発生確率を表す関数 を下記のように定める:
-
$p_{\\text{order}}(t) = \\begin{cases} t / T_{\\text{peak}}, & \\text{if } 0\\le t \\lt T_{\\text{peak}}, \\\\ (T_{\\text{last}} - t) / (T_{\\text{last}}- T_{\\text{peak}}), & \\text{if } T_{\\text{peak}} \\le t \\lt T_{\\text{last}}, \\\\ 0, & \\text{if } T_{\\text{last}} \\le t, \\end{cases}$
-
ここで であり、 は区間 \[0, T_{\\text{last}}\] から一様ランダムに定める
-
注意: の値は、入力では与えられない。