私は、あなたが欲しいものが何であるかはわかりません - 私はそれがあなたが心に留めていたものではないと確信していますが、合理的であれば試してみることができます。
距離は単にで最もd
あり、そしてそれより少ない何もすることができますので貪欲アルゴリズムは、ここで動作するはずのように、それは一見思えます。(1)可能な限り少なく、(2)既存の線から可能な限り離れているように、常に次の線を配置します。
この問題の最適なアルゴリズムがあり、最後の行から距離a <= d
に次の行を配置するとします。それがb
行を置くと言う。私たちの欲張りアルゴリズムは、b
行以上を配置することはできません(最初の基準はできるだけ配置しないためです)。b
行を配置すると、距離c
とa <= c <= d
に配置されます。可能。
貪欲アルゴリズムは、最適なアルゴリズムが何をしたかしなかった場合は、次のいずれかの方法で異なっていた:
それは遠く離れて、同じまたは少ないラインを配置。最適アルゴリズムが、b'
行を次のステップで距離a'
に配置したとします。次に、これらの線は、距離a+a'
にあり、合計でb+b'
行があります。しかし、欲張りアルゴリズムは、この場合、b'
の線を変位a+a'
に置き、c' = (a+a') - c
を選択することによって、最適なアルゴリズムを模倣することができます。 c > a
とa' < d
以降、c' < d
とこれは正式な配置です。
これは、より近いラインをより近くに配置しました。この場合は実際に問題があります。これは、少なくともk
行を必要とし、最も遠いものはより多くを要求し、(例えば)それがまたがる距離がd
の倍数となるように、穴の配置が選択される場合には、k
が不必要な線を配置する可能性がある。
したがって、貪欲アルゴリズムは、ケース2で機能しないことが判明します。ただし、それ以外の場合はそうです。特に、最初のケースでの観察は非常に便利です.2つのプレースメント(distance, lines)
と(distance', lines')
の場合、distance >= distance'
とlines <= lines'
の場合、最初のプレースメントが常に優先されます。これは、次のアルゴリズムを提案している:
PlaceLines(start, stop)
// if we are close enough to the other edge,
// don't place any more lines.
if start + d >= stop then return ([], 0)
// see how many lines we can place at distance
// d from the last placed lines. no need to
// ever place more lines than this
nmax = min_lines_at_distance(start + d)
// see how that selection pans out by recursively
// seeing how line placement works after choosing
// nmax lines at distance d from the last lines.
optimal = PlaceLines(start + d, stop)
optimal[0] = [d] . optimal[0]
optimal[1] = nmax + optimal[1]
// we only need to try fewer lines, never more
for n = 1 to nmax do
// find the max displacement a from the last placed
// lines where we can place n lines.
a = max_distance_for_lines(start, stop, n)
if a is undefined then continue
// see how that choice pans out by placing
// the rest of the lines
candidate = PlaceLines(start + a, stop)
candidate[0] = [a] . candidate[0]
candidate[1] = n + candidate[1]
// replace the last best placement with the
// one we just tried, if it turned out to be
// better than the last
if candidate[1] < optimal[1] then
optimal = candidate
// return the best placement we found
return optimal
これは(start, stop)
でインデックスされるキャッシュに結果(seq, lines)
を置くことによってメモ化によって改善することができます。そうすれば、すでに評価されている課題をいつ計算しようとしているのかを認識することができます。私は、問題インスタンスに対して粗いか細かい離散化を使用するかどうかにかかわらず、このケースを多くすることが期待されます。
max_lines_at_distance
とmax_distance_for_lines
の機能については詳しくは言及していませんが、これらについての言葉は多々あります。
最初は、ジオメトリをスパニングするために必要な線の数が表示されます。ジオメトリと色のついた穴を黒に塗りつぶした場合、これは、表示された変位でセルの行を見て、連続する黒い線分を考慮してそこからいくつの線があるかを判断することを意味します。
秒は、与えられた候補行数に対して、その行数を配置できる現在の位置からの最大距離を示します。あなたはその行数がまたはそれ以下のの最大距離を置くことができるようにすることで、これをより良くすることができます。あなたはこの改善を使用する場合は、あなたがn
を反復している方向と逆のことができます:f(start, stop, x) = a
とy < x
場合
- を、あなただけで、その後から、
stop
、a
まで検索する必要はありません。
f(start, stop, x)
が未定義で、y < x
の場合、それ以上検索する必要はありません。
どこでもstart
とstop
間n
または少ないラインを配置することは不可能である場合、この関数は未定義できることに注意してください。
これらの関数を別々に覚えておけば、繰り返し検索を節約できます。それぞれの行に対してmax_lines_at_distance
をあらかじめ計算し、後で使用するためにキャッシュに格納することができます。次に、max_distance_for_lines
は、2つの境界内の先頭に戻るキャッシュをチェックするループになる可能性があります。
固定間隔*に何行を配置する必要があるのですか?明らかに、それは彼らがお互いに同じ距離を持っていることを意味するわけではありません(あなたの例はこれと矛盾します)。ラインの横幅には要件がありますか?私。どのような形で途中で非常に短い線を作るのを止めているのですか? –
@NicoSchertlerこれは、各行に対して 'y mod I == 0 'を意味します。ここで、yは行のY座標です。あなたはここで拘束がないのは間違いないので、私は4番目のものを追加しました。図形内の利用可能な各点は、 'D/2'よりも線から離れていてはなりません。私は主な質問を編集しました。 目標は、ある行が穴と衝突した場合、穴の隣に配置し、真ん中を切り取るのではなく、その長さを維持することです。従って、線の全長を最小にする代わりに、「N」を最小化する目的。 – farbro
一般に、I> Dの保証された解はありません。なぜなら、平行線間の間隔はDよりも大きくなり、D/2より大きい中点は各線から離れるからです。 – jwimberley