How to set an objective to minimize the variance in ratio of allocation

I am trying to write a model where I have to distribute fractions of rent from properties to loans. The objective is to distribute the rents as equally as possible given the loan balance.

Say there are 5 properties and 8 loans, I have 40 variables X11, X12, X13…X18; X21, X22, X23…X28;…; X51, X52,…X58

Loan Balances are L1, L2, L3, L4 …L8 Rents from properties are R1,R2, R3, R4 and R5

So Minimize ( Absolute Value (R1 X11/L1 + R2X21/L1 + R3X31/L1 +R4X41/L1 +R5X51/L1 - AverageRentLoanRatio) + Abolute Value (R1 X12/L2 + R2X22/L2 + R3X32/L2 +R4X42/L2 +R5X52/L2 - AverageRentLoanRatio)+ Abolute Value (R1 X13/L3 + R2X23/L3 + R3X33/L3 +R4X43/L3 +R5X53/L3 - AverageRentLoanRatio)+ Abolute Value (R1 X14/L4 + R2X24/L4 + R3X34/L4 +R4X44/L4 +R5X54/L4 - AverageRentLoanRatio) + Abolute Value (R1 X15/L5 + R2X25/L5 + R3X35/L5 +R4X45/L5 +R5*X55/L5 - AverageRentLoanRatio))

With Constraints such as a property cannot be allocated to a specific property and total rent is 100%

I am able to define the constraints but struggling how to write the objective.

Here is the model I have written so far

using CSV
using DataFrames
C= CSV.read("Property.csv", DataFrame)
L = CSV.read("LoanFile.csv", DataFrame)



using JuMP, GLPK

# Preparing an optimization model
m = Model(GLPK.Optimizer)


#getting the number of properties and loans
index_i = 1:nrow(C)
index_j = 1:ncol(C)-2

#setting the number of constraints
#index_constraints = 1:nrow(C)* (ncol(C)-2)

# Declaring variables
@variable(m, x[index_i, index_j] >= 0)

# Declaring bound Constraints
@constraint(m, conb[i=index_i, j=index_j],x[i, j] <= C[i,j+2])

#Declaring total 100 % constraints
@constraint(m,cont[i=index_i],sum(x[i, j] * C[i,2] for j in index_j) <= C[i,2])

# Setting the objective
Average_KDF  = sum(C[i,2] for i in 1:nrow(C))/sum(L[i,2] for i in 1:nrow(L))

KDFratio = Array{Float64}(undef,nrow(C),ncol(C)-2)
KDFsumRatio = Array{Float64}(undef,nrow(L))


#@objective(m, Min,sum(abs((x[i, j] * C[i,2]/L[j,2]- Average_KDF) for j in index_j) for i in index_i)
# the above setting of objective is not working and I am struggling to formulate this.
  


# Printing the prepared optimization model

print(m)

Here are the files I am using for loans and properties

|LoanID  | Balance |
|L 1     |  100.00  |
|L 2     |  100.00  |
|L 3     |  300.00  |
|L 4     |  100.00  |
|L 5     |  50.00   |
|L 6     |  50.00   |
|L 7     |  50.00   |
|L 8     |  50.00   |


|PropertyID  | Rent(R)  |L1|L2|L3|L4|L5|L6|L7|L8|
|P 1         |  5.00    | 1| 0| 0| 0| 0| 0| 0| 0|
|P 2         |  10.00   | 0| 1| 1| 0| 0| 0| 0| 0|
|P 3         |  1.5     | 1| 1| 0| 0| 0| 0| 0| 0|
|P 4         |  10.50   | 1| 1| 1| 1| 0| 0| 0| 0|
|P 5         |  20.00   | 0| 1| 0| 1| 0| 1| 0| 1|

Hi @Ashok_Khatri, welcome aboard!

I think that is because your objective is nonlinear. Check out the associated docs to see how that is handled. JuMP has a particular syntax, which does not allow you to specify just any function as a constraint or objective.

As a side note, you will also need to change solver, because GLPK is made for linear programs :slight_smile:

Hi @ashok_Khatri, welcome to the forum.

I haven’t tested this locally so there might be typos, but this should point you in the right direction:

using JuMP
import CSV, DataFrames, HiGHS
C = CSV.read("Property.csv", DataFrames.DataFrame)
L = CSV.read("LoanFile.csv", DataFrames.DataFrame)
N = size(C, 1)
model = Model(HiGHS.Optimizer)
@variable(model, 0 <= x[i=1:N, j=1:N-2] <= C[i, j+2])
@constraint(model, [i=1:N], sum(C[i, 2] * x[i, j] for j in 1:N-2) <= C[i, 2])
Average_KDF = sum(C[:, 2]) / sum(L[:, 2])
@expression(
    model, 
    y[i=1:N], 
    sum(x[i, j] * C[i, 2] / L[j, 2] - Average_KDF for j in 1:(N-2)),
)
# To compute t >= sum | y_i |, use NormOneCone, see:
# https://jump.dev/JuMP.jl/stable/tutorials/linear/tips_and_tricks/#L1-norm
@variable(model, t >= 0)
@constraint(model, [t; y] in MOI.NormOneCone(1 + length(y)))
@objective(model, Min, t)

I think that is because your objective is nonlinear

The objective is linear, albeit with a minimize abs(x) formulation :smile:

Oh right of course, I read the post too fast and thought the Li were variables too, based on the title which mentioned ratios.

Thanks a lot, @odow, that was very helpful. Appreciate your quick response.
I was able to take the code you posted make some edits and run it and it gave me the results I was expecting.

Thanks @gdalle for the references to non-linear objectives. These will help with other problems.

2 Likes