Пример #1
0
    def __init__(self, type=OptimizationType.maximization, **kwargs):
        self.variable_names = []  # 所有变量,包括松弛变量
        self.original_variables = []  # 优化目标中包含的变量
        self.left_side = []  # 存储扩展后方程组左侧的系数
        self.right_side = []  # 存储扩展后方程组右侧的常数
        self.ratio = []  # 存储各方程组的离速
        self.basic_variables = []  # 基变量列表
        self.slack_variables = []  # 松弛变量列表
        self.artificial_variables = []  # 人工变量列表
        self.surplus_variables = []  # 剩余变量

        if type == OptimizationType.maximization:
            eq0 = [FractionWithM(1)]
            for v in kwargs:
                self.variable_names.append(v)
                self.original_variables.append(len(self.variable_names) - 1)
                eq0.append(FractionWithM(-kwargs[v]))
        else:
            eq0 = [FractionWithM(-1)]
            for v in kwargs:
                self.variable_names.append(v)
                self.original_variables.append(len(self.variable_names) - 1)
                eq0.append(FractionWithM(kwargs[v]))

        self.left_side.append(eq0)
        self.right_side.append(FractionWithM(0))
        self.ratio.append('')
        self.basic_variables.append(None)
Пример #2
0
 def add_greater_constraint(self, constraint, **kwargs):
     eq0 = self.left_side[0]
     eq0.append(FractionWithM(0))
     eq0.append(FractionWithM(M=1, value=0))
     for i in range(1, len(self.left_side)):
         eq = self.left_side[i]
         eq.append(FractionWithM(0))
         eq.append(FractionWithM(0))
     eq = [FractionWithM(0)]
     for var in self.variable_names:
         if var in kwargs:
             eq.append(FractionWithM(kwargs[var]))
         else:
             eq.append(FractionWithM(0))
     eq.append(FractionWithM(-1))
     eq.append(FractionWithM(1))
     self.left_side.append(eq)
     self.right_side.append(FractionWithM(constraint))
     self.ratio.append('')
     self.variable_names.append('_ss' +
                                str(len(self.surplus_variables) + 1))
     self.surplus_variables.append(len(self.variable_names) - 1)
     self.variable_names.append('_a' +
                                str(len(self.artificial_variables) + 1))
     self.artificial_variables.append(len(self.variable_names) - 1)
     self.basic_variables.append(len(self.variable_names) - 1)
Пример #3
0
    def __init__(self, **kwargs):
        """
        创建优化模型,并建立(最大化)优化目标函数

        :param kwargs: 目标函数中各变量的系数
        """
        self.variable_names = []  # 所有变量的变量名,包括松弛变量
        self.original_variables = []  # 优化目标中包含的变量
        self.left_side = []  # 存储扩展后方程组左侧的系数矩阵(用二维列表表示)
        self.right_side = []  # 存储扩展后方程组右侧的常数
        self.ratio = []  # 存储各方程组的离速
        self.basic_variables = []  # 基变量列表
        self.slack_variables = []  #松弛变量列表
        self.artificial_variables = []  #人工变量列表

        eq0 = [FractionWithM(1)]
        for v in kwargs:
            self.variable_names.append(v)
            self.original_variables.append(len(self.variable_names) - 1)
            eq0.append(FractionWithM(-kwargs[v]))

        self.left_side.append(eq0)
        self.right_side.append(FractionWithM(0))
        self.ratio.append('')
        self.basic_variables.append(None)
Пример #4
0
    def add_equal_constraint(self, constraint, **kwargs):
        """
        添加约束(等于)

        :param constaint: 右侧的约束值,必须大于0
        :param kwargs: 左侧各变量的系数
        :return: 无
        """
        eq0 = self.left_side[0]
        eq0.append(FractionWithM(M=1, value=0))
        for i in range(1, len(self.left_side)):
            eq = self.left_side[i]
            eq.append(FractionWithM(0))
        eq = [FractionWithM(0)]
        for var in self.variable_names:
            if var in kwargs:
                eq.append(FractionWithM(kwargs[var]))
            else:
                eq.append(FractionWithM(0))
        eq.append(FractionWithM(1))
        self.left_side.append(eq)
        self.right_side.append(FractionWithM(constraint))
        self.ratio.append('')
        self.variable_names.append('_a' + str(len(self.left_side) - 1))
        self.artificial_variables.append(len(self.variable_names) - 1)
        self.basic_variables.append(len(self.variable_names) - 1)
Пример #5
0
 def add_less_constraint(self, constraint, **kwargs):
     for eq in self.left_side:
         eq.append(FractionWithM(0))
     eq = [FractionWithM(0)]
     for var in self.variable_names:
         if var in kwargs:
             eq.append(FractionWithM(kwargs[var]))
         else:
             eq.append(FractionWithM(0))
     eq.append(FractionWithM(1))
     self.left_side.append(eq)
     self.right_side.append(FractionWithM(constraint))
     self.ratio.append('')
     self.variable_names.append('_s' + str(len(self.slack_variables) + 1))
     self.slack_variables.append(len(self.variable_names) - 1)
     self.basic_variables.append(len(self.variable_names) - 1)
Пример #6
0
    def add_less_constraint(self, constraint, **kwargs):
        """
        添加约束(小于等于)

        :param constaint: 右侧的约束值,必须大于0
        :param kwargs: 左侧各变量的系数
        :return: 无
        """
        for eq in self.left_side:
            eq.append(FractionWithM(0))
        eq = [FractionWithM(0)]
        for var in self.variable_names:
            if var in kwargs:
                eq.append(FractionWithM(kwargs[var]))
            else:
                eq.append(FractionWithM(0))
        eq.append(FractionWithM(1))
        self.left_side.append(eq)
        self.right_side.append(FractionWithM(constraint))
        self.ratio.append('')
        self.variable_names.append('_s' + str(len(self.left_side) - 1))
        self.slack_variables.append(len(self.variable_names) - 1)
        self.basic_variables.append(len(self.variable_names) - 1)
Пример #7
0
    def solve(self):
        print("Intial form:")
        print('---------------------------------')
        self._display(highlight=False)
        print()
        print("Converting Equaiton(0) to proper form:")
        print('---------------------------------')
        self._eliminate_artificials()
        self._display(highlight=False)
        iteration = 0
        while True:
            iteration += 1
            print(f'iteration {iteration}:')
            print('---------------------------------')
            # Optimality Test
            # find the variable with the minimum negative coeffecient
            eq0 = self.left_side[0]
            min_v = FractionWithM(0)
            min_i = -1
            for i in range(1, len(eq0)):
                if eq0[i] < min_v:
                    min_v = eq0[i]
                    min_i = i
            if min_v == 0:
                print("The solution is optimal")
                break
            enter_basic = min_i

            # Minumum Ratio Test
            min_ratio = None
            min_i = -1
            for i in range(1, len(self.left_side)):
                eq = self.left_side[i]
                if eq[enter_basic] == 0:
                    self.ratio[i] = ''
                else:
                    denominator = eq[enter_basic]
                    if denominator <= 0:
                        self.ratio[i] == ''
                    else:
                        self.ratio[i] = self.right_side[i] / denominator
                        if min_ratio is None or self.ratio[i] < min_ratio:
                            min_ratio = self.ratio[i]
                            min_i = i
            if min_i == -1:
                print("can't find the minimum ratio!")
                return
            leaving_basic_eq_index = min_i
            leaving_basic = self.basic_variables[min_i]

            self._display(enter_basic - 1, leaving_basic_eq_index)
            print("Entering basic :", self.variable_names[enter_basic - 1])
            print("leaving basic:", self.variable_names[leaving_basic])

            # Gaussian Elimination
            leaving_basic_eq = self.left_side[min_i]
            denominator = leaving_basic_eq[enter_basic]
            for i in range(len(leaving_basic_eq)):
                leaving_basic_eq[i] /= denominator
            self.right_side[min_i] /= denominator
            self.basic_variables[min_i] = enter_basic - 1
            for i in range(len(self.left_side)):
                if i == min_i:
                    continue
                eq = self.left_side[i]
                multiple = eq[enter_basic]
                for j in range(len(eq)):
                    eq[j] -= multiple * leaving_basic_eq[j]
                self.right_side[i] -= multiple * self.right_side[min_i]

        self._display(highlight=False)
        self._display_solution()