Folosind metoda de programare liniară implexă pentru a rezolva problema dietei dat un set de alimente cu
| # include algoritmul> |
| # include iostream> |
| # include vector> |
| # include cstdio> |
| # include cassert> |
| utilizarea spațiului de nume std; |
| typedef ElementType dublu; |
| vector typedef> matrice; |
| const int NO_SOLUTION = - 1; |
| const int BOUNDED_SOLUTION = 0; |
| const int INFINITY_SOLUTION = 1; |
| const ElementType C_THRESHOLD = 0,0000001; |
| const ElementType DELTA_RATIO_THRESHOLD = 0; // 0,0001; |
| const ElementType DELTA_COMPARE_EPSILON = 0.0000001; |
| // implementează PIVOT din CLRS |
| pivot nul ( |
| vector int> & nonbasics, |
| vector int> & elemente de bază, |
| matrice & A, |
| vector & b, |
| vector etc., |
| ElementType & v, |
| int l, |
| int e) |
| // în CLRS, acesta este N - |
| vector int> otherNonbasics; |
| pentru (int n: nonbasics) |
| dacă (n! = e) |
| otherNonbasics. push_back (n); |
| > |
| > |
| // variabilele e & l furnizează indicii variabilelor de intrare și ieșire, dar |
| // nu sunt la fel ca rândul din A care va fi procesat. row_l furnizează această mapare |
| // (aka, rândul din A care reprezintă în prezent variabila de bază x [l]) |
| int rând_l = - 1; |
| pentru (size_t i = 0; i size (); ++ i) |
| if (elemente de bază [i] == l) |
| rând_l = i; |
| pauză; |
| > |
| > |
| // calculați coeficienții ecuației pentru noua variabilă de bază x [e]. |
| // cu alte cuvinte, rezolvăm pentru x [e] folosind constrângerea indexată de l. |
| // pentru a face acest lucru, scalăm constrângerea împărțind la A [l] [e], care stabilește coeficientul |
| // în A în constrângerea l pentru x [e] la 1.0 și rezolvă efectiv pentru aceasta |
| b [rând_l] = b [rând_l]/A [rând_l] [e]; |
| pentru (int j: otherNonbasics) |
| A [row_l] [j] = A [row_l] [j]/A [row_l] [e]; |
| > |
| A [rând_l] [l] = 1,0/A [rând_l] [e]; |
| A [rând_l] [e] = 0,0; |
| // calculați coeficienții restrângerilor rămase. |
| // În mod eficient, aceasta actualizează constrângerile care nu sunt indexate de l |
| // prin înlocuirea RHS a ecuației cu x [e] în fiecare constrângere |
| // pentru fiecare apariție a x [e] |
| pentru (size_t i = 0; i size (); ++ i) |
| if (i == rând_l) |
| continua; |
| > |
| b [i] - = A [i] [e] * b [rând_l]; |
| pentru (int j: otherNonbasics) |
| A [i] [j] - = A [i] [e] * A [row_l] [j]; |
| > |
| A [i] [l] = -A [i] [e] * A [rând_l] [l]; |
| A [i] [e] = 0,0; |
| > |
| // calculează funcția obiectivă |
| // prin substituirea în constrângere l (rezolvat pentru x [e]) |
| v + = c [e] * b [rând_l]; |
| pentru (int j: otherNonbasics) |
| c [j] - = c [e] * A [rând_l] [j]; |
| > |
| c [l] = -c [e] * A [rând_l] [l]; |
| c [e] = 0,0; |
| // calculați seturi noi de variabile de bază și non-bazice schimbând e & l |
| pentru (size_t n = 0; n size (); ++ n) |
| if (nonbasics [n] == e) |
| nonbasics [n] = l; |
| pauză; |
| > |
| > |
| pentru (size_t n = 0; n size (); ++ n) |
| if (elemente de bază [n] == l) |
| elemente de bază [n] = e; |
| pauză; |
| > |
| > |
| întoarcere; |
| > |
| typedef struct SlackForm |
| vector int> nonbasics, elemente de bază; |
| matricea A; |
| vectorul b, c; |
| ElementType v; |
| > SlackForm; |
| șablon typename T> |
| std: ostream & operator const vector & v) |
| afară " < "; |
| pentru (size_t i = 0; i size (); ++ i) |
| afară dacă (i! = v. mărime () - 1) |
| afară ","; |
| > |
| > |
| afară ">"; |
| întoarce-te; |
| > |
| std: ostream & operator "N =" nonbasics "B =" noțiuni de bază "A = < "; |
| pentru (vector și rând: s. A) |
| out ">" "b =" b "c =" c "v =" v return out; |
| > |
| pair int, vector> SimplexIterations (SlackForm & slack) |
| vector int> |
| & nonbasics = slăbiciune. non-de bază, |
| & de bază = slăbiciune. elemente de bază; |
| matrice & A = slack. A; |
| vector |
| & b = slăbiciune. b, |
| & c = slăbiciune. c; |
| ElementType & v = slack. v; |
| // aceasta implementează liniile 2 - 17 ale SIMPLEX din CLRS |
| vector delta (elemente de bază. size (), std: limite_numerice: infinit ()); |
| for (vector: iterator j = std: max_element (c. begin (), c. end ()); |
| * j> C_THRESHOLD; |
| j = std: max_element (c. begin (), c. end ())) |
| int e = std: distance (c. begin (), j); |
| // alegeți l, indexul variabilelor care vor fi variabila de plecare. |
| // faceți acest lucru văzând care dintre constrângeri permite cea mai mare valoare a |
| // x [e] în timp ce nu încalcă constrângerile de non-negativitate de pe x |
| pentru (size_t i = 0; i size (); ++ i) |
| delta [i] = (A [i] [e]> DELTA_RATIO_THRESHOLD)? b [i]/A [i] [e]: std: numeric_limits: infinity (); |
| > |
| // găsește acum „cea mai mică” deltă, dar există un factor fudge pentru „cravate”. Dacă delta [i] = |
Nu puteți efectua acțiunea în acest moment.

V-ați conectat cu o altă filă sau fereastră. Reîncărcați pentru a reîmprospăta sesiunea. V-ați deconectat într-o altă filă sau fereastră. Reîncărcați pentru a reîmprospăta sesiunea.