Работа готова
This commit is contained in:
commit
ba713dca25
BIN
misc/task.jpg
Normal file
BIN
misc/task.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
13
readme.md
Normal file
13
readme.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Лабораторная работа №1 по ВМ
|
||||||
|
|
||||||
|
___
|
||||||
|
|
||||||
|
## Состав команды №4 (ПИбд-33):
|
||||||
|
|
||||||
|
- ### Полевой Сергей
|
||||||
|
- ### Мочалов Данила
|
||||||
|
- ### Минхасапов Руслан
|
||||||
|
|
||||||
|
## Задание:
|
||||||
|
|
||||||
|
![Картинка задания](misc/task.jpg)
|
163
src/main.py
Normal file
163
src/main.py
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from utils import *
|
||||||
|
|
||||||
|
|
||||||
|
class SimplexColumn:
|
||||||
|
def __init__(self, coefficient: float, variable: Variable, values: list[float]):
|
||||||
|
self.coefficient: float = coefficient
|
||||||
|
self.variable: Variable = variable
|
||||||
|
self.inner: list[float] = values
|
||||||
|
self.delta: float | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class Simplex:
|
||||||
|
def __init__(self, equations: list[Equation], function: Function):
|
||||||
|
self.function: Function = function
|
||||||
|
self.equations: list[Equation] = equations
|
||||||
|
self.variables: set[Variable] = set(literal.var for equation in equations for literal in equation.literals)
|
||||||
|
|
||||||
|
self.b_variable: Variable = Variable("b")
|
||||||
|
|
||||||
|
self.columns: list[SimplexColumn] = [
|
||||||
|
SimplexColumn(
|
||||||
|
next(filter(lambda l: l.var == var, self.function.literals)).a,
|
||||||
|
var,
|
||||||
|
list(
|
||||||
|
next(
|
||||||
|
filter(
|
||||||
|
lambda l: l.var == var,
|
||||||
|
equation.literals
|
||||||
|
)
|
||||||
|
).a
|
||||||
|
for equation in self.equations
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for var in sorted(self.variables)
|
||||||
|
] + [SimplexColumn(0, self.b_variable, [equation.b for equation in equations])]
|
||||||
|
|
||||||
|
self.base: list[Variable] = [
|
||||||
|
var
|
||||||
|
for var in list(OrderedDict.fromkeys(literal.var for equation in equations for literal in equation.literals))
|
||||||
|
if sum(self.column_by_var(var).inner) == 1
|
||||||
|
]
|
||||||
|
|
||||||
|
def compute_deltas(self):
|
||||||
|
for column in self.columns:
|
||||||
|
column.delta = sum(
|
||||||
|
col.coefficient * val
|
||||||
|
for (col, val) in zip((self.column_by_var(base)
|
||||||
|
for base in self.base),
|
||||||
|
column.inner
|
||||||
|
)
|
||||||
|
) - column.coefficient
|
||||||
|
|
||||||
|
def iteration(self) -> bool:
|
||||||
|
main_column = self.max_delta_column()
|
||||||
|
|
||||||
|
if abs(main_column.delta) <= 0.00000000001:
|
||||||
|
return False
|
||||||
|
|
||||||
|
main_column_values = main_column.inner.copy()
|
||||||
|
main_row_index = self.min_q_row()
|
||||||
|
|
||||||
|
self.base[main_row_index] = main_column.variable
|
||||||
|
|
||||||
|
for column in self.columns:
|
||||||
|
column.inner[main_row_index] /= main_column_values[main_row_index]
|
||||||
|
|
||||||
|
for row in filter(lambda x: x != main_row_index, range(len(self.base))):
|
||||||
|
for column in self.columns:
|
||||||
|
column.inner[row] -= main_column_values[row] * column.inner[main_row_index]
|
||||||
|
|
||||||
|
self.compute_deltas()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def min_q_row(self) -> int:
|
||||||
|
pairs = filter(
|
||||||
|
lambda x: x[1] > 0,
|
||||||
|
zip(
|
||||||
|
range(len(self.base)),
|
||||||
|
self.max_delta_column().inner,
|
||||||
|
self.column_by_var(self.b_variable).inner
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return min(pairs, key=lambda x: x[2] / x[1])[0]
|
||||||
|
|
||||||
|
def max_delta_column(self) -> SimplexColumn:
|
||||||
|
return max(self.columns, key=lambda c: c.delta)
|
||||||
|
|
||||||
|
def min_delta_column(self) -> SimplexColumn:
|
||||||
|
return min(self.columns, key=lambda c: c.delta)
|
||||||
|
|
||||||
|
def column_by_var(self, var: Variable):
|
||||||
|
return next(filter(lambda c: c.variable == var, self.columns))
|
||||||
|
|
||||||
|
def answer(self) -> tuple[float, list[Substitution]]:
|
||||||
|
substitutions = [Substitution(var, 0) for var in self.variables]
|
||||||
|
column = self.min_delta_column()
|
||||||
|
|
||||||
|
for base, value in zip(self.base, column.inner):
|
||||||
|
next(filter(lambda s: s.var == base, substitutions)).value = value
|
||||||
|
|
||||||
|
return self.function.compute(substitutions), substitutions
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
result = ''
|
||||||
|
|
||||||
|
result += 'C\t\t' + '\t\t'.join(str(column.coefficient) for column in self.columns) + '\n'
|
||||||
|
result += 'Базис\t' + '\t\t'.join(column.variable.name for column in self.columns) + '\n'
|
||||||
|
for i, base in enumerate(self.base):
|
||||||
|
result += f'{base.name}\t\t' + '\t'.join('{0:4.1f}'.format(column.inner[i]) for column in self.columns) + '\n'
|
||||||
|
|
||||||
|
result += 'Дельта\t' + '\t'.join('{0:4.1f}'.format(column.delta) if column.delta is not None else '-' for column in self.columns) + '\n'
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
x1 = Variable('x1')
|
||||||
|
x2 = Variable('x2')
|
||||||
|
x3 = Variable('x3')
|
||||||
|
x4 = Variable('x4')
|
||||||
|
x5 = Variable('x5')
|
||||||
|
|
||||||
|
func = Function(
|
||||||
|
[Literal(x1, 0), Literal(x2, 0), Literal(x3, 0), Literal(x4, 1), Literal(x5, -2)],
|
||||||
|
-1
|
||||||
|
)
|
||||||
|
|
||||||
|
eqs = [
|
||||||
|
Equation(
|
||||||
|
[Literal(x1, 1), Literal(x2, 0), Literal(x3, 0), Literal(x4, -1), Literal(x5, 1)],
|
||||||
|
2
|
||||||
|
),
|
||||||
|
Equation(
|
||||||
|
[Literal(x1, 0), Literal(x2, 1), Literal(x3, 0), Literal(x4, 2), Literal(x5, 3)],
|
||||||
|
7
|
||||||
|
),
|
||||||
|
Equation(
|
||||||
|
[Literal(x1, 0), Literal(x2, 0), Literal(x3, 1), Literal(x4, 1), Literal(x5, -2)],
|
||||||
|
1
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
simplex = Simplex(eqs, func)
|
||||||
|
simplex.compute_deltas()
|
||||||
|
print(simplex)
|
||||||
|
|
||||||
|
iteration = 1
|
||||||
|
while simplex.iteration():
|
||||||
|
print(f'\n\t============ Итерация {iteration} ============\t\n' + str(simplex))
|
||||||
|
iteration += 1
|
||||||
|
|
||||||
|
func_value, substitutions = simplex.answer()
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(f'f = {func_value}')
|
||||||
|
print()
|
||||||
|
|
||||||
|
for substitution in sorted(substitutions):
|
||||||
|
print(f'{substitution.var.name} = {"{0:2.2f}".format(substitution.value)}')
|
41
src/utils.py
Normal file
41
src/utils.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True, frozen=True, order=True)
|
||||||
|
class Variable:
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True, order=True)
|
||||||
|
class Literal:
|
||||||
|
var: Variable
|
||||||
|
a: float
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True, frozen=True)
|
||||||
|
class Equation:
|
||||||
|
literals: list[Literal]
|
||||||
|
b: float
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True, order=True)
|
||||||
|
class Substitution:
|
||||||
|
var: Variable
|
||||||
|
value: float
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(unsafe_hash=True)
|
||||||
|
class Function:
|
||||||
|
literals: list[Literal]
|
||||||
|
tends: int
|
||||||
|
|
||||||
|
def compute(self, substitutions: list[Substitution]) -> float:
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for literal, substitution in zip(sorted(self.literals), sorted(substitutions)):
|
||||||
|
result += literal.a * substitution.value
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def compute_with_tends(self, substitutions: list[Substitution]) -> float:
|
||||||
|
return -self.compute(substitutions) if self.tends == 1 else self.compute(substitutions)
|
Loading…
Reference in New Issue
Block a user