ChatGPTの作図能力を問う-クイックソート可視化に挑戦

ChatGPTはテキストしか出力しませんが、出力形式を工夫することで、グラフや図を描画させることが可能です。出力方法をまとめてみます。

お題はクイックソートです。

結論から書くと、出力形式により作図能力が変わりました。クリックソートに関しては次の通りの結果でした。

```
テキスト > Mermaid > PlantUML > Graphviz > SVG
```


# default - text

特に出力形式を指定しないと、テキストで図を描画してくれます。

```
クイックソートのアルゴリズムを図にしたいです。作図してください。
```

何のひねりもなく指示すると、テキスト上に図を出力します。

![スクリーンショット 2023-06-03 9.49.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/c98c3681-551a-a31d-dcdf-6b3b7ee65d2f.png)


# SVGで出力

SVGも出力できます。でも、ちょっと座標がおかしいので苦手なのかな？

```
クイックソートのアルゴリズムを図にしたいです。
出力形式はSVGで作図してください。
```

![スクリーンショット 2023-06-03 18.30.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/a7f6766e-6a8f-6eab-5489-ad35f6ea2391.png)

それで、SVGをブラウザで表示すると次のようになりました。
自信たっぷりの回答だったので、期待していたのですが。。。

![スクリーンショット 2023-06-03 18.31.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/27cbe9c5-32bc-0531-ec23-916141e73737.png)

・・・結構壊れていますね。続く会話で以下のようなプロンプトを投げてみます。

```
レイアウトが崩れています。図が重ならないように配置できませんか？
```

![スクリーンショット 2023-06-03 18.34.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/8bff28ea-95f6-34fe-df8b-6751f1ccde7e.png)

ChatGPTの謙遜さには、倣いたいと思います。結果はどうでしょうか？

![スクリーンショット 2023-06-03 18.35.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/4bc0b587-aecc-eb6c-9e5f-0e0f9abe4747.png)

大した変化はありませんでした。残念。


# PlantUMLで出力

次に、PlantUMLで出力してみましょう。
ChatGPTはPlanuUMLの作図はそこそこ得意です。
次のようなプロンプトを投げてみました。

```
クイックソートのアルゴリズムを図にしたいです。
出力形式はPlantUMLで出力してください。
```

PlantUMLは、Qiitaでもデフォルトでレンダリング可能なので、貼り付けてみたのですが、文法エラーになってしまいました。そこで、改めて再生成すると、次のような図を生成しました。

```plantuml
@startuml
class QuickSort {
  +quickSort(arr: int[], low: int, high: int): void
  -partition(arr: int[], low: int, high: int): int
}

QuickSort ..> QuickSort : <<utility>>
QuickSort ..> QuickSort : <<utility>>

class Main {
  +main(): void
}

Main ..> QuickSort : <<uses>>

class ArrayUtils {
  +printArray(arr: int[]): void
}

Main ..> ArrayUtils : <<uses>>

Main --> QuickSort : Create instance
Main --> ArrayUtils : Create instance

class QuickSortTest {
  +test(): void
}

QuickSortTest ..> QuickSort : <<uses>>
QuickSortTest ..> ArrayUtils : <<uses>>

Main --> QuickSortTest : Create instance

@enduml
```

それっぽいですね。素晴らしいです。
ただし、アルゴリズムを図にしたというよりは、プログラムの構造を図にしたような雰囲気です。

# Graphvizで出力

Graphvizの出力精度もPlantUMLくらいありそうです。
次のプロンプトを投げました。

```
クイックソートのアルゴリズムを図にしたいです。
出力形式はGraphvizで出力してください。
```

生成されたデータを「qsort.gv」という名前で保存して以下のようなコマンドでPNGファイルを生成しました。

```
$ dot -Tpng -o qsort.png qsort.gv
```

すると図は次のようになりました。ただし、あまりアルゴリズムを解説しているという感じはしません。

![qsort.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/f337689f-699d-4745-73e6-052a9f449486.png)

そこで、ここに来てプロンプトを工夫することにしました。

```
クイックソートのアルゴリズムを知りたいです。
クイックソートの手順を箇条書きにしてください。
出力形式はGraphvizで出力してください。
```

なんとなく雰囲気だけは出ているでしょうか。

![qsort.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/5c11dd99-9633-6e8f-1f7b-c9dfdd3a29f9.png)


# Mermaidで出力

次に、気軽に図が記述できる、Mermaidで出力してみます。個人的には、かなり期待しています。

```
クイックソートのアルゴリズムを知りたいです。
出力形式はMermaidで出力してください。
```

どうでしょうか。すると、次のような図が出力されました。アルゴリズムの説明という点では、これまでで一番優秀でしょうか。

```mermaid
graph TD
  A[クイックソート] --> B[分割]
  B --> C[要素の選択]
  C --> D[枢軸の選択]
  D --> E[枢軸の配置]
  E --> F[分割]
  F --> G[再帰的なソート]
  G --> F
  F --> H[結果の連結]
  H --> I[ソート済み配列]
```


そこで、もう少しプロンプトを工夫しました。

```
クイックソートのアルゴリズムを知りたいです。
クイックソートの手順を箇条書きにしてください。
出力形式はMermaidで出力してください。
```

すると、以下のような図を出力します。

```mermaid
graph TD
  A[配列を選択] --> B{要素数が1以下か}
  B -- Yes --> C[配列を返す]
  B -- No --> D[ピボットの選択]
  D --> E[ピボットを基準に要素を分割]
  E --> F[基準より小さい要素を再帰的にソート]
  E --> G[基準より大きい要素を再帰的にソート]
  F --> D
  G --> H[ソートされた配列を結合]
  H --> C
```

ちょっと不正確ですが、それなりの図を出力しています。
ここまでは、モデルGPT-3.5でしたので、GPT-4でも試してみました。

```mermaid
graph TD;
A[開始] --> B{配列が1要素以下か?}
B -->|Yes| C[終了]
B -->|No| D[ピボット選択]
D --> E[ピボットより小さい要素集合: L]
D --> F[ピボットより大きい要素集合: R]
E --> G[クイックソートを再帰的にLに適用]
F --> H[クイックソートを再帰的にRに適用]
G --> I[結果結合: ソート済みL + ピボット + ソート済みR]
H --> I
```

やはり、GPT-3.5よりも、GPT-4の方が結果が良い感じの図を出力しています。

# GPT-4 + Show Meプラグイン

餅は餅屋でしょうか。GPT-4と「Show Me」プラグインで描画してみます。

```
クイックソートのアルゴリズムを知りたいです。
クイックソートの手順を箇条書きにして、図で出力してください。
```

プロンプトが悪かったのか、意外にもあっさりしています。

![スクリーンショット 2023-06-03 19.10.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/7ea34aac-136d-baaa-648c-c862261fef4c.png)


先ほど結果が良かったプロンプトで改めて試してみます。

```
クイックソートのアルゴリズムを知りたいです。
クイックソートの手順を箇条書きにしてください。
出力形式はMermaidで出力してください。
```

![スクリーンショット 2023-06-03 19.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33180/afd211f4-bf2c-ccd9-5fe1-5d50f36ddfeb.png)

「Show Me」プラグインもGPT-4で生成したものをグラフで出力するだけなので、それほど変わらないようです。

# お題が難しすぎた？

なお、「Wolfram」プラグインも試してみましたが、「申し訳ありませんが、クイックソートの視覚化に問題があります。クイックソートの視覚化は、一般的なプログラミング環境では簡単には実現できないかもしれません。それは、クイックソートが再帰的なアルゴリズムであり、その動作を一度に全体として視覚化するのが難しいからです。」とのことでした。

クイックソートでは、お題が難しすぎたようです。

# まとめ

ここまでの結果を比較してみて、単純にクイックソートが分かりやすかったのは、テキスト出力したもの、次にMermaidでした。PlantUMLもプロンプトを工夫すればもっと分かりやすくなりそうでした。

また、プロンプトに与える入力を少し変えるだけでも結果が向上するので、いろいろ試してみたいと思いました。