Trova un ordine ottimale


9

Mi sono imbattuto in questo problema e sto lottando per trovare un modo per affrontarlo. Ogni pensiero sarebbe molto apprezzato!

Supponiamo che ci venga data una matrice , ad esempio,{1,0,1}n × k

[1010110001011011101110001]

Senza provare ogni singola permutazione, trova un ordinamento di colonne che massimizzi il numero di righe per le quali il primo elemento diverso da zero è .ci1

Per l'esempio sopra, uno di questi ordini (non è univoco!) È , cioè,(c3,c4,c1,c2,c5)

[1010-100-1011001-1011-110010-1]

Qui, per righe su il primo elemento diverso da zero è .451


Quali approcci algoritmici hai provato? Dove hai riscontrato questo problema? Puoi accreditare la fonte originale? Puoi condividere qualcosa sul contesto o sulla motivazione? Questa pagina potrebbe essere utile per migliorare la tua domanda.
DW

1
Voglio suggerire una fase di preelaborazione: lascia che una colonna semi-positiva (risp. Riga) sia una colonna (risp. Riga) con solo 0s e 1s. Il suggerimento è di rimuovere tutte le colonne semi-positive e anche le righe con 1 in una colonna semi-positiva. Nel tuo esempio, ciò rimuoverà le righe 1, 3 e 4. Ora ti rimangono righe e colonne che contengono tutte -1s. Potrebbe non essere d'aiuto, ma potrebbe essere più semplice ragionare.
Pål GD,

Possiamo supporre che il numero di righe sia molto più piccolo del numero di colonne? Questo potrebbe rendere il problema più semplice.
Angela Pretorius,

1
@Pål, una pre-elaborazione simile è possibile con righe e colonne che non contengono 1s. Tuttavia, non penso che renda più facile ragionare su: solo più piccolo.
Peter Taylor,

1
FWIW questo è un cross-post . haijo, se non ricevi una risposta su uno stack e pensi che un altro potrebbe essere migliore, puoi contrassegnarlo e richiedere una migrazione. Il cross-post non è una buona etichetta perché i rispondenti non sono a conoscenza delle risposte che potresti aver ricevuto sull'altro sito e potrebbero perdere tempo a ripeterle.
Peter Taylor,

Risposte:


4

Questo problema, che chiamerò CO per l'ordinamento delle colonne, è NP-difficile . Ecco una riduzione dal problema NP-difficile Vertex Cover (VC) ad esso:

Forme problematiche decisionali di VC e CO

Lascia che l'istanza VC di input sia (V,E,k) . Rappresenta la domanda: "Dato il grafico (V,E) , è possibile scegliere un insieme di al massimo k vertici da V tale che ogni fronte in E sia incidente su almeno un vertice scelto?" Costruiremo un'istanza (A,k) di CO che rappresenta la domanda: "Data la matrice A con elementi in , è possibile permutare le colonne di{1,0,1}Atale che un 1 appare prima di un -1 su almeno righe? "Questi due problemi sono indicati nella forma del problema decisionale , per cui la risposta a ciascuno è SÌ o NO: formalmente parlando, è questa forma di un problema che è NP-complete (o no) Non è troppo difficile vedere che la forma del problema di ottimizzazione più naturale dichiarata nella domanda del PO è approssimativamente equivalente in termini di complessità: la ricerca binaria sul parametro di soglia può essere utilizzata per risolvere il problema di ottimizzazione usando un risolutore di problemi di decisione, mentre una singola invocazione di un risolutore di problemi di ottimizzazione, seguita da un singolo confronto, è sufficiente per risolvere il problema decisionale.k

Costruire un'istanza di CO da un'istanza di VC

Siae. Costruiremo una matrice conn=|V|m=|E|A( n + 1 ) m m n + 1 n(n+1)m+n righe en+1 colonne. Le primerighe saranno formate dablocchi dirighe ciascuno, con ogni blocco che rappresentaun bordo che deve essere coperto. Il fondo(n+1)mmn+1n le righe contengono "flag" di vertici, che comportano un costo fisso per una colonna (corrispondente a un vertice) se è inclusa nella parte sinistra della soluzione di CO (corrispondente a un vertice che viene incluso nella copertura dei vertici della Soluzione VC).

Per ogni vertice , crea una colonna in cui:vi

  • tra le prime righe, il -esimo blocco di righe contiene tutte un +1 quando il bordo è incidente su e 0 altrimenti, e(n+1)mjn+1ejvi
  • le righe inferiori sono tutte 0 tranne per l' -esimo, che è -1.ni

Crea un'altra colonna "recinzione" composta da copie di -1, seguita da copie di +1.(n+1)mn

Infine, imposta la soglia per l'istanza CO costruita: . In altre parole, consentiamo al massimo righe in cui appare -1 prima di +1. Chiamiamo questo numero di righe in violazione il "costo" di una soluzione di CO.k(n+1)m+nkk

Prova

La corrispondenza tra una soluzione all'istanza CO e un insieme di vertici nell'istanza VC originale è: Ogni colonna a sinistra della recinzione corrisponde a un vertice che si trova nell'insieme e ogni colonna a destra della recinzione corrisponde a un vertice che non lo è.

Intuitivamente, gli -1 nella parte superiore della colonna "fence" obbligano la selezione di un sottoinsieme di colonne da posizionare alla sua sinistra che insieme contengono + 1 in tutte queste posizioni, corrispondenti a un sottoinsieme di vertici che si verificano su ogni bordo. Ognuna di queste colonne che appare a sinistra della "recinzione" ha un -1 su una riga distinta da qualche parte nelle righe inferiori , sostenendo un costo di 1; i +1 nella parte inferiore della "recinzione" assicurano che tutte le colonne poste alla sua destra non comportino tale costo.n

Chiaramente una soluzione VC che utilizza al massimo vertici fornisce una soluzione all'istanza CO costruita con un costo al massimo : ordina arbitrariamente le colonne corrispondenti ai vertici nella copertura del vertice, seguita dalla colonna di recinzione, seguita da tutte le colonne rimanenti in qualsiasi ordine .kk

Resta da dimostrare che una soluzione all'istanza CO con costo al massimo corrisponde a una copertura del vertice con al massimo vertici.kk

Supponiamo al contrario che esista una soluzione all'istanza CO con un costo al massimo che lasci una riga nelle righe superiori con un -1 prima di un +1. Questa riga appartiene a un blocco di righe corrispondenti a un bordo particolare . Ogni riga in questo blocco nell'istanza originalek(n+1)m(n+1)uvA è identico per costruzione; le colonne di permutazione possono modificare queste righe, ma non influiscono sul fatto che sono identiche. Quindi ciascuna di questen+1 righe identiche ha un -1 prima di un +1 nella soluzione, il che implica un costo di almenon+1 . Makn<n+1 : contraddizione.

Poiché ciascuno dei m blocchi di righe nella parte superiore (n+1)m righe ha un +1 prima di un -1, ciascuno dei bordi corrispondenti è coperto da un vertice corrispondente a una colonna a sinistra della recinzione: cioè , questo sottoinsieme di vertici costituisce una copertura del vertice. Poiché nessuna delle righe m superiori (n+1)m ha un -1 prima di un +1, l'unico posto in cui il costo può accumularsi nella soluzione è nelle n righe inferiori , dalle colonne posizionate a sinistra della recinzione. Ciascuna di queste colonne ha un costo esattamente 1, quindi dato che il costo è al massimo k , ci deve essere al massimo ktali colonne, e quindi al massimo k vertici nella copertina.

Infine, è chiaro che l'istanza CO può essere costruita in tempo polinomiale dall'istanza VC, il che significa che se esistesse un algoritmo tempo polinomiale per risolvere CO, qualsiasi istanza VC potrebbe anche essere risolta in tempo polinomiale costruendo prima un'istanza CO come descritto sopra e poi risolverlo. Poiché VC è NP-difficile, anche CO.


Ogni volta che c'è una risposta così bella, mi chiedo se le "Domande sulla rete calda" debbano essere sostituite o unite da qualcosa come "Risposte preziose alla rete".
John L.

Potresti far luce su come trovi la risposta? Questo dovrebbe essere ancora più illuminante della risposta stessa.
John L.

1
@ Apass.Jack: grazie! :) Non ho una strategia speciale e posso passare molto tempo a vagare nella direzione sbagliata. Ad esempio, qui ho trascorso molto tempo pensando di poter ridurre dal ciclo hamiltoniano (che è simile per quanto riguarda l'ordinazione di elementi) prima di rendermi conto che la mia costruzione avrebbe permesso configurazioni corrispondenti ai sottotesti, e quindi non avrebbe funzionato. Di norma, provo sempre riduzioni da Vertex Cover o Partition, quindi forse Clique. "Valuable Network Answers" sembra un'ottima idea :)
j_random_hacker

1
@ Apass.Jack: Un'utile idea generale è quella di pensare a come "ridimensionare" un'istanza del problema di destinazione senza modificarne la risposta, ad esempio se il problema di destinazione (ciò che stiamo cercando di dimostrare duro) è Vertex Cover, che rende positivo integer copie disgiunte del grafico e anche moltiplicando la soglia k per r lascia invariata la risposta. Spesso si desiderano determinate violazioni (soluzioni target che non corrispondono a soluzioni di origine valide) per "sopraffarne" altre, e in tal caso è possibile "moltiplicare" i gadget che corrispondono alla violazione più importante. rkr
j_random_hacker

1
Per la riduzione della mia risposta, vogliamo codificare un'istanza di un problema in cui esistono due "forze": provare a coprire tutti i bordi e provare a usare il minor numero possibile di vertici. Il primo è più importante qui, quindi ho "moltiplicato" le righe corrispondenti ai bordi: ora una singola violazione del bordo costa , il che significa che è peggio perdere un singolo bordo piuttosto che includere tutti i vertici. E ho appena capito che avrei dovuto modificare la risposta a esplicitare che abbiamo a che fare con le problematiche decisione versioni di questi due problemi, in cui i parametri di soglia fanno parte dell'istanza problema ...n+1
j_random_hacker

2

Non so se esiste effettivamente una soluzione polinomiale. Tuttavia, in base al commento di Pål GD, è possibile creare una funzione di semplificazione. La matrice iniziale è simplificated come si costruisce la sequenza di uscita S .

function simplification:
while(true)
    if any row i$ has no 1 or no -1 left, remove it
    if any column j has no -1 then,
       remove it and put j on the leftmost available position in S,
       remove all rows where column j has 1.
    if any column j has no 1 then, 
       remove it and put j on the rightmost available position in S.
    if no modification has been done on this loop, break

Quindi devi fare una completa esplorazione della combinatoria usando iterativamente la funzione pick:

function pick(k):
    put column k on the leftmost available position in S
    remove any row where column k is -1 or 1

Dopo ogni scelta puoi fare una semplificazione per ridurre eventualmente il numero di possibilità da esplorare. Suggerisco di esplorare avidamente a partire dalla colonna con meno -1, quindi potresti raggiungere un limite inferiore facendo un criterio di stop.

Nell'esempio dato, la prima semplificazione dà (come spiegato da Pål GD nel commento)

  • S[0]=c3 , rimuovi r1, r3
  • S[1]=c4
  • S[2]=c2
    [-111-1]

[-1100001-1000000-1100001-1000000-1100001-1]

Tuttavia, la semplificazione risparmia ancora circa la metà delle fasi di esplorazione. E questo tipo di matrice può essere suddivisa in più sotto-matrici indipendenti.


1
@ Apass.Jack L'ho modificato per essere più preciso. Sì, intendevo la posizione della colonna nella sequenza di output.
Optidad

Considerato il passaggio di semplificazione potrebbe essere abbastanza buono per scopi pratici (come esercizi di programmazione online?).
John L.

Grazie, infatti, ero interessato a stimare il costo del tempo ammortizzato, ma non so davvero come fare. È possibile ? O dipende molto dal problema?
Optidad

2
iojiojjioj

1
iojiojiojiojioKK
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.