"지문"세트 찾기


11

좋아하는 책 목록이있는 10 명의 사람이 있다고 가정하겠습니다. 주어진 사람 X의 경우, X만이 좋아하는 X 책의 특별한 부분 집합을 찾고 싶습니다. 즉, X의 특별한 부분 집합에서 모든 책을 좋아하는 사람은 없습니다. 이 특수한 부분 집합을 X의 고유 한 "지문"이라고 생각합니다.

그런 세트를 찾는 접근법에 대한 제안을 부탁드립니다. (이것은 숙제 문제처럼 보이지만, 내가 해결하려는 생물학 연구의 문제와 관련이 있습니다.)


1
가능한 책의 범위 / 수는 한정되어 있습니까? 이 "지문"식별은 각 책이 어떤 사람의 선호 목록에 추가 될 때 즉석에서 수행 될 수 있습니까? 아니면 사전에 일련의 목록이 제공됩니까?
Paresh

답변:


6

지문을 최대한 작게 만들고 싶다고 가정합니다. 그렇다면 이것은 타격 세트 문제입니다 : 각 사람마다,이 사람이 아닌 X가 좋아하는 모든 책의 목록을 만드십시오. 그런 다음 각 목록에서 하나 이상의 책을 선택하는 것이 목표입니다. 문제는 NP-hard이므로 다항식 시간에 항상 최적으로 해결하는 알고리즘을 찾을 수 없습니다. 욕심 많은 알고리즘은 이론상 최악의 경우가 좋지 않지만 실제로는 꽤 괜찮습니다. 최적으로 해결하려면 Integer Linear Programming 솔버가 최대 1000 개 또는 10000 권의 인스턴스를 해결할 수 있어야합니다. 인스턴스의 크기와 구조에 대한 자세한 내용을 제공하면 다른 방법을 제안 할 수 있습니다.


+1 물론입니다! :) 내 욕심 많은 알고리즘이 그리워지는 예제를 만드는 것은 어렵지 않습니다. 죄송합니다.
Patrick87

OP : 피드백에 너무 감사합니다. 원래 탐욕스러운 알고리즘 솔루션이 올바른 방향으로 나아갔습니다. 내가 작업하고있는 총 공간은 개인 100 명과 1000 권의 "도서"에 관한 것입니다. 이것이 정수 프로그래밍 방식으로 가능하다면 그것에 대해 더 많이 듣고 싶습니다.
Merbs December

4

이것은 특히 영리한 알고리즘은 아니지만 다항식이며 작동해야한다고 생각합니다. 어떤 세트를 가져 가십시오. 이 세트의 각 요소에 대해 포함되지 않은 나머지 세트 수를 세고 어떤 세트를 포함하는지 기억하십시오. 개수가 가장 큰 요소를 선택하고 방금 선택한 요소가없는 세트를 무시하고 나머지 요소의 개수를 다시 실행하십시오. 나머지 세트가 모두 고려되지 않을 때까지 계속하십시오.

예 : , B = { 2 , 3 , 4 } , C = { 2 , 4 , 6 } , D = { 1 , 3 , 5 }로 지정하십시오 . 그런 다음 c 1 = 2 , c 2 = 1 , c 3 = 1입니다.={1,2,}={2,,4}={2,4,6}={1,,5}1=22=1=1. 포함하지 않은 세트 C 를 제거하고 1을 선택 합니다. 카운트를 다시 실행하면 c 2 = 1c 3 = 0이 됩니다. 다음 요소로 2를 선택 하고 고려에서 D 를 제거 합니다. 이제 "지문"세트는 { 1 , 2 } 입니다. 편집 : 예제를 완료하려면 다른 지문 세트가 { 3 , 4 } , { 6 }{ 5 } 로 나오도록해야합니다 .2=1=0{1,2}{,4}{6}{5}

나는 이것을 많이 생각하지 않았지만 직관적으로 작동 해야하는 것처럼 보입니다. 아이디어는 지문의 다음 요소가 가장 많이 발견되지 않은 세트를 다루는 항목을 탐욕스럽게 생각하는 것입니다.


Falk Huffner의 답변을 참조하여 문제를 NP-Hard Hitting Set 문제로 올바르게 식별하십시오. 내 대답은 문제에 대한 일반적인 탐욕스러운 근사를 제공하는 것 같습니다. 나쁘지는 않지만 최적도 아닙니다.
Patrick87

0

미디엄미디엄[영형영형케이]fingerprint books

파이썬 코드를 보여 드리겠습니다.

%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입니다 (초기 제출에 등록하지 않았으므로 이제는 올바르게 의견을 말할 수 없습니다). 피드백에 대해 대단히 감사합니다. 원래 탐욕스러운 알고리즘 솔루션이 올바른 방향으로 나아갔습니다. 내가 작업하고있는 총 공간은 개인 100 명과 1000 권의 "도서"에 관한 것입니다. 이것이 정수 프로그래밍 방식으로 가능하다면 그것에 대해 더 듣고 싶습니다.


Falk에 알릴 수 있도록 귀하의 의견을 제시했습니다.
Merbs
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.