mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-25 10:28:39 +00:00
Compare commits
No commits in common. "be44d46bd8456bb0ae5c1342662cd1a69a5e72e6" and "a1acf503d698e53f72fb24e78e26afa981b56d83" have entirely different histories.
be44d46bd8
...
a1acf503d6
@ -4,7 +4,7 @@ tabular form with
|
|||||||
- `>=`, `<=`, and `=` constraints and
|
- `>=`, `<=`, and `=` constraints and
|
||||||
- each variable `x1, x2, ...>= 0`.
|
- each variable `x1, x2, ...>= 0`.
|
||||||
|
|
||||||
See https://gist.github.com/imengus/f9619a568f7da5bc74eaf20169a24d98 for how to
|
See https://gist.github.com/imengus/f9619a568f8da5bc74eaf20169a24d98 for how to
|
||||||
convert linear programs to simplex tableaus, and the steps taken in the simplex
|
convert linear programs to simplex tableaus, and the steps taken in the simplex
|
||||||
algorithm.
|
algorithm.
|
||||||
|
|
||||||
@ -24,45 +24,30 @@ class Tableau:
|
|||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValueError: RHS must be > 0
|
ValueError: RHS must be > 0
|
||||||
|
|
||||||
>>> Tableau(np.array([[-1,-1,0,0,1],[1,3,1,0,4],[3,1,0,1,4.]]), -2, 2)
|
|
||||||
Traceback (most recent call last):
|
|
||||||
...
|
|
||||||
ValueError: number of (artificial) variables must be a natural number
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Maximum number of iterations to prevent cycling
|
def __init__(self, tableau: np.ndarray, n_vars: int, n_art_vars: int) -> None:
|
||||||
maxiter = 100
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, tableau: np.ndarray, n_vars: int, n_artificial_vars: int
|
|
||||||
) -> None:
|
|
||||||
# Check if RHS is negative
|
# Check if RHS is negative
|
||||||
if not (tableau[:, -1] >= 0).all():
|
if np.any(tableau[:, -1], where=tableau[:, -1] < 0):
|
||||||
raise ValueError("RHS must be > 0")
|
raise ValueError("RHS must be > 0")
|
||||||
|
|
||||||
if n_vars < 2 or n_artificial_vars < 0:
|
|
||||||
raise ValueError(
|
|
||||||
"number of (artificial) variables must be a natural number"
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tableau = tableau
|
self.tableau = tableau
|
||||||
self.n_rows, n_cols = tableau.shape
|
self.n_rows, n_cols = tableau.shape
|
||||||
|
|
||||||
# Number of decision variables x1, x2, x3...
|
# Number of decision variables x1, x2, x3...
|
||||||
self.n_vars, self.n_artificial_vars = n_vars, n_artificial_vars
|
self.n_vars, self.n_art_vars = n_vars, n_art_vars
|
||||||
|
|
||||||
# 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
|
# 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
|
||||||
self.n_stages = (self.n_artificial_vars > 0) + 1
|
self.n_stages = (self.n_art_vars > 0) + 1
|
||||||
|
|
||||||
# Number of slack variables added to make inequalities into equalities
|
# Number of slack variables added to make inequalities into equalities
|
||||||
self.n_slack = n_cols - self.n_vars - self.n_artificial_vars - 1
|
self.n_slack = n_cols - self.n_vars - self.n_art_vars - 1
|
||||||
|
|
||||||
# Objectives for each stage
|
# Objectives for each stage
|
||||||
self.objectives = ["max"]
|
self.objectives = ["max"]
|
||||||
|
|
||||||
# In two stage simplex, first minimise then maximise
|
# In two stage simplex, first minimise then maximise
|
||||||
if self.n_artificial_vars:
|
if self.n_art_vars:
|
||||||
self.objectives.append("min")
|
self.objectives.append("min")
|
||||||
|
|
||||||
self.col_titles = self.generate_col_titles()
|
self.col_titles = self.generate_col_titles()
|
||||||
@ -180,7 +165,7 @@ class Tableau:
|
|||||||
return self.tableau
|
return self.tableau
|
||||||
|
|
||||||
# Slice containing ids for artificial columns
|
# Slice containing ids for artificial columns
|
||||||
s = slice(-self.n_artificial_vars - 1, -1)
|
s = slice(-self.n_art_vars - 1, -1)
|
||||||
|
|
||||||
# Delete the artificial variable columns
|
# Delete the artificial variable columns
|
||||||
self.tableau = np.delete(self.tableau, s, axis=1)
|
self.tableau = np.delete(self.tableau, s, axis=1)
|
||||||
@ -190,7 +175,7 @@ class Tableau:
|
|||||||
|
|
||||||
self.n_stages = 1
|
self.n_stages = 1
|
||||||
self.n_rows -= 1
|
self.n_rows -= 1
|
||||||
self.n_artificial_vars = 0
|
self.n_art_vars = 0
|
||||||
self.stop_iter = False
|
self.stop_iter = False
|
||||||
return self.tableau
|
return self.tableau
|
||||||
|
|
||||||
@ -260,7 +245,7 @@ class Tableau:
|
|||||||
{'P': 132.0, 'x1': 12.000... 'x2': 5.999...}
|
{'P': 132.0, 'x1': 12.000... 'x2': 5.999...}
|
||||||
"""
|
"""
|
||||||
# Stop simplex algorithm from cycling.
|
# Stop simplex algorithm from cycling.
|
||||||
for _ in range(Tableau.maxiter):
|
for _ in range(100):
|
||||||
# Completion of each stage removes an objective. If both stages
|
# Completion of each stage removes an objective. If both stages
|
||||||
# are complete, then no objectives are left
|
# are complete, then no objectives are left
|
||||||
if not self.objectives:
|
if not self.objectives:
|
||||||
@ -291,16 +276,16 @@ class Tableau:
|
|||||||
output_dict = {"P": abs(self.tableau[0, -1])}
|
output_dict = {"P": abs(self.tableau[0, -1])}
|
||||||
|
|
||||||
for i in range(self.n_vars):
|
for i in range(self.n_vars):
|
||||||
# Gives indices of nonzero entries in the ith column
|
# Gives ids of nonzero entries in the ith column
|
||||||
nonzero = np.nonzero(self.tableau[:, i])
|
nonzero = np.nonzero(self.tableau[:, i])
|
||||||
n_nonzero = len(nonzero[0])
|
n_nonzero = len(nonzero[0])
|
||||||
|
|
||||||
# First entry in the nonzero indices
|
# First entry in the nonzero ids
|
||||||
nonzero_rowidx = nonzero[0][0]
|
nonzero_rowidx = nonzero[0][0]
|
||||||
nonzero_val = self.tableau[nonzero_rowidx, i]
|
nonzero_val = self.tableau[nonzero_rowidx, i]
|
||||||
|
|
||||||
# If there is only one nonzero value in column, which is one
|
# If there is only one nonzero value in column, which is one
|
||||||
if n_nonzero == 1 and nonzero_val == 1:
|
if n_nonzero == nonzero_val == 1:
|
||||||
rhs_val = self.tableau[nonzero_rowidx, -1]
|
rhs_val = self.tableau[nonzero_rowidx, -1]
|
||||||
output_dict[self.col_titles[i]] = rhs_val
|
output_dict[self.col_titles[i]] = rhs_val
|
||||||
return output_dict
|
return output_dict
|
||||||
|
Loading…
x
Reference in New Issue
Block a user