A szimplex algoritmus, más néven szimplex módszer a lineáris programok optimumának megtalálására szolgáló, egyben annak létezését is vizsgáló módszer. Használják linearizált nemlineáris programok megoldására is. Műveletideje akár exponenciális is lehet, mivel csúcsról csúcsra jár, és egy konvex poliédernek exponenciálisan sok csúcsa lehet. Erre példa a kocka.
Bizonyítható vele az az állítás is, hogy ha az , rendszernek akkor és csak akkor van olyan megoldása, amelyben A x pozitív változóinak megfelelő oszlopai lineárisan függetlenek, ha nincs olyan y, hogy , , és A-nak van rang(A,b)-1 független oszlopa, amire y merőleges. Röviden, vagy a primál, vagy a duál feladatnak van bázismegoldása. Általánosabb alakra is kiterjeszthető; ha például vannak egyenlőségek is, akkor az egyenlőségeket leíró P mátrixból annyi oszlopot teszünk a bázisba, amennyit csak lehet. A továbbiakban ezek az oszlopok nem mozognak.
A szimplex algoritmus (vagy szimplex módszer) egy olyan matematikai eljárás, amelyet a lineáris programozásban használnak optimalizálási feladatok megoldására. A módszert George Dantzig fejlesztette ki 1947-ben, és a lineáris egyenletek vagy egyenlőtlenségek közötti maximális vagy minimális érték keresésére szolgál. A szimplex algoritmus célja, hogy megtalálja a legjobb (optimális) megoldást a lineáris programozási problémákhoz.
A szimplex módszer a lineáris programozás keretében működik, amely a következő általános formát öleli fel:
A cél a célfüggvény optimalizálása a kölcsönösen korlátozó feltételek mellett.
A szimplex algoritmus a következő lépésekben működik:
Előnyök: - A szimplex algoritmus gyorsan és hatékonyan találja meg a lineáris programozás optimális megoldását. - Jól alkalmazható nagyobb problémák esetén, ahol a lineáris egyenletek és egyenlőtlenségek komplexek.
Hátrányok: - Bár a szimplex algoritmus általában gyors, egyes esetekben, különösen degenerált problémáknál, az algoritmus lelassulhat vagy hosszú iterációkat igényelhet. - Az optimális megoldás keresése nem mindig garantált, ha a probléma nem jól van felépítve.
A szimplex algoritmust széles körben használják a gazdaságban és az iparban különböző optimalizálási problémák megoldására, például: - Gazdasági Modellezés: A vállalatok termelési és erőforrás-allokációs problémáit oldják meg. - Logisztika: Szállítási és raktározási problémák, mint a költségek minimalizálása. - Pénzügyi Kockázatkezelés: Portfóliók optimalizálása, kockázatkezelési stratégiák kidolgozása.
A következő lineáris programozási problémát szeretnénk megoldani:
Maximalizáljuk:
Korlátozó feltételek:
from scipy.optimize import linprog
# Célfüggvény koefficiensei
# Mivel a SciPy minimizálja a célfüggvényt, az optimalizálás miatt a maximalizálásnál a változókat negatívra kell venni
c = # Maximális Z = 3x1 + 2x2, ezért a negatív értékek
# Korlátozó egyenlőtlenségek
A = , # x1 + x2 <= 4
] # 2x1 + x2 <= 5
b = # A jobb oldali értékek: 4 és 5
# Változók nemnegativitásának biztosítása
x0_bounds = (0, None)
x1_bounds = (0, None)
# Szimplex algoritmus alkalmazása
result = linprog(c, A_ub=A, b_ub=b, bounds=, method='simplex')
# Eredmény kiírása
print("Optimalizált célfüggvény értéke (max Z):", -result.fun) # Ne felejtsük el visszaalakítani a maximalizálásra
print("Optimális megoldás (x1, x2):", result.x)
A kód futtatásával az optimalizált célfüggvényt és a változók optimális értékeit kapjuk. A példában az optimalizált célfüggvény értéke és az optimális értékek kerülnek visszaadásra.
Optimalizált célfüggvény értéke (max Z): 13.0 Optimális megoldás (x1, x2):
Ez azt jelenti, hogy a maximális akkor érhető el, amikor és .
Input: Coefficient matrix A, RHS vector b, Objective coefficients c Output: Optimal solution x and maximum objective value z 1. Initialize: - Form the initial simplex tableau with slack variables. - Identify basic and non-basic variables. 2. Repeat until optimality is reached: a. Check the z-row (reduced costs): - If all reduced costs are ? 0 › Optimal solution found. Exit loop. - Otherwise, select the most negative reduced cost as the entering variable. b. Apply the minimum ratio rule: - For each row, calculate: Ratio = RHS / Coefficient of entering variable - Choose the row with the smallest positive ratio › Leaving variable. c. Perform Pivoting: - Normalize the pivot row (divide by pivot element). - Adjust other rows to zero out the entering variable column. 3. Update the tableau and repeat until no negative reduced costs remain. 4. Output the optimal solution and the objective value.
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
// Function to print the Simplex tableau
void printTableau(const vector<vector<double>>& tableau) {
cout << "\nSimplex Tableau:\n";
for (const auto& row : tableau) {
for (double val : row) {
cout << setw(10) << fixed << setprecision(2) << val << " ";
}
cout << endl;
}
cout << endl;
}
// Function to find the column with the most negative reduced cost
int findEnteringVariable(const vector<double>& lastRow) {
int col = -1;
double minVal = 0;
for (int j = 0; j < lastRow.size() - 1; j++) {
if (lastRow < minVal) {
minVal = lastRow;
col = j;
}
}
return col;
}
// Function to find the leaving variable using the minimum ratio rule
int findLeavingVariable(const vector<vector<double>>& tableau, int enteringCol) {
int row = -1;
double minRatio = 1e9;
for (int i = 0; i < tableau.size() - 1; i++) {
double rhs = tableau.back();
double coeff = tableau;
if (coeff > 0) {
double ratio = rhs / coeff;
if (ratio < minRatio) {
minRatio = ratio;
row = i;
}
}
}
return row;
}
// Function to perform pivoting
void pivot(vector<vector<double>>& tableau, int pivotRow, int pivotCol) {
double pivotElement = tableau;
// Normalize the pivot row
for (double& val : tableau) {
val /= pivotElement;
}
// Zero out the pivot column in other rows
for (int i = 0; i < tableau.size(); i++) {
if (i != pivotRow) {
double factor = tableau;
for (int j = 0; j < tableau.size(); j++) {
tableau -= factor * tableau;
}
}
}
}
// Main Simplex Algorithm
void simplex(vector<vector<double>>& tableau) {
while (true) {
printTableau(tableau);
// Step 1: Find entering variable (most negative reduced cost)
int enteringCol = findEnteringVariable(tableau.back());
if (enteringCol == -1) {
cout << "Optimal solution reached!\n";
break;
}
// Step 2: Find leaving variable (minimum ratio rule)
int leavingRow = findLeavingVariable(tableau, enteringCol);
if (leavingRow == -1) {
cout << "Unbounded solution!\n";
return;
}
// Step 3: Perform pivoting
pivot(tableau, leavingRow, enteringCol);
cout << "Pivoting: Entering variable (col " << enteringCol
<< "), Leaving variable (row " << leavingRow << ")\n";
}
// Display final solution
cout << "\nOptimal Solution Found:\n";
for (int i = 0; i < tableau.size() - 1; i++) {
cout << "Product " << i + 1 << " (x" << i + 1 << ") = " << tableau.back() << " units\n";
}
cout << "Maximum Objective Value (Profit) = " << tableau.back().back() << endl;
}
int main() {
int numProducts, numResources;
// Get number of products and resources
cout << "Enter the number of products: ";
cin >> numProducts;
cout << "Enter the number of resources: ";
cin >> numResources;
vector<double> profit(numProducts);
vector<double> capacity(numResources);
vector<vector<double>> resourceRequirement(numResources, vector<double>(numProducts));
// Input profit per product
cout << "\nEnter the profit per unit for each product:\n";
for (int i = 0; i < numProducts; i++) {
cout << "Profit for Product " << i + 1 << ": ";
cin >> profit;
}
// Input resource capacities
cout << "\nEnter the capacity of each resource:\n";
for (int i = 0; i < numResources; i++) {
cout << "Capacity for Resource " << i + 1 << ": ";
cin >> capacity;
}
// Input resource requirements per product
cout << "\nEnter the resource requirements for each product (how much of each resource each product consumes):\n";
for (int i = 0; i < numResources; i++) {
cout << "Resource " << i + 1 << " requirements per product:\n";
for (int j = 0; j < numProducts; j++) {
cout << "Product " << j + 1 << ": ";
cin >> resourceRequirement;
}
}
// Create the Simplex tableau
vector<vector<double>> tableau(numResources + 1, vector<double>(numProducts + numResources + 1, 0));
// Fill the tableau with constraints
for (int i = 0; i < numResources; i++) {
for (int j = 0; j < numProducts; j++) {
tableau = resourceRequirement;
}
tableau = 1; // Slack variable
tableau.back() = capacity; // RHS value (capacity)
}
// Objective function (profit)
for (int j = 0; j < numProducts; j++) {
tableau = -profit; // Negative for maximization
}
// Run Simplex method
simplex(tableau);
return 0;
}
import numpy as np
def print_tableau(tableau):
"""Print the current simplex tableau."""
print("\nSimplex Tableau:")
for row in tableau:
print(" ".join(f"{val:10.2f}" for val in row))
print()
def find_entering_variable(last_row):
"""Find the column index of the most negative reduced cost (entering variable)."""
min_val = 0
col = -1
for j in range(len(last_row) - 1):
if last_row < min_val:
min_val = last_row
col = j
return col
def find_leaving_variable(tableau, entering_col):
"""Find the row index of the leaving variable using the minimum ratio test."""
min_ratio = float('inf')
row = -1
for i in range(len(tableau) - 1):
rhs = tableau
coeff = tableau
if coeff > 0:
ratio = rhs / coeff
if ratio < min_ratio:
min_ratio = ratio
row = i
return row
def pivot(tableau, pivot_row, pivot_col):
"""Perform the pivot operation to update the simplex tableau."""
pivot_element = tableau
# Normalize the pivot row
tableau /= pivot_element
# Zero out the pivot column in other rows
for i in range(tableau.shape):
if i != pivot_row:
factor = tableau
tableau -= factor * tableau
def simplex(tableau):
"""Run the Simplex method to find the optimal solution."""
while True:
print_tableau(tableau)
# Step 1: Find entering variable (most negative reduced cost)
entering_col = find_entering_variable(tableau)
if entering_col == -1:
print("Optimal solution reached!")
break
# Step 2: Find leaving variable (minimum ratio rule)
leaving_row = find_leaving_variable(tableau, entering_col)
if leaving_row == -1:
print("Unbounded solution!")
return
# Step 3: Perform pivoting
pivot(tableau, leaving_row, entering_col)
print(f"Pivoting: Entering variable (col {entering_col}), Leaving variable (row {leaving_row})")
# Display final solution
print("\nOptimal Solution Found:")
for i in range(tableau.shape - 1):
print(f"Product {i + 1} (x{i + 1}) = {tableau:.2f} units")
print(f"Maximum Objective Value (Profit) = {tableau:.2f}")
def main():
"""Main function to run the production problem with Simplex method."""
# User input for number of products and resources
num_products = int(input("Enter the number of products: "))
num_resources = int(input("Enter the number of resources: "))
# Profit per product
print("\nEnter the profit per unit for each product:")
profit =
# Resource capacity
print("\nEnter the capacity of each resource:")
capacity =
# Resource requirements per product
print("\nEnter the resource requirements for each product (each resource per product):")
resource_requirements = np.zeros((num_resources, num_products))
for i in range(num_resources):
print(f"\nResource {i + 1} requirements per product:")
for j in range(num_products):
resource_requirements = float(input(f" Product {j + 1}: "))
# Create simplex tableau
tableau = np.zeros((num_resources + 1, num_products + num_resources + 1))
# Fill the tableau with constraints
for i in range(num_resources):
tableau = resource_requirements
tableau = 1 # Slack variable
tableau = capacity # RHS (capacity)
# Objective function row (profit)
tableau = -np.array(profit) # Negative for maximization
# Solve using Simplex method
simplex(tableau)
if __name__ == "__main__":
main()