質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

566閲覧

矩形模様の最短手順での塗りつぶし。その3

can110

総合スコア38339

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/06/22 08:37

編集2023/06/22 09:06

前提

矩形模様の最短手順での塗りつぶし
矩形模様の最短手順での塗りつぶし。その2
の続きです。
「スキャンライン法」「最小矩形分割問題」「連結成分ラベリング」以外での解決方法を探しています。

問題

二次元の矩形領域を塗りつぶして、色の模様を描きます。
矩形領域の塗りつぶしという操作では、始点(xs,ys)と終点(xe,ye)と色の名前(color)を指定することで、その矩形範囲を塗りつぶします。
なお、領域上の同じ位置に複数回の塗りつぶしが行われると、後で実行した色で塗りつぶされます。

実現したいこと

このとき、任意で指定された模様を描くために、できるだけ少ない回数で塗りつぶすための操作データ(始点、終点、色)のリストを求めたい。

回答してほしいこと

  • 上記を実現するために利用できるアルゴリズム、もしそれに名前があればそのアルゴリズムの名称
  • そのアルゴリズムの概要の説明
  • そのアルゴリズムを利用して問題をとく、単純な例での具体的な手順
  • 具体的に実行可能なPythonコード

ただし、以下の手法以外を提示ください。

  • 最小矩形分割問題
  • スキャンライン法 (Scanline Algorithm)
  • 連結成分ラベリング (Connected Component Labeling)

調べたこと・考えたこと

ChatGPTにたずねたところ「グラフ理論に基づくアプローチ」が利用できるかもしれないと提案されましたが、詳細は確認していません。

また、塗りつぶしは後の操作結果で上書き(重ね合わされる)ことから、レイヤー(層)を意識した手法が必要だと思われます。
たとえば3次元上で複数の矩形の板(ポリゴン)を水平面に層状に重ね合わせ、それを真上から見た場合を考えます。
任意の指定された模様を最小の板の数で実現する問題と等価だと思われます。

模様の具体例

Python

1pat = [['R','G','G','R'], 2 ['R','G','G','R']]

幅4x高さ2の領域に上の模様を描きたい場合は、左上を原点とすると

Python

1instructions = [((0,0),(0,1),'R'), # 左端の赤い矩形 2 ((1,0),(2,1),'G'), # 中央の緑の矩形 3 ((3,0),(3,1),'R')] # 右端の赤い矩形

という3回の操作で描けますが

Python

1instructions = [((0,0),(3,1),'R'), # 全体を赤い矩形で塗りつぶし 2 ((1,0),(2,1),'G')] # 中央に緑の矩形で塗りつぶし

という、より少ない2回の操作で描けます。

問題の制限

指定される色の模様の全体領域サイズは幅と高さともに1024以下。色の種類の数は256色以下です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

この回答はGPT-4による自動生成回答です

この問題に対して、動的計画法 (Dynamic Programming) を利用することができます。動的計画法は、問題を小さな部分問題に分割し、それらの部分問題を解決して最終的な解を得るアルゴリズムです。

アルゴリズムの概要

  1. 与えられた模様を左上から右下までの順番で走査します。
  2. 各セルについて、そのセルの色が上下左右のセルの色と異なる場合、そのセルを始点とする新しい矩形を作成します。
  3. 新しい矩形が作成された場合、その矩形を右方向に拡張できるだけ拡張します。
  4. 拡張が終わったら、その矩形を下方向に拡張できるだけ拡張します。
  5. すべてのセルを走査し終わったら、作成された矩形のリストを返します。

具体的な手順

例として、以下の模様を考えます。

pat = [['R', 'G', 'G', 'R'], ['R', 'G', 'G', 'R']]
  1. 左上のセルから走査を開始します。最初のセルは 'R' です。
  2. 上下左右のセルと色が異なるので、新しい矩形を作成します。始点は (0, 0) です。
  3. 右方向に拡張できませんので、次のステップに進みます。
  4. 下方向に拡張できますので、矩形を拡張します。終点は (0, 1) になります。
  5. 次のセルに進みます。現在のセルは 'G' です。
  6. 上下左右のセルと色が異なるので、新しい矩形を作成します。始点は (1, 0) です。
  7. 右方向に拡張できますので、矩形を拡張します。終点は (2, 0) になります。
  8. 下方向に拡張できますので、矩形を拡張します。終点は (2, 1) になります。
  9. すべてのセルを走査し終わりましたので、作成された矩形のリストを返します。

結果として、以下の矩形のリストが得られます。

[((0, 0), (0, 1), 'R'), ((1, 0), (2, 1), 'G')]

Pythonコード

python

1def find_rectangles(pat): 2 rectangles = [] 3 h, w = len(pat), len(pat[0]) 4 5 for y in range(h): 6 for x in range(w): 7 if (y == 0 or pat[y][x] != pat[y - 1][x]) and (x == 0 or pat[y][x] != pat[y][x - 1]): 8 xs, ys = x, y 9 xe, ye = x, y 10 11 while xe + 1 < w and pat[ye][xe + 1] == pat[ys][xs]: 12 xe += 1 13 14 while all(pat[y][xs] == pat[y][xe] for y in range(ys, ye + 1)) and ye + 1 < h: 15 ye += 1 16 17 rectangles.append(((xs, ys), (xe, ye), pat[ys][xs])) 18 19 return rectangles 20 21pat = [['R', 'G', 'G', 'R'], 22 ['R', 'G', 'G', 'R']] 23 24print(find_rectangles(pat))

このコードは、与えられた模様に対して動的計画法を適用し、最小回数で塗りつぶすための操作データのリストを返します。ただし、このアルゴリズムは最適解を保証するものではありませんが、実用上は十分な結果を提供することが多いです。

投稿2023/06/22 08:39

teratail-ai

Powered by GPT-4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2023/06/22 08:59

回答コードの実行結果は正しいですが、やはり最適解ではありません。 [((0, 0), (0, 1), 'R'), ((1, 0), (2, 1), 'G'), ((3, 0), (3, 1), 'R')] この手法も基本的には重ね合わせが考慮できないと思います。 たとえば具体的な手順3「右方向に拡張できませんので」という時点で探索を止めていますが、 その場合に「この位置はあとの操作で塗りつぶしが必要」として探索を進めるようなアプローチがよりよいように思います。
guest

0

自己解決

GPT-4による自動生成回答によって
指定された模様を走査する過程で異なる色が現れたら探索を終えるという手順では最適解が得られないのではないか?
という知見を得られた成果としてクローズします。

投稿2023/06/22 09:08

can110

総合スコア38339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問