Source code for mex.simplex.problem_definition

import numpy as np
import logging

from mex.utils.general import gen_var, convert_min, convert
from mex.simplex.simplex_networks import pivots_col, find_pivot_col, pivots_row, pivot, find_pivot_row


[docs]def add_cons(matrix): """ Checks if 1 extra constraint can be added to the matrix, this means that there are at least two rows of all 0 elements. If this condition is not satisfied, our program will not allow the user to add additional constraints. Args: matrix (numpy array): matrix to be reviewed. Returns: Flag (bool): True or False indicating whether 1+ constraints can be added. """ lr = len(matrix[:, 0]) empty = [] for i in range(lr): total = 0 for j in matrix[i, :]: total += j**2 if total == 0: empty.append(total) if len(empty) > 1: return True else: return False
[docs]def constrain(matrix, eq, memory_prof=False): """ Adds constraints to the problem. Args: matrix (numpy array): matrix defined with :mod:`create_matrix`. eq (string): coefficients of constraints expressions. Use **L** for *less than*, **G** for *greater than*, **E** for *equal to*. >>> problem_matrix = create_matrix(2,3) # 2 variables and 3 constraints >>> constrain(problem_matrix,'1,L,4') # x_1 <= 4 >>> constrain(problem_matrix,'0,2,L,12') # 2x_2 <= 12 >>> constrain(problem_matrix,'3,2,G,18') # 3x_1 + 2x_2 >= 18 """ if 'E' in eq: if add_cons(matrix): lc = len(matrix[0, :]) lr = len(matrix[:, 0]) var = lc - lr - 1 j = 0 while j < lr: row_check = matrix[j,:] total = 0 for i in row_check: total += float(i**2) if total == 0: row = row_check break j += 1 eq = convert(eq) i = 0 while i<len(eq)-1: row[i] = eq[i] i += 1 row[-1] = eq[-1] #row[var+j] = 1 else: logging.info('Cannot add another constraint.') else: if add_cons(matrix): lc = len(matrix[0, :]) lr = len(matrix[:, 0]) var = lc - lr -1 j = 0 while j < lr: row_check = matrix[j, :] total = 0 for i in row_check: total += float(i**2) if total == 0: row = row_check break j +=1 eq = convert(eq) i = 0 while i<len(eq)-1: row[i] = eq[i] i += 1 row[-1] = eq[-1] row[var+j] = 1 else: logging.info('Cannot add another constraint.') if memory_prof: return matrix
[docs]def add_obj(matrix): """ Verifies if the objective function can be added. Args: matrix (numpy array): matrix to be reviewed. Returns: Flag (bool): True or False indicating whether objective function can be added. """ lr = len(matrix[:,0]) empty = [] for i in range(lr): total = 0 for j in matrix[i, :]: total += j**2 if total == 0: empty.append(total) if len(empty) == 1: return True else: return False
[docs]def obj(matrix,eq, memory_prof=False): """ Adds the objective function to the problem matrix. .. note:: Objective function must be added **after** constraints have been input. Args: matrix (numpy array): matrix defined with :mod:`create_matrix`. eq (string): coefficients of objective function. >>> problem_matrix = create_matrix(2,3) # 2 variables and 3 constraints >>> constrain(problem_matrix,'1,L,4') # x_1 <= 4 >>> constrain(problem_matrix,'0,2,L,12') # 2x_2 <= 12 >>> constrain(problem_matrix,'4,2,G,18') # 4x_1 + 2x_2 >= 18 >>> obj(problem_matrix,'3,5,0') # 3x_1 + 5x_2 """ if add_obj(matrix): eq = [float(i) for i in eq.split(',')] lr = len(matrix[:,0]) row = matrix[lr-1,:] i = 0 while i<len(eq)-1: row[i] = eq[i]*-1 i +=1 row[-2] = 1 row[-1] = eq[-1] else: logging.info('You must finish adding constraints before the objective function can be added.') if memory_prof: return matrix
[docs]def maxz(matrix, aux=True): """ Creates maximization function. Determines if 1 extra pivot is required, locates the pivot element, pivots about it and continues the process until all negative elements have been removed from the last column and row. Args: matrix (numpy array): problem matrix with constraints and objective function added. Returns: *(dict)* A dictionary with Max and variables. >>> problem_matrix = create_matrix(2,3) # 2 variables and 3 constraints >>> constrain(problem_matrix,'1,L,4') # x_1 <= 4 >>> constrain(problem_matrix,'0,2,L,12') # 2x_2 <= 12 >>> constrain(problem_matrix,'4,2,G,18') # 4x_1 + 2x_2 >= 18 >>> obj(problem_matrix,'3,5,0') # 3x_1 + 5x_2 >>> maxz(problem_matrix) {'x1': 4.0, 'x2': 6.0, 'max': 42.0} """ while pivots_col(matrix): matrix = pivot(find_pivot_col(matrix)[0], find_pivot_col(matrix)[1], matrix) while pivots_row(matrix): matrix = pivot(find_pivot_row(matrix)[0], find_pivot_row(matrix)[1], matrix) lc = len(matrix[0, :]) lr = len(matrix[:, 0]) var = lc - lr - 1 i = 0 val = {} for i in range(var): col = matrix[:, i] s = sum(col) m = max(col) if float(s) == float(m): loc = np.where(col == m)[0][0] val[gen_var(matrix)[i]] = matrix[loc, -1] else: val[gen_var(matrix)[i]] = 0 val['max'] = matrix[-1, -1] if aux: return val
[docs]def minz(matrix): """ Creates minimization function. Determines if 1 extra pivot is required, locates the pivot element, pivots about it and continues the process until all negative elements have been removed from the last column and row. Args: matrix (numpy array): problem matrix with constraints and objective function added. Returns: (dict) A dictionary with Min and variables. >>> problem_matrix = create_matrix(2,4) # 2 variables and 4 constraints >>> constrain(problem_matrix,'1,1,L,6') # x_1 + x_2 <= 6 >>> constrain(problem_matrix,'-1,2,L,8') # -x_1 + 2x_2 <= 8 >>> constrain(problem_matrix,'1,G,0') # x_1 >= 0 >>> constrain(problem_matrix,'0,1,G,0') # x_2 >= 0 >>> obj(problem_matrix,'-1,-3,0') # -x_1 - 3x_2 >>> minz(problem_matrix) {'x1': 1.3333333333333333, 'x2': 4.666666666666667} """ matrix = convert_min(matrix) while pivots_col(matrix): matrix = pivot(find_pivot_col(matrix)[0], find_pivot_col(matrix)[1], matrix) while pivots_row(matrix): matrix = pivot(find_pivot_row(matrix)[0], find_pivot_row(matrix)[1], matrix) lc = len(matrix[0, :]) lr = len(matrix[:, 0]) var = lc - lr - 1 i = 0 val = {} for i in range(var): col = matrix[:, i] s = sum(col) m = max(col) if float(s) == float(m): loc = np.where(col == m)[0][0] val[gen_var(matrix)[i]] = matrix[loc, -1] else: val[gen_var(matrix)[i]] = 0 val['min'] = matrix[-1, -1]*-1 return val