Работа готова
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