Trovare set di "impronte digitali"


11

Diciamo che abbiamo 10 persone, ognuna con un elenco di libri preferiti. Per una determinata persona X, vorrei trovare un sottoinsieme speciale dei libri di X che piaccia solo a X, cioè che non esiste nessun'altra persona a cui piacciono tutti i libri nel sottoinsieme speciale di X. Penso a questo sottoinsieme speciale come a un'impronta digitale unica per X.

Gradirei suggerimenti su un approccio per trovare tali set. (Mentre questo sembra un problema di compiti a casa, è correlato a un problema nella mia ricerca in biologia che sto cercando di risolvere.)


1
L'intervallo / il numero di libri possibili è finito? Questa identificazione con "impronta digitale" può essere fatta al volo - man mano che ogni libro viene aggiunto all'elenco dei preferiti di una persona - oppure ti è stato assegnato in anticipo il set di elenchi?
Paresh,

Risposte:


6

Presumo che tu voglia che l'impronta digitale sia il più piccola possibile. Quindi questo è il problema dell'Hitting Set : per ogni persona, fai un elenco di tutti i libri che piacciono a X ma non a questa persona. Quindi, l'obiettivo è selezionare almeno un libro da ciascun elenco. Il problema è NP-difficile, quindi non puoi aspettarti di trovare un algoritmo che risolva sempre in modo ottimale in tempo polinomiale. L'algoritmo avido ha un pessimo limite teorico nel caso peggiore, ma spesso nella pratica funziona abbastanza bene. Se si desidera risolverlo in modo ottimale, un solutore di Programmazione lineare integer dovrebbe essere in grado di risolvere istanze fino a 1000 o forse 10000 libri. Se fornisci maggiori dettagli sulla dimensione e sulla struttura delle tue istanze, potremmo suggerire altri approcci.


+1 Certo che hai ragione! :) Non è difficile costruire esempi in cui manca il mio avido algoritmo. Ops.
Patrick87,

OP: Grazie mille per il feedback: la soluzione originale per algoritmi avidi mi ha portato nella giusta direzione. Lo spazio totale su cui sto lavorando riguarda centinaia di individui e migliaia di "libri" - se questo è possibile con l'approccio di programmazione dei numeri interi, mi piacerebbe saperne di più.
Merbs,

4

Questo non è un algoritmo particolarmente intelligente, ma è polinomiale e penso che dovrebbe funzionare. Prendi qualsiasi set. Per ogni elemento in questo set, conta il numero di set rimanenti che non lo contengono e ricorda quali set lo contengono. Scegli l'elemento con il conteggio più alto e rifai i conteggi per gli elementi rimanenti, ignorando i set che mancano dell'elemento che hai appena scelto. Continua fino a quando tutti i set rimanenti sono stati eliminati dalla considerazione.

Esempio: let , , e . Quindi abbiamo conteggi , e . Scegliamo 1, eliminando gli insiemi e che non lo contenevano; rifacendo i conteggi, abbiamo e . Scegliamo 2 come elemento successivo e rimuoviamo dalla considerazione. Ora abbiamo finito e il nostro set di "impronte digitali" è . EDIT: per completare l'esempio, dovresti ottenere gli altri set di impronte digitali come ,UN={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} e .{5}

Non ci ho pensato molto, ma intuitivamente, sembra che dovrebbe funzionare. L'idea è quella di prendere avidamente come elemento successivo dell'impronta digitale impostare l'elemento che copre i set più scoperti.


Vedi la risposta di Falk Huffner, dove identifica correttamente il tuo problema come il problema dell'HP-Hard Hitting Set. Sembra che la mia risposta dia la solita approssimazione avida per il problema, che non è male, ma non è ottimale.
Patrick87,

0

Forse non ho capito correttamente la domanda (sulla base di risposte piuttosto complicate), ma qui va. Passi attraverso tutte le persone, e attraverso tutti i loro libri, che a loro piace. Si crea una struttura di dati (preferibilmente una Hash Map ), in cui la chiave è il libro e il valore è un elenco di persone a cui piace questo libro. Riempi questa struttura di dati in modo intuitivo (per ogni coppia persona / libro, aggiungi una persona all'elenco ). Quindi si passa attraverso i tasti della mappa e dove la lunghezza dell'elenco è uguale a uno, quindi questo libro è uno dei di questa persona in particolare.MM[BooK]fingerprint books

Lasciami dimostrare sul codice 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

Il codice stampa:

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

0

Questo è l'OP (non registrato al momento dell'invio iniziale, quindi ora non posso commentare correttamente). Grazie mille per il feedback: la soluzione originale per algoritmi avidi mi ha portato nella giusta direzione. Lo spazio totale su cui sto lavorando riguarda centinaia di individui e migliaia di "libri" - se ciò è possibile con l'approccio di programmazione dei numeri interi, mi piacerebbe saperne di più.


Ho inserito il tuo commento in modo tale che Falk fosse informato.
Merbs,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.