可能な限り多くのスペースをカバーするように画面上の(サイズ変更可能な)ウィンドウを配置するアルゴリズムを考案する方法は?


20

一連のウィンドウ(幅+高さ)と画面解像度を受け入れ、ウィンドウが最大のスペースを占めるように画面上のそれらのウィンドウの配置を出力する単純なプログラムを作成したいと思います。したがってoutput size >= initial size、アスペクト比を維持しながら、ウィンドウのサイズを変更できます 。したがって、ウィンドウi場合、アルゴリズムがタプルを返すようにします(x,y,width,height)

これは2Dナップザックのバリエーションかもしれません。私はウェブ上の結果を調べてみましたが、それらはほとんど私が従うことを困難にした多くのバックグラウンド(そして実装なし)を持っていました。

最速のアルゴリズムにはあまり興味がありませんが、特定のニーズに合った実用的なものに興味があります。


1
ウィンドウのサイズを変更する場合、「初期サイズを維持する」のではなく、アスペクト比だけを使用することになります。
エムール

1
1つのウィンドウのサイズを変更して画面を覆うことができますが、問題は何ですか?

2
Saeedのコメントは2番目です。些細な解決策を除外したい場合、最小サイズのような追加の制約が必要です。Nota bene:数学者はタイル化問題をテセレーションと呼ぶようです。
ラファエル

1
言うまでもなく、最小の表示可能ウィンドウ領域を最大化し、最大の表示可能ウィンドウ領域を最小化する必要がありますが、競合は許可されますか?質問を編集してバグをなくしてください。現在の問題の説明を考えるのは簡単ではありません。

2
@ daniel.jackson:彼は、最小ウィンドウが可能な限り大きい星座を目指して努力する必要があることを示唆しています。つまり、本当に小さなウィンドウはありません。数学的には、あなたが最大限に言うことができるとのWウィンドウのセット。minwWsize(w)W
ラファエル

回答:


9

あなたの質問はそれを言っていませんが、私はあなたがウィンドウをオーバーラップさせたくないと仮定しています。

この問題に対する1つのアプローチは、Chocoなどの制約ソルバーを使用することです。問題をエンコードする制約を書き留め、ソルバーをスマートな方法で動作するように調整し、実行させます。これは、アルゴリズムを考案したりプログラミングやチューニングを行うのではなく、問題をエンコードする良い方法を見つけることにあなたがする必要があるすべての思考が費やされることを意味します。開始するための部分的な回答を次に示します。

画面サイズがと仮定します。バツmaバツ×ymaバツ

各ウィンドウについて、、あなたは変数のセットがありますX IY IH IW Iと制約をWバツyhw

  • バツyhw0
  • バツ+wバツmaバツ
  • y+hymaバツ
  • おそらく、また、例えば、ウィンドウの最小サイズ、上のいくつかの制約など。h100
  • アスペクト比が3である場合:アスペクト制約4、制約のようなものとすることができるεは、不完全なウィンドウを可能にするためにいくつかの小さな非ゼロの誤差項でありますそれ以外の場合は、問題を過度に制約します。4hϵ3w4h+ϵϵ

ここで、ウィンドウのオーバーラップに注意する必要があります。ウィンドウの各ペア、i j)に対して、次のような制約を生成します。これは、W i内にW jのコーナーが表示されないことをキャプチャします。以下のためのX Y { XのJY JX J + W JY JXのJYWWjjWjW、制約を生成します:バツy{バツjyjバツj+wjyjバツjyj+hjバツj+wjyj+hj}

  • ¬バツバツバツ+wjyyy+hj

これまでに指定された制約は、画面の端からはみ出ず、いくつかの最小サイズの制約を満たし、アスペクト比を維持する、重なり合わないウィンドウのみを説明します。

適切にフィットさせるには、適切なレイアウトであることの意味を把握するメトリックを指定する必要があります。1つの可能性は、ウィンドウのサイズをほぼ同じにしたい、および/または「空白」を最小限に抑えたいと仮定することです。これはChocoを使用して指定できるとは思いませんが、別の制約解決で可能になる可能性があります(他の誰かがここで助けてくれるかもしれません)。

Chocoでは、単一の変数として指定された目的関数に対してwrtを最大化できます。この考えに基づいて、次を最大化できます。

  • h+w

制約書き込むことにより、及び最大化するためにチョコを伝えるC 、O 、S 、Tcost=h+wcost


これは有望に見えます。私は間違いなくChocoで遊んで、これがどのように機能し、どのくらい速くなるかを確認します。
ダニエルジャクソン

しかし、なぜそれを一般的に言いますか?制約を線形不等式として表現できると思います。つまり、あなたが持っているのはバニラ線形プログラムだということです。
-Suresh

@Suresh:自由に説明してください。すぐにはわかりません。
デイブクラーク

1

私は、ブルートフォースソリューションのプロトタイプの作成を開始しました。これは、実用的なポイントに最適化できることを願っています。

Wwバツwywwwhw

S

大まかに動作します:

void fit(W, S, i, n, result)
    if i == n
        if S.score() < result.score()
            result = S
        return

    w = W[i]
    foreach x, y in S.coordinates()
        set w position to (x, y)
        while S.put(w) # check that w doesn't overlap with S's other windows and add it
            fit(W, S, i+1, n, result)
            S.windows.pop()
            w.grow()
        w.restoresize()

改善すべき点がいくつかあります。

  • S.coordinates()今はとても遅いです。すべてのポイントを反復処理しS.width x S.height、各ポイントがSのウィンドウの1つにあるかどうかをチェックします。

  • S.put()Daveの回答に記載されているテストを実行して、パラメーターがSの残りのウィンドウと重複しているかどうかを確認します。たぶん、これはインターバルツリーを使用することで改善できますか?

  • S.score()wSwndowshwww

  • W

私は現在、画面とそのウィンドウを表す適切なデータ構造を見つけようとしていますが、これらのクエリをサポートする必要があります:

  • 特定のウィンドウを他のウィンドウと重ならないように配置できる座標のリストを返します
  • 位置x、yにウィンドウを挿入します(すでに重なっていないことが確認済みです)
  • すべてのウィンドウを返す
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.