私は庭を植えようとしています。特定の植物は、いくつかの植物にとっては良く、他の植物にとっては悪いです、そして私は植物の最良の順序を見つけようとしています:この表で定義されているように、最も隣接する友達と隣接する敵はありません:
Num Vegetable Friends Foes
1 Watermelon 7,4,3 8,6
2 Tomatoes 9,8,6,5,1 7
3 Sunflowers 7,6,11
4 Zucchini 9,7,3
5 Eggplant 9,6,2 7,10
6 Cucumbers 9,7,3 8,1
7 Corn 8,6,4,3,1 5,2
8 Cantaloup 7,4,3 6,1
9 Bell peppers6,5,11,10,2
10 Swiss chard 2 5
11 Rhubarb 9,3
各植物が1つずつあり、それらが一列に植えられていると仮定すると、どのようにして(最も効率的に)並べ替えて、最も隣接する友達を取得し、隣接する敵を排除することができますか?オンラインのツールがありますが、私は思考プロセスと実装を理解しようとしています。 Javaは私が知っている言語なので、それはどの言語の中でも最も役立つでしょうが、概念は私にとって重要な点です。
この種の問題には、 branch&bound テクニックを使用して対処できます。要するに
サーチスペースはツリーを形成します。ツリーは、深さ優先検索、幅優先検索、または組み合わせたアプローチで走査できます(Wikipediaの ツリートラバーサルを参照)
ツリーの各レベルは、植栽行のエントリの1つを表します
ツリーの一番上で、1つの植物を選ぶ11の可能性があります
以下の各レベルで、利用可能な植物の数は1つ減少します
11をすべて探索するのを避けるために! (= 39.916.800)異なる順序、検索ツリーを枝刈りする必要がある
剪定することができます
(1)敵を互いに下に置くことを禁止することによって、または
(2)与えられた部分解の可能な友人の最大数を推定し、この数が現在の最もよく知られている解よりも小さい場合、サブツリーの探索を停止する
このような検索スペースの完全な分析が可能かどうかは、アイテムの数に大きく依存し、制約によってツリーの効果的な枝刈りが可能かどうかに依存します。
膨大な数のアイテム(数百または数千)の場合、合理的な時間内でグローバルに最適なソリューションを見つけることは事実上不可能である可能性があります。ただし、 シミュレートされたアニーリング のようなアルゴリズムは、グローバル最適に近似する「十分に良い」解を見つけることを可能にする場合があります。 「 遺伝的アルゴリズム 」で質問にタグを付けたので、これは確かに近似解を見つけるためのアプローチでもありますが、通常、 進化論よりも実装に多くの労力を費やしますSAのようなアルゴリズム 。
私が正しく理解していれば、この問題の構造は、有向グラフを作成し、ノードを繰り返さずにすべてのノードを含むパスがあるかどうかを判断することで解決できます。私は先に進んで、フレンドグラフの(醜い)描画を描きました:
私はチェックしていませんが、おそらくそのような経路が少なくとも1つはあると思います。このグラフでは、「友達」だけが隣接するパスになるため、「敵」のデータを考慮する必要はありません。
ここで、「敵」間の距離を最大化しようとしたり、行を追加したりすると、これははるかに複雑な問題になりますが、前述のとおり、それはかなりよく知られています。これは ケーニヒスベルクの7つの橋 問題と構造的に同等です。 Dijkstraのアルゴリズム のバリアントを使用して、すべての頂点の距離が1であるすべてのノードに触れる最短経路ソリューションを考え出すことができると思います。
再びグラフを見ると、友人関係が方向性があるという事実を考えていました。これは、双方向であるかどうかに基づいて各頂点に重み(距離)を追加することでモデル化できます。 1方向の関係の場合は1、双方向の関係の場合は0.5。これにより、最短経路アルゴリズムが最適化され、植物の両側にできる限り友人がいるような答えが得られます。