3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

頂点被覆(Vertex Cover)問題をPySATのHitmanを使って解く

Posted at

頂点被覆(Wikipedia)問題はそれだけでグラフ理論の1章になるような大きな問題ですが、ここではPySATのHitmanを使って簡単なものを解くことを目指します。

【問題】以下のグラフのすべての辺に接する最小の頂点の集合を求めよ

image.png

PySATのHitmanの基本的な使い方

Wikipediaにもある簡単な問題を使ってHitmanの使い方を見て行きます。開発環境はGoogle Colabで、まずPySATのインストールから行います

!pip install python-sat

プログラムとしては辺の情報をリスト形式で入力してHitmanを呼ぶだけという超簡単なものです。期待通り[2,3,4]という結果が得られました。

import pysat
from pysat.examples.hitman import Hitman

hits = [[1,2],[1,3],[2,3],[2,4],[3,5],[4,5],[4,6]]
print(Hitman(bootstrap_with=hits).get())
# [2,3,4]

頂点の重み情報を加える

応用例として頂点に重み情報を加えてみます。weightsパラメータとして渡すのは各々の頂点の数に対して重みを返すDICT形式で渡します。頂点の数字をそのまま重みとしてみます。すると[2,3,4]の代わりに[1,3,4]となりました。

w = {x:x for x in range(1,6+1)}
print(w)
hits = [[1,2],[1,3],[2,3],[2,4],[3,5],[4,5],[4,6]]
print(Hitman(bootstrap_with=hits, weights=w).get())
# {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
# [1, 3, 4]

2位以下の順位を知りたければ、以下のようにenumerateを使って見ることが出来ます。

with Hitman(bootstrap_with=hits, htype='sorted', weights=w) as hitman:
    for hs in hitman.enumerate():
        print(f"{hs}, cost={sum([w[s] for s in hs])}")
# [1, 3, 4], cost=8
# [2, 3, 4], cost=9
# [1, 2, 4, 5], cost=12
# [1, 2, 5, 6], cost=14
# [2, 3, 5, 6], cost=16

(開発環境:Google Colab)

この考え方はProject Euler, Problem 838: Not Coprimeを解くのに役に立ちます。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?