예제 #1
0
파일: simplex.py 프로젝트: zuevval/mo2020
def add_to_Nk(Nk0: np.array,  binom_table: np.ndarray, binom_index: int)->np.array:
    """
    Дополняет индексы положительных базисных векторов так, чтобы составленная из них матрица была квадратной
    :param Nk0: массив индексов положительных переменных
    :param binom_table: биномиальная таблица, созданная функцией `utils.binomial_grid`
    :param binom_index: номер итерации смены базиса от 0 до C[|Nk_plus|,m-|Nk0|]
    :return: индексы из `Nk0`, которые надо добавить к `Nk_plus`, чтобы получить квадратную матрицу
    """
    return subset_by_index(Nk0, binom_table, binom_index)
예제 #2
0
def add_to_Nk(Nk0: np.array, binom_table: np.ndarray,
              binom_index: int) -> np.array:
    """
    Augments indices of positive basis vectors so that they form
    a square matrix when put together
    :param Nk0: an array of indices of positive vectors
    :param binom_table: binomial table created by `utils.binomial_grid` method
    :param binom_index: iteration of basis change (0 to C[|Nk_plus|,m-|Nk0|])
    :return: indices from `Nk0` that should be added to `Nk_plus` in order to
    make a square matrix from vectors with those indices
    """
    return subset_by_index(Nk0, binom_table, binom_index)
예제 #3
0
def find_all_svs(cf: NpCanonicalForm):
    binom_table = binomial_grid(cf.n, cf.m)
    N = np.array(list(range(cf.n)))
    for idx in range(binom_table[-1, -1]):
        Nk = subset_by_index(N, binom_table, idx)
        AMNk = np.array([cf.A[:, i] for i in Nk]).T
        if np.abs(np.linalg.det(AMNk)) > 1e-3:
            xNk = np.matmul(np.linalg.inv(AMNk), cf.b)
            if np.min(xNk) < 0:
                continue
            xN = np.zeros(cf.n)
            for i in range(len(Nk)):
                xN[Nk[i]] = xNk[i]
            yield xN
예제 #4
0
def starting_vector(cf: CanonicalForm) -> np.array:
    binom_table = binomial_grid(cf.n, cf.m)
    N = np.array(list(range(cf.n)))
    for idx in range(binom_table[-1, -1]):
        Nk = subset_by_index(N, binom_table, idx)
        AMNk = np.array([cf.A[:, i] for i in Nk]).T
        if np.linalg.det(AMNk) != 0:
            xNk = np.matmul(np.linalg.inv(AMNk), cf.b)
            if np.min(xNk) < 0:
                continue  # we need only vectors with all positive components
            xN = np.zeros(cf.n)
            for i in range(len(Nk)):
                xN[Nk[i]] = xNk[i]
            return xN
    logging.info("error, initial vector not found!")
    return np.zeros(cf.n)
예제 #5
0
def find_min_sv(cf: CanonicalForm,
                target_function: Callable[[np.array], float],
                abs_tolerance: float = 1e-3) -> BruteForceResult:
    binom_table = binomial_grid(cf.n, cf.m)
    N = np.array(list(range(cf.n)))
    min_sv, inv_AMNk_min, Nk_min = None, None, None
    for idx in range(binom_table[-1, -1]):
        Nk = subset_by_index(N, binom_table, idx)
        AMNk = np.array([cf.A[:, i] for i in Nk]).T
        if np.abs(np.linalg.det(AMNk)) > abs_tolerance:
            inv_AMNk = np.linalg.inv(AMNk)
            xNk = np.matmul(inv_AMNk, cf.b)
            if np.min(xNk) < 0:
                continue
            xN = np.zeros(cf.n)
            for i in range(len(Nk)):
                xN[Nk[i]] = xNk[i]
            if min_sv is None or target_function(xN) < target_function(min_sv):
                min_sv, inv_AMNk_min, Nk_min = xN, inv_AMNk, Nk
    return BruteForceResult(min_sv, inv_AMNk_min, Nk_min)