「指紋」セットを見つける


11

10人がいて、それぞれにお気に入りの本のリストがあるとします。ある人Xについて、Xだけが好きなXの本の特別なサブセットを見つけたいと思います。つまり、Xの特別なサブセットのすべての本を好きな人は他にいません。私はこの特別なサブセットをXのユニークな「指紋」と考えています。

そのようなセットを見つけるためのアプローチについての提案をいただければ幸いです。(これは宿題のように見えますが、私が解決しようとしている私の生物学研究の問題に関連しています。)


1
可能な本の範囲/数は有限ですか?この「指紋」の識別は、その場で行うことができます-各本が誰かのお気に入りのリストに追加されるとき-または、事前にリストのセットを与えられていますか?
Paresh

回答:


6

指紋をできるだけ小さくしたいと思います。次に、これはヒッティングセットの問題です。各人について、この人ではなくXが気に入ったすべての本のリストを作成します。次に、各リストから少なくとも1冊の本を選択することが目標です。問題はNP困難であるため、多項式時間で常に最適に解くアルゴリズムを見つけることは期待できません。貪欲なアルゴリズムは理論的には最悪の場合には限界がありますが、実際にはかなり適切に機能します。最適に解く場合、Integer Linear Programmingソルバーは、最大1000冊またはおそらく10万冊のインスタンスを解くことができるはずです。インスタンスのサイズと構造の詳細を提供する場合、他のアプローチを提案できます。


+1もちろんです!:)私の貪欲なアルゴリズムが失敗する例を構築することは難しくありません。おっとっと。
Patrick87

OP:フィードバックに感謝します-元の貪欲なアルゴリズムソリューションは正しい方向に進みました。私が取り組んでいる総スペースは、数百人の個人と数千人の「本」に関係しています。これが整数プログラミングアプローチで実現可能である場合、私はそれについてもっと聞きたいです。
Merbs 2012

4

これは特に賢いアルゴリズムではありませんが、多項式であり、動作するはずです。セットを取る。このセットの各要素について、それを含まない残りのセットの数を数え、どのセットに含まれるかを覚えてください。カウントが最も高い要素を選択し、残りの要素のカウントをやり直して、選択した要素がないセットを無視します。残りのすべてのセットが検討から除外されるまで続行します。

A={1,2,3}B={2,3,4}C={2,4,6}D={1,3,5}c1=2c2=1c3=1BCc2=1c3=0D{1,2}{3,4}{6}{5}

私はこれについてはあまり考えていませんが、直感的にはうまくいくようです。アイデアは、指紋セットの次の要素として、最もカバーされていないセットをカバーするアイテムを貪欲にとることです。


Falk Huffnerの回答を参照してください。彼はあなたの問題をNP-Hard Hitting Set問題として正しく識別しています。私の答えは、問題に対して通常の貪欲な近似を与えるようです。これは悪くはありませんが、最適でもありません。
Patrick87

0

MM[book]fingerprint books

Pythonコードでデモンストレーションをさせてください:

%persons with books they like (it could also be a list or a set)
joe='ABCD'
andy='CDG'
frank='AHX'
anna='HAYZ'
matt='ACH'
%just transformation form variables, to names
names={joe:"Joe",andy:"Andy",frank:"Frank",anna:"Anna", matt:"Matt"}
%the map, from books to persons who like this book
books={}

%for each person
for p in names:
    %go through his liked books
    for book in p:
        %if book is already in the map, then append the person
        if book in books:
            books[book].append(names[p])
        else:
            %if not, then create a new book, and append the current person
            books[book]=[names[p]]

%create the fingerprint map (from person to books he likes)
fingerprint={}

%for each person create an empty list
for p in names:
    fingerprint[names[p]]=[]

%for each book in the map
for book in books:
    %if only one person likes this book, then it must be a part of his fingerprint
    if len(books[book])==1:
        fingerprint[books[book][0]].append(book)

print fingerprint

コードは次のように出力します。

{'Frank': ['X'], 'Matt': [], 'Andy': ['G'], 'Joe': ['B'], 'Anna': ['Y', 'Z']}

0

これはOPです(最初の送信時に登録されなかったため、適切にコメントできません)。フィードバックをありがとうございました。元の貪欲なアルゴリズムソリューションは正しい方向に進みました。私が取り組んでいる総スペースは、数百人の個人と数千人の「本」に関係しています。これが整数プログラミングアプローチで実現可能である場合、私はそれについてもっと聞きたいです。


Falkに通知されるようにコメントしました。
Merbs 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.