2015-12-07 8 views
5

Questa domanda è stata posta una volta prima ma non è stata data risposta, quindi ho pensato di chiedere di nuovo con alcune specifiche della mia situazione.Algoritmo di ordinamento di elenchi per confronti effettuati dall'uomo

Sto provando a sviluppare un'applicazione che consente di inserire un elenco di elementi discreti (per questo esempio, frutta) e offre confronti tra due. Scegli il tuo preferito tra i due e poi questo processo si ripete finché alla fine hai una lista ordinata per preferenza di questi oggetti (in questo esempio, un elenco dei tuoi frutti preferiti, in ordine).

Il problema è che le tradizionali strategie di smistamento, non importa quanto velocemente, coinvolgeranno necessariamente più operazioni di quanto sia fattibile per un umano in qualsiasi ragionevole lasso di tempo (anche con una lista di soli 50, come il mio la lista di test corrente è).

Poiché ovviamente non esiste un algoritmo di ordinamento garantito con una complessità sufficientemente bassa, credo che alcune indennità debbano essere fatte. C'è un modo per saltare grandi blocchi di smistamento? Ho considerato un modo per assegnare valori alle voci in base al numero di confronti che hanno "vinto" e quindi arrestare l'ordinamento dopo un po 'e assumendo che quei valori danno l'ordine corretto, simile allo stile che si potrebbe risolvere con un scacchi svizzero torneo se non riesci a completare abbastanza round per determinare un vincitore normalmente. Non so se sia plausibile.

Un esempio per chiarire cosa intendo: dire che aveva una lista di

Apple 
Orange 
Kiwi 
Banana 
Melon 

Sarebbe di offrire i confronti come

Do you prefer: 
A Apple 
B Kiwi 

e così via fino a quando si dispone di un elenco che sembra

Kiwi 
Apple 
Orange 
Melon 
Banana 

che è il vostro ordine di preferenza di quei frutti.

+0

Quali sono esattamente i confronti offerti? Potresti chiarire cosa intendi mostrando i passi che dovresti fare con un array di 5 elementi? – jperezov

+0

@jperezov ha aggiunto un esempio al mio post originale – CountBale

+0

Questo può essere risolto con un approccio completamente diverso. Piuttosto che chiedere all'utente di classificare ogni singolo oggetto, dargli una lista e un modo semplice per spostare le cose su e giù nell'elenco. –

risposta

4

Quali sono le tue preferenze di frutta? Hai una lista completa di preferenze nella tua mente, o hai dei frutti che "ti piacciono più dei più", frutti che "ti piacciono meno della maggior parte", e il resto di cui non hai sentimenti forti - o non hai nemmeno provato.

Il problema con il modo in cui si è formulato il problema è che si è assunto che le preferenze di una persona siano total order, che è naturalmente codificata come elenco. In realtà, le preferenze di una persona sono spesso pari a partial order, che è naturalmente codificata come directed acyclic graph.

Ad esempio, per l'insieme dei frutti {Apple, Orange, Kiwi, Banana, Melon, Starfruit}, potrei avere preferenze frutta come segue:

Melon < Apple 
Apple < Banana 
Banana < Kiwi 
Banana < Orange 

Un buon modo per arrivare ad un ordine parziale in base all'input dell'utente è di riprodurre radix sort. Per iniziare, chiedi all'utente di selezionare, per ogni frutto, se gli piace, se non lo gradisce, se si sente neutrale o non lo sa. Vorrei rispondere a questa come segue:

  Like Dislike Neutral Unknown 
Apple     x 
Orange  x 
Kiwi  x 
Banana  x 
Melon   x 
Starfruit      x 

Supponendo Dislike < Neutral < Like, queste risposte codificare le seguenti informazioni, anche se ho risposto solo le domande che ci sono frutti:

Melon < Apple 
Apple < Orange 
Apple < Kiwi 
Apple < Banana 

Avanti, identificare quali risposta (s) ha ricevuto il maggior numero di segni di spunta. In questo caso, mi sembra di avere 3 frutti che mi piacciono, 1 non mi piacciono, e 1 mi sento neutrale (a meno che non sia coinvolto il burro di arachidi), e 1 non ho mai provato (quindi non ho alcuna preferenza rispetto a gli altri frutti).

Quindi il luogo naturale per approfondire le mie preferenze sarebbe nei frutti che mi piacciono. Il problema è ricorsivo: ora vuoi determinare le mie preferenze nel set di frutti {Orange, Kiwi, Banana}. Potresti chiedermi quali di quei frutti sono i miei preferiti e fare clic su Orange e Kiwi. Che ti dice quanto segue:

Banana < Orange 
Banana < Kiwi 

In combinazione con il primo turno di informazioni, ora avete:

Melon < Apple 
Apple < Orange 
Apple < Kiwi 
Apple < Banana 
Banana < Kiwi 
Banana < Orange 

Apple < Banana e Banana < Kiwi implica Apple < Kiwi; Apple < Banana e Banana < Orange implicano Apple < Orange. Quindi possiamo eliminare le informazioni ridondanti per arrivare al seguente:

Melon < Apple 
Apple < Banana 
Banana < Kiwi 
Banana < Orange 
+0

Questa è un'idea interessante, come pensi che i dati possano essere visualizzati in modo più facilmente leggibile? – CountBale

+0

@CountBale Se si limitano le preferenze dell'utente ad assomigliare a '{A, B, C} <{D, E} <{F, G, H} <{I} <{J, K, L, M}' più alcuni non classificati '{X, Y, Z}' (come 'Starfruit' nel mio esempio), quindi è possibile visualizzare le preferenze dell'utente come un elenco di gruppi, in cui ogni elemento in un gruppo è preferibile a ogni elemento in ogni gruppo inferiore. Le mie preferenze per la frutta sarebbero le seguenti: '{Melone} <{Apple} <{Banana} <{Kiwi, Arancio}' + non classificato '{Starfruit}'. –

3

Si può consentire all'utente non solo di determinare se un articolo è più preferibile rispetto a un altro, ma anche un voto da 1 a 10 per esempio quanto più preferisce l'uno dall'altro. In questo modo hai più informazioni e puoi facilmente creare una classifica.

Nell'approccio ottimale in cui un utente può solo dire più piccolo o più grande è necessario eseguire la ricerca binaria per ogni elemento nell'elenco. La ricerca binaria ha complessità O(log n). In questo modo n con n passando da 1 a n fa un totale di O(n * log (n/2)). In caso di 50 articoli che richiederebbero un po 'più di 200 passaggi.

+0

Mi piace la prima idea, anche se piuttosto che un voto da 1 a 10 probabilmente lo implementerei come qualcosa del tipo: Molto A> A> Poco A> Nessuna preferenza> Leggermente B> B> Molto B o qualcosa lungo quelle linee . Avrò bisogno di capire come usare esattamente quei valori nell'algoritmo sebbene – CountBale

+0

+1 per la valutazione. Valutare 50 articoli e ordinare in base alla valutazione sarebbe molto più veloce rispetto a qualsiasi numero di confronti. – jperezov

+0

Ma il problema con il solo dare una valutazione è che ti costringe a considerare tutti i dati contemporaneamente per valutare davvero tutto. Dare qualcosa 89 non ha senso senza il contesto dell'intero insieme di dati. Volevo creare un'app che semplificasse il processo di ordinazione dell'elenco in modo tale da dover considerare solo due elementi contemporaneamente. – CountBale

2

Utilizzare un insertion sort. Invece di chiedere all'utente di confrontare due elementi alla volta, chiedigli di selezionare il loro preferito dall'intero elenco rimanente. Metti quell'elemento alla fine dell'elenco ordinato, rimuovilo dagli altri elementi e ripeti fino a quando gli oggetti rimanenti sono esauriti.

+0

Sto considerando una via di mezzo tra questa e la mia idea iniziale.Forse offrendo all'utente una scelta di 10 elementi e chiedendo loro di scegliere il loro preferito da quelli, quindi iterandolo fino a quando il set di dati non viene ordinato. Sarebbe superiore alla complessità N ma consentirebbe anche all'utente di prendere in considerazione meno dati in un dato momento. – CountBale