Вам необходимо сложить отдельные денежные потоки в рамках вашей функции и вернуть их. В данный момент вы возвращаете значение 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)))
Сначала необходимо найти ближайшего соседа каждого элемента в другом наборе.
Чтобы сделать это эффективно, Вам нужен ближайший соседний алгоритм. Лично я реализовал бы kd-дерево просто, потому что я сделал его в прошлом в моем классе алгоритма, и это было довольно просто. Другой жизнеспособной альтернативой является R-дерево.
Сделайте это однажды для каждого элемента в самом маленьком наборе. (Добавьте один элемент от самого маленького до большего и выполните алгоритм для нахождения его ближайшего соседа.)
От этого необходимо смочь получить список ближайших соседей к каждому элементу.
При нахождении пар ближайших соседей сохраните их в отсортированной структуре данных, которая имеет быстрый дополнительный метод и быстрый getMax метод, такой как "куча", отсортированная по Евклидову расстоянию.
Затем после того как Вы сделаны, просто просят у "кучи" максимум.
Время выполнения для этого ломается следующим образом:
N = размер меньшего набора
M = размер большего набора
Таким образом в конце целый алгоритм является O (N*log M).
Если Вы не заботитесь о порядке каждой пары, можно сохранить немного времени и пространства, только сохраняя макс. найденным до сих пор.
*Правовая оговорка: это все предполагает, что Вы не будете использовать чрезвычайно высокое количество размеров и что Ваши элементы следуют за главным образом случайным распределением.
Самый очевидный подход, кажется, мне для создания древовидной структуры на одном наборе, чтобы позволить Вам искать его относительно быстро. Kd-дерево или подобный, вероятно, подходило бы для этого.
Сделав это, Вы техническая победа все точки в другом наборе и использовании дерево для нахождения их ближайшего соседа в первом наборе, отслеживании максимума, когда Вы идете.
Это - nlog (n) для создания дерева и журнала (n) для одного поиска, таким образом, все это должно работать в nlog (n).
Для каждой точки в наборе B, найдите расстояние до его ближайшего соседа в наборе A.
Для нахождения расстояния до каждого ближайшего соседа можно использовать kd-дерево, пока количество размеров разумно, нет слишком многих точек, и Вы будете делать много запросов - иначе будет слишком дорого создать дерево для стоения.
Для создания вещей более эффективными рассмотрите использование алгоритма Ящика - группируют точки во множестве элементарных исходов (таблица цветов) их местоположением в n-пространстве. Это позволяет Вам эффективно находить ближайшего соседа, не имея необходимость выполнять итерации всех точек.
Например, если Вы работали в с 2 пространствами, делите свою плоскость на сетку 5 x 5, давая 25 квадратов, с 25 группами точек.
В 3 пространствах разделите свой куб на сетку 5 x 5 x 5, дав 125 кубов, каждого с рядом точек.
Затем к контрольной точке n, найдите квадрат/куб/группу, который содержит n и тестовое расстояние до тех точек. Вам только нужно к контрольным точкам от соседних групп, если точка n ближе к краю, чем ближайшему соседу в группе.
Править: Я имел в виду nlog (n), где n является суммой размеров обоих наборов.
В наборе 1 пространства I Вы могли сделать что-то вроде этого (псевдокод)
Используйте структуру как это
Struct Item {
int value
int setid
}
(1) Расстояние Max = 0
(2) Считайте все наборы в структуры Объекта
(3) Создайте Массив указателей на все Объекты
(4) Отсортируйте массив указателей Объектом-> поле значения структуры
(5) Обойдите массив с начала до конца, проверив, отличается ли Объект-> setid от предыдущего Объекта-> setid если (SetIDs отличаются),
проверьте, больше ли это расстояние, чем Расстояние Max раз так установило MaxDistance на это расстояние
Возвратите макс. расстояние.