Використання лінійного програмуванняпростий метод для вирішення дієтичної задачі з урахуванням набору продуктів з
| # включити алгоритм> |
| # включають iostream> |
| # включає вектор> |
| # включає cstdio> |
| # включає cassert> |
| використання простору імен std; |
| typedef double ElementType; |
| typedef вектор> матриця; |
| 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; |
| // реалізує PIVOT від CLRS |
| порожній шарнір ( |
| вектор int> & неосновні, |
| вектор int> & основи, |
| матриця & A, |
| вектор & b, |
| вектор & c, |
| Тип елемента & v, |
| int l, |
| int e) |
| // в CLRS це N - |
| вектор int> otherNonbasics; |
| для (int n: nonbasics) |
| якщо (n! = e) |
| іншеНеоснови. push_back (n); |
| > |
| > |
| // змінні e & l надають індекси змінних, що входять і виходять, але |
| // вони не збігаються з рядком в А, який буде оброблено. row_l забезпечує це відображення |
| // (він же рядок в A, який на даний момент являє собою основну змінну x [l]) |
| int row_l = - 1; |
| для (size_t i = 0; i size (); ++ i) |
| if (основи [i] == l) |
| рядок_l = i; |
| перерву; |
| > |
| > |
| // обчислюємо коефіцієнти рівняння для нової базової змінної x [e]. |
| // іншими словами, ми вирішуємо для x [e], використовуючи обмеження, проіндексоване l. |
| // для цього ми масштабуємо обмеження шляхом ділення на A [l] [e], яке встановлює коефіцієнт |
| // в A з обмеженням l для x [e] до 1,0 і ефективно вирішує це |
| b [рядок_l] = b [рядок_l]/A [рядок_l] [е]; |
| для (int j: otherNonbasics) |
| A [рядок_l] [j] = A [рядок_l] [j]/A [рядок_l] [e]; |
| > |
| A [рядок_l] [l] = 1,0/A [рядок_l] [e]; |
| A [рядок_l] [е] = 0,0; |
| // обчислюємо коефіцієнти решти обмежень. |
| // Фактично це оновлює обмеження, не проіндексовані l |
| // шляхом підстановки RHS рівняння на x [e] у кожне обмеження |
| // для кожного входження x [e] |
| для (size_t i = 0; i size (); ++ i) |
| якщо (i == рядок_l) |
| продовжувати; |
| > |
| b [i] - = A [i] [e] * b [рядок_l]; |
| для (int j: otherNonbasics) |
| A [i] [j] - = A [i] [e] * A [рядок_l] [j]; |
| > |
| A [i] [l] = -A [i] [e] * A [рядок_l] [l]; |
| A [i] [e] = 0,0; |
| > |
| // обчислюємо цільову функцію |
| // шляхом підстановки в обмеження l (вирішено для x [e]) |
| v + = c [e] * b [рядок_l]; |
| для (int j: otherNonbasics) |
| c [j] - = c [e] * A [рядок_l] [j]; |
| > |
| c [l] = -c [e] * A [рядок_l] [l]; |
| c [e] = 0,0; |
| // обчислюємо нові набори основних та неосновних змінних, обмінюючи e & l |
| для (size_t n = 0; n size (); ++ n) |
| якщо (не основне [n] == e) |
| неосновні [n] = l; |
| перерву; |
| > |
| > |
| для (size_t n = 0; n size (); ++ n) |
| if (основи [n] == l) |
| основи [n] = e; |
| перерву; |
| > |
| > |
| повернення; |
| > |
| typedef struct SlackForm |
| вектор int> не основи, основи; |
| матриця A; |
| вектор b, c; |
| ElementType v; |
| > SlackForm; |
| шаблон типу ім'я T> |
| std: ostream & operator const vector & v) |
| з " < "; |
| для (size_t i = 0; i size (); ++ i) |
| out if (i! = v. size () - 1) |
| вийти ","; |
| > |
| > |
| вихід ">"; |
| повернутися; |
| > |
| std: ostream & operator "N =" nonbasics "B =" basics "A = < "; |
| для (вектор і рядок: с. А) |
| out ">" "b =" b "c =" c "v =" v повернутися; |
| > |
| пара int, vector> SimplexIterations (SlackForm & slack) |
| вектор int> |
| & nonbasics = слабість. неосновні, |
| & basics = слабість. основи; |
| матриця & A = слабість. A; |
| вектор |
| & b = слабість. b, |
| & c = слабість. c; |
| Тип елемента & v = слабкий. v; |
| // це реалізує рядки 2 - 17 SIMPLEX від CLRS |
| вектор дельта (основи. розмір (), std: numeric_limits: infinity ()); |
| 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); |
| // вибираємо l, індекс змінних, які будуть змінною, що залишається. |
| // робимо це, бачачи, яке з обмежень допускає найбільше значення |
| // x [e], не порушуючи обмежень щодо невід'ємності для x |
| для (size_t i = 0; i size (); ++ i) |
| дельта [i] = (A [i] [e]> DELTA_RATIO_THRESHOLD)? b [i]/A [i] [e]: std: numeric_limits: infinity (); |
| > |
| // тепер знаходимо "найменшу" дельту, але для "зв’язків" існує фактор хитрості. Якщо дельта [i] = |
Зараз ви не можете виконати цю дію.

Ви ввійшли з іншої вкладки чи вікна. Оновіть, щоб оновити сеанс. Ви вийшли з іншої вкладки чи вікна. Оновіть, щоб оновити сеанс.