Exemplo n.º 1
0
    def analyse_interval(self, left_point, right_point, parent, plan):
        current_solution = Solution(left_point, right_point, [], [], None,
                                    None, parent)
        s = 0
        first_pass = True
        while not plan.is_optimal() and (not plan.is_only_l() or first_pass):
            s += 1
            first_pass = False
            if s > 100:
                current_solution.insolvable_reason = "Возможно зацикливание!"
                print current_solution.insolvable_reason
                return current_solution

            print "План не оптимален"

            if not plan.is_solvable():
                current_solution.insolvable_reason = "Задача не разрешима из-за неогрниченности целевой функции в области допустимых решений"
                print current_solution.insolvable_reason
                return current_solution

            # задача разрешима, переходим к новому плану

            plan = self.transition(plan)
            plan.calc_alpha_assessment()
            plan.calc_z()
            solve_col = self.get_solve_col(plan.alpha)
            plan.calc_sigma(solve_col)

            print "Текущий план: "
            plan.print_plan()

        current_solution.X_opt = []
        for i in range(0, self.task.n):
            if i in plan.B:
                current_solution.X_opt.append(plan.ai0[plan.B.index(i)])
            else:
                current_solution.X_opt.append(0)

        current_solution.Z_max = plan.z

        print "Разбиваем интервал ({0}, {1})".format(left_point, right_point)

        solve_col = self.get_solve_col_lambda(plan.alpha)

        while solve_col is not None:
            split_point = -plan.alpha[solve_col].real / plan.alpha[
                solve_col].imag

            # проверяем вхождение точки в заданный интервал
            if not (split_point > left_point and split_point < right_point):
                # есть ли ещё решение с параметром, попробуем разбить и этот интервал
                solve_col = self.get_solve_col_lambda(plan.alpha,
                                                      solve_col + 1)
                continue
            print "Точка разделения: {0:^8.2f}".format(split_point)
            # если слева или с права от текущей токи занчение отрицательно, то, соотвественно запускаем процесс расчёта
            # для подинтервала

            current_solution.left_child = copy.deepcopy(current_solution)
            current_solution.right_child = copy.deepcopy(current_solution)
            current_solution.left_child.right_point = split_point
            current_solution.right_child.left_point = split_point

            # левая точка
            lp = split_point - 0.000001
            if plan.alpha[solve_col].real + plan.alpha[solve_col].imag * lp < 0:
                current_solution.left_child = self.analyse_interval(
                    left_point, split_point, current_solution, plan)

            # правая точка
            rp = split_point + 0.000001
            if plan.alpha[solve_col].real + plan.alpha[solve_col].imag * rp < 0:
                current_solution.right_child = self.analyse_interval(
                    split_point, right_point, current_solution, plan)
            else:
                current_solution.right_child = None
            break

        current_solution.insolvable = False

        return current_solution