[SciPy-User] simple optimization but very complex constraints

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[SciPy-User] simple optimization but very complex constraints

Ben Orr
I am trying to find the optimal student loan payoff schedule. I believe the scipy.optimize.minimize function will do what I need but I'm not sure if it's the best solution.

I represent the loan payment schedule as a 2D array; each column is a loan, each row is a month. I start off by determining the initial guess (x0). There are 'number-of-loans' columns. The number of rows is the max of the number of months to pay off each loan if making the minimum payments. I then fill in each column with the minimum payment for each loan until it is payed off, followed by zeros.

I would like to pay "y" amount each month (must be greater than the sum of the minimum payments). Therefore, I would like to adjust the amount payed each month (aka the sum of each row) to be equal to or less than my target monthly payment such that the total payoff amount (sum of the array) is minimized.

Thus, my function to minimize is simply "sum(x)".

The trick is all the constraints. Each cell must be greater-than-or-equal-to the minimum payment, unless the remaining balance is less than the minimum payment, in which case the minimum of that cell is the remaining balance (0 if paid off). The maximum for any given cell is the target monthly payment "y". The maximum of the sum of each row is also the target monthly payment "y". Each column must pay-off the loan that column represents.

Note that the sum(column)!=initialBalance. "Balance" is only the principal. The following formula calculates the remaining balance after a monthly  payment: 
i = interest rate (ex: 6.7%, i=6.7 not 0.067)
b = balance (after a payment)
bp = balance previous (before a payment)
p = payment
b = bp*(1+(i/1200))-((p/(i/1200))*((1+(i/1200))-1))

I hoped to simplify the problem by having an array the same shape as "x" but with the remaining balance (formula above) after each month's payment. This array would be used in for both constraints pertaining to remaining balance (remaining balance < min payment and each column must pay off each loan). See attached spreadsheet for calculating both x0 and the remaining balance.

Given all that (sorry for the long description), any help choosing and implementing the appropriate optimization method is greatly appreciated. Thank you.

Ben  

_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user

Loan Calculator.xlsx (169K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: simple optimization but very complex constraints

josef.pktd
On Sun, Apr 6, 2014 at 5:54 PM, Ben Orr <[hidden email]> wrote:

> I am trying to find the optimal student loan payoff schedule. I believe the
> scipy.optimize.minimize function will do what I need but I'm not sure if
> it's the best solution.
>
> I represent the loan payment schedule as a 2D array; each column is a loan,
> each row is a month. I start off by determining the initial guess (x0).
> There are 'number-of-loans' columns. The number of rows is the max of the
> number of months to pay off each loan if making the minimum payments. I then
> fill in each column with the minimum payment for each loan until it is payed
> off, followed by zeros.
>
> I would like to pay "y" amount each month (must be greater than the sum of
> the minimum payments). Therefore, I would like to adjust the amount payed
> each month (aka the sum of each row) to be equal to or less than my target
> monthly payment such that the total payoff amount (sum of the array) is
> minimized.
>
> Thus, my function to minimize is simply "sum(x)".
>
> The trick is all the constraints. Each cell must be greater-than-or-equal-to
> the minimum payment, unless the remaining balance is less than the minimum
> payment, in which case the minimum of that cell is the remaining balance (0
> if paid off). The maximum for any given cell is the target monthly payment
> "y". The maximum of the sum of each row is also the target monthly payment
> "y". Each column must pay-off the loan that column represents.
>
> Note that the sum(column)!=initialBalance. "Balance" is only the principal.
> The following formula calculates the remaining balance after a monthly
> payment:
> i = interest rate (ex: 6.7%, i=6.7 not 0.067)
> b = balance (after a payment)
> bp = balance previous (before a payment)
> p = payment
> b = bp*(1+(i/1200))-((p/(i/1200))*((1+(i/1200))-1))
>
> I hoped to simplify the problem by having an array the same shape as "x" but
> with the remaining balance (formula above) after each month's payment. This
> array would be used in for both constraints pertaining to remaining balance
> (remaining balance < min payment and each column must pay off each loan).
> See attached spreadsheet for calculating both x0 and the remaining balance.
>
> Given all that (sorry for the long description), any help choosing and
> implementing the appropriate optimization method is greatly appreciated.
> Thank you.

You don't have any curvature that I can see. This looks more like a
linear programming problem.

AFAICS: The solution will be to pay off as fast as possible, if you
don't discount in the objective, max(x), but pay interest on loans. If
all loans have the same interest rate, then it doesn't matter which
ones you pay off faster or slower. If interest rates differ, then you
pay off the highest interest rate loan as fast as possible.

With curvature it would be commonly (?) treated as a dynamic
programming/optimization problem.

Josef

>
> Ben
>
> _______________________________________________
> SciPy-User mailing list
> [hidden email]
> http://mail.scipy.org/mailman/listinfo/scipy-user
>
_______________________________________________
SciPy-User mailing list
[hidden email]
http://mail.scipy.org/mailman/listinfo/scipy-user