10人がいて、それぞれにお気に入りの本のリストがあるとします。ある人Xについて、Xだけが好きなXの本の特別なサブセットを見つけたいと思います。つまり、Xの特別なサブセットのすべての本を好きな人は他にいません。私はこの特別なサブセットをXのユニークな「指紋」と考えています。
そのようなセットを見つけるためのアプローチについての提案をいただければ幸いです。(これは宿題のように見えますが、私が解決しようとしている私の生物学研究の問題に関連しています。)
10人がいて、それぞれにお気に入りの本のリストがあるとします。ある人Xについて、Xだけが好きなXの本の特別なサブセットを見つけたいと思います。つまり、Xの特別なサブセットのすべての本を好きな人は他にいません。私はこの特別なサブセットをXのユニークな「指紋」と考えています。
そのようなセットを見つけるためのアプローチについての提案をいただければ幸いです。(これは宿題のように見えますが、私が解決しようとしている私の生物学研究の問題に関連しています。)
回答:
指紋をできるだけ小さくしたいと思います。次に、これはヒッティングセットの問題です。各人について、この人ではなくXが気に入ったすべての本のリストを作成します。次に、各リストから少なくとも1冊の本を選択することが目標です。問題はNP困難であるため、多項式時間で常に最適に解くアルゴリズムを見つけることは期待できません。貪欲なアルゴリズムは理論的には最悪の場合には限界がありますが、実際にはかなり適切に機能します。最適に解く場合、Integer Linear Programmingソルバーは、最大1000冊またはおそらく10万冊のインスタンスを解くことができるはずです。インスタンスのサイズと構造の詳細を提供する場合、他のアプローチを提案できます。
これは特に賢いアルゴリズムではありませんが、多項式であり、動作するはずです。セットを取る。このセットの各要素について、それを含まない残りのセットの数を数え、どのセットに含まれるかを覚えてください。カウントが最も高い要素を選択し、残りの要素のカウントをやり直して、選択した要素がないセットを無視します。残りのすべてのセットが検討から除外されるまで続行します。
私はこれについてはあまり考えていませんが、直感的にはうまくいくようです。アイデアは、指紋セットの次の要素として、最もカバーされていないセットをカバーするアイテムを貪欲にとることです。
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']}
これはOPです(最初の送信時に登録されなかったため、適切にコメントできません)。フィードバックをありがとうございました。元の貪欲なアルゴリズムソリューションは正しい方向に進みました。私が取り組んでいる総スペースは、数百人の個人と数千人の「本」に関係しています。これが整数プログラミングアプローチで実現可能である場合、私はそれについてもっと聞きたいです。