Spiacente, ma questo sta per essere più di un layout di logica rispetto al codice ...
non è del tutto chiaro se la matrice (1,2,3,4) sono i punteggi per il primo piatto o per la prima cuoca, ma mi sarebbe probabilmente utilizzare un array in modo tale che
$array[$cook_id][$dish_number] = $score;
asort() ogni array in modo che $ array [$ cook_id] = array ($ lowest_scored _dish, ..., $ più alto);
Considerare una preferenza ponderata per un cuoco particolare per fare di un piatto la differenza tra il punteggio del piatto migliore e un altro.
Come esempio molto semplice, cucina a, b, c e piatti 0,1,2
$array['a'] = array(0=>100, 1=>50, 2=>0); // cook a prefers 0 over 1 with weight 50, over 2 with weight 100
$array['b'] = array(0=>100, 1=>100, 2=>50); // cook b prefers 0,1 over 2 with weight 50
$array['c'] = array(0=>50, 1=>50, 2=>100); // cook c prefers 2 with weight 50
Dopo asort(): $ array [ 'a'] = array (0 => 100 , 1 => 50, 2 => 0); $ array ['b'] = array (0 => 100, 1 => 100, 2 => 50); $ array ['c'] = array (2 => 100, 0 => 50, 1 => 50);
Inizia con il cuoco 'a' che preferisce il piatto 0 sul piatto successivo migliore di 50 punti (peso). Anche Cook 'b' preferisce dih 0, ma con un peso di 0 sul piatto successivo. Quindi è probabile (anche se non è ancora certo che cuocere 'a' dovrebbe fare il piatto 0.
Considerare il piatto 0 da prenotare e passare a cucinare 'b'. Escludendo il piatto 0, il cuoco 'b' preferisce il piatto 1. No altro cuoco preferisce piatto 1, in modo da cucinare 'b' viene assegnato piatto 1.
Cook 'c' ottiene piatto 2 per impostazione predefinita.
Questo è un esempio molto pratico in cui ogni cuoco viene a cucinare qualcosa che è un personal max, ma spero che sia illustrativo di una logica che potrebbe funzionare.
Rendiamolo meno conveniente:
$array['a'] = array(0=>75, 1=>50, 2=>0);
$array['b'] = array(0=>100, 1=>50, 2=>50);
$array['c'] = array(0=>100, 1=>25, 2=>25);
Inizia di nuovo con cuoco 'a' e vedere che 0 è preferito, ma questa volta con il peso 25. Cook 'b' preferisce con un peso di 50 e cuocere 'c' preferisce con un peso di 75. Cook 'c' vince il piatto 0.
Tornando all'elenco dei cuochi disponibili, 'a' preferisce 1 con un peso di 50, ma 'b' lo preferisce con il peso 0. 'a' ottiene il piatto 1 e 'b 'ottiene piatto 2.
Questo ancora non si prende cura di tutte le complessità, ma è un passo nella giusta direzione. A volte l'ipotesi fatta per la prima combinazione cuoco/piatto sarà errata.
modo meno conveniente:
$array['a'] = array(0=>200, 1=>148, 2=>148, 3=>0);
$array['b'] = array(0=>200, 1=>149, 2=>0, 3=>0);
$array['c'] = array(0=>200, 1=>150, 2=>147, 3=>147);
$array['d'] = array(0=>69, 1=>18, 2=>16, 3=>15);
'a' ottiene 0 dato che è il massimo e nessun altro che preferisce 0 ha un peso più elevato 'b' vince 1 con un peso di 149 'd' vince 2 poiche 'c' non ha una preferenza tra le opzioni disponibili 'c' ottiene 3
punteggio: 200 + 149 + 147 + 16 = 512
Mentre questo è una buona congettura che è riunito senza controllare ogni permutazione, i potrebbe essere sbagliato Da qui, chiedi: "Se un cuoco commercia con un altro cuoco, l'aumento totale?"
La risposta è sì, un (0) + d (2) = 200 + 16 = 216, ma una (2) + d (0) = 148 + 69 = 217.
lascio a voi di scrivere il codice per la "ipotesi migliore" utilizzando l'approccio ponderato, ma dopo che, qui è un buon inizio per voi:
// a totally uneducated guess...
$picks = array(0=>'a', 1=>'b', 2=>'c', 3=>'d');
do {
$best_change = false;
$best_change_weight = 0;
foreach ($picks as $dish1 => $cook1) {
foreach ($picks as $dish2 => $cook2) {
if (($array[$cook1][$dish1] + $array[$cook2][$dish2]) <
($array[$cook1][$dish2] + $array[$cook2][$dish1]))
{
$old_score = $array[$cook1][$dish1] + $array[$cook2][$dish2];
$new_score = $array[$cook1][$dish2] + $array[$cook2][$dish1];
if (($new_score - $old_score) > $best_change_weight) {
$best_change_weight = $new_score - $old_score;
$best_change = $dish2;
}
}
}
if ($best_change !== false) {
$cook2 = $picks[$best_change];
$picks[$dish1] = $cook2;
$picks[$dish2] = $cook1;
break;
}
}
} while ($best_change !== false);
non riesco a trovare un controesempio per mostrare che questo doesn' lavoro, ma sono sospettoso del caso in cui ($ array [$ cook1] [$ dish1] + $ array [$ cook2] [$ dish2]) == ($ array [$ cook1] [$ dish2 ] + $ array [$ cook2] [$ dish1])
Forse qualcun altro risponderà a questa domanda "E se?"
Data questa matrice, dove gli elementi tra parentesi sono i "picconi"
[a1] a2 a3
b1 [b2] b3
c1 c2 [c3]
Se a1 + b2 == a2 + b1, quindi 'a' e 'b' non passerà piatti. Il caso non sono sicuro al 100% circa è se esiste una matrice tale che questa è una scelta migliore:
a1 [a2] a3
b1 b2 [b3]
[c1] c2 c3
Come dal primo stato al secondo richiede due interruttori, il primo dei quali sembra arbitraria dal non cambia il totale. Ma solo passando attraverso questo cambiamento arbitrario si può fare l'ultimo passaggio.
Ho cercato di trovare un esempio 3x3 tale che in base al modello "preferenza ponderata" di cui sopra ho scritto, il primo sarebbe stato selezionato, ma anche tale che la reale selezione ottimale è data dal secondo. Non ero in grado di trovare un esempio, ma ciò non significa che non esiste. Non mi sento di fare più algebra matriciale adesso, ma forse qualcuno riprenderà da dove ho lasciato. Diamine, forse il caso non esiste, ma ho pensato di dover segnalare la preoccupazione.
Se funziona e si inizia con la scelta corretta, il codice precedente eseguirà solo un ciclo di 64 volte (8x8) per 8 cuochi/piatti. Se il plettro non è corretto e il primo cuoco cambia, passerà a 72. Se l'ottavo cuoco ha una modifica, è fino a 128. È possibile che il do-while esegua il loop più volte, ma dubito si alzerà vicino ai cicli della CPU necessari per sommare tutte le combinazioni 40k.
Se max (N sub-array) = 8, quindi max (perm) = 4^8 = 65536. – HamZa
Da quello che ho capito di questo problema, ogni cuoco può cucinare una sola ricetta, quindi il numero di le permutazioni effettive sono 4 * 3 * 2 * 1 = 4! = 24. Con questo in mente, non sarebbe un tale sforzo per la forza bruta calcolarlo se ci sono solo 4 cuochi/ricette. – Pudge601
Grazie ragazzi! Il mio pensiero è davvero che è 8! quale = 40.320. – Gamemorize