Simplex Algorithm – Tabular Method

16 May, 2020
Simplex Algorithm is a well-known optimization technique in Linear Programming.The general form of an LPP (Linear Programming Problem) is
Example: Let’s consider the following maximization problem.Initial construction steps :
Build your matrix A. A will contain the coefficients of the constraints.
Matrix b will contain the amount of resources.
And matrix c will contain the coefficients of objective function or cost.
For the above problem –Matrix A – At Iteration 0
At Iteration 0
Simplex Algorithm
1. Start with the initial basis associated with identity matrix.
2. Calculate the relative profits. 

For MAX problem-
If all the relative profits are less than or equal to 0, then the current basis is the optimal one. STOP.
Else continue to 3.

For MIN problem 
If all the relative profits are greater than or equal to 0, then the current basis is the optimal one. STOP.
Else continue to 3.

3. Find the column corresponding to max relative profit. Say column k has the max 
Rel. profit. So xk will enter the basis.

4. Perform a min ratio test to determine which variable will leave the basis.
 
Index of the min element i.e 'r' will determine the leaving variable.
The basic variable at index r, will leave the basis. 
NOTE: Min ratio test is always performed on positive elements.

5. It's evident that the entered variable will not form an identity matrix, so 
we will have to perform row operations to make it identity again.
Find the pivot element. The element at index (r, k) will be the pivot element and 
row r will be the pivot row. 

6. Divide the rth row by pivot to make it 1. And subtract c*(rth row) from other 
rows to make them 0, where c is the coefficient required to make that row 0.

Table at Iteration 1
Table at iteration 1
Calculation of relative profits – (Cj – Zj), where Cj is the coefficient in Z and Zj is yi*CBC1 – Z1 = 1 – (1*0 + 2*0)C2 – Z2 = 1 – (1*0 + 1*0)C3 – Z3 = 0 – (0*0 + 1*0)C4 – Z4 = 0 – (1*0 + 0*0)
So Relative profits are- 1, 1, 0, 0 (As shown in the table)Clearly not all the relative profits are less or equal to 0. So will perform the next iteration.Determination of entering variable and leaving variable.Max relative profit 1 at index 1. So x1 will enter the basis.Min of (8, 5) is 5 which is at index 2. So x3 will leave the basis.
Since x1 entered perform required row operations to make an identity matrix.
Pivot index = [2, 4]Pivot element = 2
Divide the 2nd row by pivot element i.e 2 to make it 1.And subtract 1*R2 from R1 to make it 0See the next table.
Table At Iteration 2
Table at iteration 2
Relative profits = 0, 1/2, -1/2, 0Pivot index = [1, 5]Pivot element = 1/2Perform necessary row operations.See next table
Table At iteration 3
Following cases can occur while performing this algorithm.
Case 1 – Unbounded SolutionIf the column corresponding to the max relative profit contains only non-positive real numbers then we won’t be able to perform the min ratio test. Therefore it is reported as unbounded solution.
Case 2 – Alternate SolutionIf at any iteration any one of the non-basic variable’s relative profit comes out to be 0, then it contains alternate solutions. Many optimal solutions will exist.
Example 2The above example was an equality case where we were able to find the initial basis. Now we will perform simplex on an example where there is no identity forming.Convert the above problem into standard form i.ewhere x3, x4 and x5 are slack variables. These will form identity and hence the initial basis.Table at Iteration 0
Table at iteration 0
Now continuing as the previous example.Table at iteration 1
Table at iteration 1
Table at Iteration 2
Table at iteration 2
Table at iteration 3
Table at iteration 3
Code Implementation of Simplex Algorithm
import numpy as np from fractions import Fraction # so that numbers are not displayed in decimal.  print("\n                 ****SiMplex Algorithm ****\n\n")  # inputs   # A will contain the coefficients of the constraintsA = np.array([[1, 1, 0, 1], [2, 1, 1, 0]])# b will contain the amount of resources b = np.array([8, 10])           # c will contain coefficients of objective function Z      c = np.array([1, 1, 0, 0])               # B will contain the basic variables that make identity matrixcb = np.array(c[3])B = np.array([[3], [2]])           # cb contains their corresponding coefficients in Z   cb = np.vstack((cb, c[2]))        xb = np.transpose([b])                 # combine matrices B and cbtable = np.hstack((B, cb))             table = np.hstack((table, xb))         # combine matrices B, cb and xb# finally combine matrix A to form the complete simplex tabletable = np.hstack((table, A))         # change the type of table to floattable = np.array(table, dtype ='float') # inputs end  # if min problem, make this var 1MIN = 0  print("Table at itr = 0")print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")for row in table:    for el in row:                # limit the denominator under 100        print(Fraction(str(el)).limit_denominator(100), end ='\t')     print()print()print("Simplex Working....")  # when optimality reached it will be made 1reached = 0     itr = 1unbounded = 0alternate = 0  while reached == 0:      print("Iteration: ", end =' ')    print(itr)    print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")    for row in table:        for el in row:            print(Fraction(str(el)).limit_denominator(100), end ='\t')        print()      # calculate Relative profits-> cj - zj for non-basics    i = 0    rel_prof = []    while i<len(A[0]):        rel_prof.append(c[i] - np.sum(table[:, 1]*table[:, 3 + i]))        i = i + 1      print("rel profit: ", end =" ")    for profit in rel_prof:        print(Fraction(str(profit)).limit_denominator(100), end =", ")    print()    i = 0          b_var = table[:, 0]    # checking for alternate solution    while i<len(A[0]):        j = 0        present = 0        while j<len(b_var):            if int(b_var[j]) == i:                present = 1                break;            j+= 1        if present == 0:            if rel_prof[i] == 0:                alternate = 1                print("Case of Alternate found")                # print(i, end =" ")        i+= 1    print()    flag = 0    for profit in rel_prof:        if profit>0:            flag = 1            break        # if all relative profits <= 0    if flag == 0:        print("All profits are <= 0, optimality reached")        reached = 1        break      # kth var will enter the basis    k = rel_prof.index(max(rel_prof))    min = 99999    i = 0;    r = -1    # min ratio test (only positive values)    while i<len(table):        if (table[:, 2][i]>0 and table[:, 3 + k][i]>0):             val = table[:, 2][i]/table[:, 3 + k][i]            if val<min:                min = val                r = i     # leaving variable        i+= 1          # if no min ratio test was performed    if r ==-1:        unbounded = 1        print("Case of Unbounded")        break      print("pivot element index:", end =' ')    print(np.array([r, 3 + k]))      pivot = table[r][3 + k]    print("pivot element: ", end =" ")    print(Fraction(pivot).limit_denominator(100))                  # perform row operations    # divide the pivot row with the pivot element    table[r, 2:len(table[0])] = table[            r, 2:len(table[0])] / pivot                  # do row operation on other rows    i = 0    while i<len(table):        if i != r:            table[i, 2:len(table[0])] = table[i,                 2:len(table[0])] - table[i][3 + k] *                  table[r, 2:len(table[0])]        i += 1            # assign the new basic variable    table[r][0] = k    table[r][1] = c[k]          print()    print()    itr+= 1        print()  print("***************************************************************")if unbounded == 1:    print("UNBOUNDED LPP")    exit()if alternate == 1:    print("ALTERNATE Solution")  print("optimal table:")print("B \tCB \tXB \ty1 \ty2 \ty3 \ty4")for row in table:    for el in row:        print(Fraction(str(el)).limit_denominator(100), end ='\t')    print()print()print("value of Z at optimality: ", end =" ")  basis = []i = 0sum = 0while i<len(table):    sum += c[int(table[i][0])]*table[i][2]    temp = "x"+str(int(table[i][0])+1)    basis.append(temp)    i+= 1# if MIN problem make z negativeif MIN == 1:    print(-Fraction(str(sum)).limit_denominator(100))else:    print(Fraction(str(sum)).limit_denominator(100))print("Final Basis: ", end =" ")print(basis)  print("Simplex Finished...")print()
For the above just plug in the required values and you will get a detailed step by step solution of your LPP by the simplex algorithm.
choudharyshreyansh27
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Install PIP on Windows ?
Python Classes and Objects
Python | os.path.join() method
Python OOPs Concepts
How to drop one or multiple columns in Pandas Dataframe
Introduction To PYTHON
How To Convert Python Dictionary To JSON?
Check if element exists in list in Python
Python | datetime.timedelta() function
Python | Get unique values from a list