Нахождение самой дальней точки в одном наборе от другого набора

Вам необходимо сложить отдельные денежные потоки в рамках вашей функции и вернуть их. В данный момент вы возвращаете значение pv первого денежного потока, поскольку у вас есть отчет о возврате в цикле for.

Кроме того, я думаю, что то, как вы проверите свой цикл while по i, будет означать, что вы пропустите последний платеж. Обычно вам не нужно создавать экземпляры встречных переменных самостоятельно (см. Мои примеры ниже):

def npv(cfList, r):
    f = 0
    i = 1

    pv = cfList[f] / ((1 + r) ** i)  # <-- this needs to be in the loop

    while i < len(cfList): # <-- i will break loop before last payment is calculated.
        f += 1
        i += 1
        return pv  # <-- this return here is the issue


print(npv(cfList, r))

NPV - это сумма PV всех будущих денежных потоков, это то, что вам нужно рассчитать. Например :

def npv(cfList, r):

    sum_pv = 0  # <-- variable used to sum result

    for i, pmt in enumerate(cfList, start=1):  # <-- use of enumerate allows you to do away with the counter variables.
        sum_pv += pmt / ((1 + r) ** i)  # <-- add pv of one of the cash flows to the sum variable

    return sum_pv  # <-- only return the sum after your loop has completed.

Всегда помните, что оператор return в цикле for выйдет из цикла при первом обнаружении return.

Альтернативной реализацией будет получение отдельных PV от генератора PV и суммирование результатов:

def pv_gen(cfList, r):

    for i, pmt in enumerate(cfList, start=1):

        yield pmt / ((1 + r) ** i)

print(sum(pv_gen(cfList, r)))
5
задан Community 23 May 2017 в 12:26
поделиться

5 ответов

Сначала необходимо найти ближайшего соседа каждого элемента в другом наборе.

Чтобы сделать это эффективно, Вам нужен ближайший соседний алгоритм. Лично я реализовал бы kd-дерево просто, потому что я сделал его в прошлом в моем классе алгоритма, и это было довольно просто. Другой жизнеспособной альтернативой является R-дерево.

Сделайте это однажды для каждого элемента в самом маленьком наборе. (Добавьте один элемент от самого маленького до большего и выполните алгоритм для нахождения его ближайшего соседа.)

От этого необходимо смочь получить список ближайших соседей к каждому элементу.

При нахождении пар ближайших соседей сохраните их в отсортированной структуре данных, которая имеет быстрый дополнительный метод и быстрый getMax метод, такой как "куча", отсортированная по Евклидову расстоянию.

Затем после того как Вы сделаны, просто просят у "кучи" максимум.

Время выполнения для этого ломается следующим образом:

N = размер меньшего набора
M = размер большего набора

  • N * O (регистрируют M + 1) для всего kd-дерева ближайшие соседние проверки.
  • N * O (1) для вычисления Евклидова расстояния прежде, чем добавить его к "куче".
  • N * O (регистрируют N) для добавления пар в "кучу".
  • O (1) для получения окончательного ответа :D

Таким образом в конце целый алгоритм является O (N*log M).

Если Вы не заботитесь о порядке каждой пары, можно сохранить немного времени и пространства, только сохраняя макс. найденным до сих пор.

*Правовая оговорка: это все предполагает, что Вы не будете использовать чрезвычайно высокое количество размеров и что Ваши элементы следуют за главным образом случайным распределением.

10
ответ дан 14 December 2019 в 01:18
поделиться

Самый очевидный подход, кажется, мне для создания древовидной структуры на одном наборе, чтобы позволить Вам искать его относительно быстро. Kd-дерево или подобный, вероятно, подходило бы для этого.

Сделав это, Вы техническая победа все точки в другом наборе и использовании дерево для нахождения их ближайшего соседа в первом наборе, отслеживании максимума, когда Вы идете.

Это - nlog (n) для создания дерева и журнала (n) для одного поиска, таким образом, все это должно работать в nlog (n).

0
ответ дан 14 December 2019 в 01:18
поделиться

Для каждой точки в наборе B, найдите расстояние до его ближайшего соседа в наборе A.

Для нахождения расстояния до каждого ближайшего соседа можно использовать kd-дерево, пока количество размеров разумно, нет слишком многих точек, и Вы будете делать много запросов - иначе будет слишком дорого создать дерево для стоения.

0
ответ дан 14 December 2019 в 01:18
поделиться

Для создания вещей более эффективными рассмотрите использование алгоритма Ящика - группируют точки во множестве элементарных исходов (таблица цветов) их местоположением в n-пространстве. Это позволяет Вам эффективно находить ближайшего соседа, не имея необходимость выполнять итерации всех точек.

Например, если Вы работали в с 2 пространствами, делите свою плоскость на сетку 5 x 5, давая 25 квадратов, с 25 группами точек.

В 3 пространствах разделите свой куб на сетку 5 x 5 x 5, дав 125 кубов, каждого с рядом точек.

Затем к контрольной точке n, найдите квадрат/куб/группу, который содержит n и тестовое расстояние до тех точек. Вам только нужно к контрольным точкам от соседних групп, если точка n ближе к краю, чем ближайшему соседу в группе.

0
ответ дан 14 December 2019 в 01:18
поделиться

Править: Я имел в виду nlog (n), где n является суммой размеров обоих наборов.

В наборе 1 пространства I Вы могли сделать что-то вроде этого (псевдокод)

Используйте структуру как это

Struct Item {
    int value
    int setid
}

(1) Расстояние Max = 0
(2) Считайте все наборы в структуры Объекта
(3) Создайте Массив указателей на все Объекты
(4) Отсортируйте массив указателей Объектом-> поле значения структуры
(5) Обойдите массив с начала до конца, проверив, отличается ли Объект-> setid от предыдущего Объекта-> setid если (SetIDs отличаются),
проверьте, больше ли это расстояние, чем Расстояние Max раз так установило MaxDistance на это расстояние

Возвратите макс. расстояние.

-1
ответ дан 14 December 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: