'Function constrained optimization in r-Inventory management

I am trying to optimize a function with two constraints (which are also defined as functions) but I keep receiving errors. The main issue is that constraints are long and if I nest them in the objective function, it won't work. Any idea on how to fix it would be appreciated. The current issue is the optim function does not recognize I11 in my constraint1 function

ObjectiveFunction <- function(I){
  
  I11 = I[11]
  I12 = I[12]
  I13 = I[13]
  I14 = I[14]
  I15 = I[15]
  I21 = I[21]
  I22 = I[22]
  I23 = I[23]
  I24 = I[24]
  I25 = I[25]
  I31 = I[31]
  I32 = I[32]
  I33 = I[33]
  I34 = I[34]
  I35 = I[35]
  I41 = I[41]
  I42 = I[42]
  I43 = I[43]
  I44 = I[44]
  I45 = I[45]
  I51 = I[51]
  I52 = I[52]
  I53 = I[53]
  I54 = I[54]
  I55 = I[55]
 
  I61 = I[61]
  I62 = I[62]
  I63 = I[63]
  I64 = I[64]
  I65 = I[65]
  I71 = I[71]
  I72 = I[72]
  I73 = I[73]
  I74 = I[74]
  I75 = I[75]
  I81 = I[81]
  I82 = I[82]
  I83 = I[83]
  I84 = I[84]
  I85 = I[85]
  I91 = I[91]
  I92 = I[92]
  I93 = I[93]
  I94 = I[94]
  I95 = I[95]
  I101 = I[101]
  I102 = I[102]
  I103 = I[103]
  I104 = I[104]
  I105 = I[105] 

  #Objective Function
  Y =
    HoldingCost[1] * (I11 + I12 + I13 + I14 + I15) +
    HoldingCost[2] * (I21 + I22 + I23 + I24 + I25) +
    HoldingCost[3] * (I31 + I32 + I33 + I34 + I35) +
    HoldingCost[4] * (I41 + I42 + I43 + I44 + I45) +
    HoldingCost[5] * (I51 + I52 + I53 + I54 + I55) +
    BacklogCost[1] * (I61 + I62 + I63 + I64 + I65) +
    BacklogCost[2] * (I71 + I72 + I73 + I74 + I75) +
    BacklogCost[3] * (I81 + I82 + I83 + I84 + I85) +
    BacklogCost[4] * (I91 + I92 + I93 + I94 + I95) +
    BacklogCost[5] * (I101 +I102 + I103 + I104 + I105)
  
  if (Constraint1() & Constraint2()) {
    return(Y)
    return(NA)
    
  }
}


Constraint1 <- function(){
  
  I11 - I61 = I10 - B10 - D10 + r1_1  
  I21 - I71 = I20 - B20 - D20 + r2_1 
  I12 - I62 = I11 - I61 - D11 + r1_0 
  I22 - I72 = I21 - I71 - D21 + r2_0 
  
  I13 - I63 = I12 - I62 - D12 + r11 
  I23 - I73 = I22 - I72 - D22 + r21 
      
  I14 - I64 = I13 - I63 - D13 + r12 
  I24 - I74 = I23 - I73 - D23 + r22 
  
  I15 - I65 = I14 - I64 - D14 + r13 
  I25 - I75 = I24 - I74 - D24 + r23 
    
  I31 - I81 = I30 - B30 - D30 + r3_3 
  I41 - I91 = I40 - B40 - D40 + r4_5 
  I51 - I101 = I50 - B50 - D50 + r5_1 
  
  I32 - I82 = I31 - I81 - D31 + r3_2  
  I42 - I92 = I41 - I91 - D41 + r4_4    
  I52 - I102 = I51 - I101 - D51 + r5_0 
        
  I33 - I83 = I32 - I82 - D32 + r3_1 
  I43 - I93 = I42 - I92 - D42 + r4_3 
  I53 - I103 = I52 - I102 - D52 + r51 
    
  I34 - I84 = I33 - I83 - D33 + r3_0 
  I44 - I94 = I43 - I93 - D43 + r4_2 
  I54 - I104 = I53 - I103 - D53 + r52 
      
  I35 - I85 = I34 - I84 - D34 + r31 
  I45 - I95 = I44 - I94 - D44 + r4_1
  I55 - I105 = I54 - I104 - D54 + r53;
}

Constraint2 <- function(){
  
  #Constraint 2
  I61 - B10 <= D10
  I71 - B20 <= D20
  I81 - B30 <= 0
  I91 - B40 <= 0
  I101 - B50 <= 0
  
  I62 - I61 <= D11
  I72 - I71 <= D21
  I82 - I81 <= 0
  I92 - I91 <= 0
  I102 - I101 <= 0
  
  I63 - I62 <= D12
  I73 - I72 <= D22
  I83 - I82 <= 0
  I93 - I92 <= 0
  I103 - I102 <= 0
  
  I64 - I63 <= D13
  I74 - I73 <= D23
  I84 - I83 <= 0
  I94 - I93 <= 0
  I104 - I103 <= 0
  
  I65 - I64 <= D14
  I75 - I74 <= D24
  I85 - I84 <= 0
  I95 - I94 <= 0
  I105 - I104 <= 0
  
}

ParBase <- rep(0,50); ParBase

optim(par = ParBase, ObjectiveFunction)

Edit

I am trying to optimize a multi-period inventory control model using a dynamic programming approach and lpSolve. I have split the model into 5 periods. For the first 2 periods, everything works perfectly fine because "r" values are known. However, for period 3 onward, the code cannot work because "I", "B", and "r" are unknown.

I do not know how to solve this issue. I was thinking about the following since there is a relation among "I", "B", and "r" values. If the value of "r" in each period is positive, it equals "I" in that period. else, it is equalized to "B". I was thinking about a loop function but I do not know how to embed such information into the code and if it helps.

This is the code:

    #Basic Information (at time 0)
Item <- c(1,2,3,4,5)
Definition <- c("End-item","End-item", "Component","Component","Component")
LeadTime <- c(1,1,3,5,1)
LotSize <- c(replicate(5,"LFL"))
SafetyStock <- c(0,0,0,0,0)
CoefUse_EI1 <- c(0,0,1,1,0)
CoefUse_EI2 <- c(0,0,0,1,1)
BegInventory <- c(0,0,0,0,0)
BegBacklog <- c(0,0,0,0,0)
ScheduledReceipt <- c(0,0,0,0,0)
ScheduledReceiptT_1 <- c(0,0,0,0,0)
ScheduledReceiptT_2 <- c(0,0,0,0,0)
ScheduledReceiptT_3 <- c(0,0,0,0,0)
ScheduledReceiptT_4 <- c(0,0,0,0,0)
ScheduledReceiptT_5 <- c(0,0,0,0,0)

BasicInfor <- data.frame(Item,Definition,LeadTime,LotSize,SafetyStock,
                         CoefUse_EI1,CoefUse_EI2,BegInventory, 
                         BegBacklog, ScheduledReceiptT_5,
                         ScheduledReceiptT_4,ScheduledReceiptT_3,
                         ScheduledReceiptT_2, ScheduledReceiptT_1,
                         ScheduledReceipt
                         )
BasicInfor

# Predetermined Information
#PARAMETERS : DEMNAD
D10 <- as.numeric(0)
D11 <- as.numeric(20)
D12 <- as.numeric(0)
D13 <- as.numeric(390)
D14 <- as.numeric(0)
D15 <- as.numeric(120)

D20 <- as.numeric(0)
D21 <- as.numeric(20)
D22 <- as.numeric(0)
D23 <- as.numeric(390)
D24 <- as.numeric(0)
D25 <- as.numeric(120)

D30 <- CoefUse_EI1[3]* D10 + CoefUse_EI2[3]*D20 ; D30
D31 <- CoefUse_EI1[3]* D11 + CoefUse_EI2[3]*D21 ; D31
D32 <- CoefUse_EI1[3]* D12 + CoefUse_EI2[3]*D22 ; D32
D33 <- CoefUse_EI1[3]* D13 + CoefUse_EI2[3]*D23 ; D33
D34 <- CoefUse_EI1[3]* D14 + CoefUse_EI2[3]*D24 ; D34
D35 <- CoefUse_EI1[3]* D15 + CoefUse_EI2[3]*D25 ; D35

D40 <- CoefUse_EI1[4]* D10 + CoefUse_EI2[4]*D20 ; D40
D41 <- CoefUse_EI1[4]* D11 + CoefUse_EI2[4]*D21 ; D41
D42 <- CoefUse_EI1[4]* D12 + CoefUse_EI2[4]*D22 ; D42
D43 <- CoefUse_EI1[4]* D13 + CoefUse_EI2[4]*D23 ; D43
D44 <- CoefUse_EI1[4]* D14 + CoefUse_EI2[4]*D24 ; D44
D45 <- CoefUse_EI1[4]* D15 + CoefUse_EI2[4]*D25 ; D45

D50 <- CoefUse_EI1[5]* D10 + CoefUse_EI2[5]*D20 ; D50
D51 <- CoefUse_EI1[5]* D11 + CoefUse_EI2[5]*D21 ; D51
D52 <- CoefUse_EI1[5]* D12 + CoefUse_EI2[5]*D22 ; D52
D53 <- CoefUse_EI1[5]* D13 + CoefUse_EI2[5]*D23 ; D53
D54 <- CoefUse_EI1[5]* D14 + CoefUse_EI2[5]*D24 ; D54
D55 <- CoefUse_EI1[5]* D15 + CoefUse_EI2[5]*D25 ; D55

#SCHEDULED RECEIPT

r1_5 <- ScheduledReceiptT_5[1]
r1_4 <- ScheduledReceiptT_4[1]
r1_3 <- ScheduledReceiptT_3[1]
r1_2 <- ScheduledReceiptT_2[1]
r1_1 <- ScheduledReceiptT_1[1]
r1_0 <- ScheduledReceipt[1]

r2_5 <- ScheduledReceiptT_5[2]
r2_4 <- ScheduledReceiptT_4[2]
r2_3 <- ScheduledReceiptT_3[2]
r2_2 <- ScheduledReceiptT_2[2]
r2_1 <- ScheduledReceiptT_1[2]
r2_0 <- ScheduledReceipt[2]

r3_5 <- ScheduledReceiptT_5[3]
r3_4 <- ScheduledReceiptT_4[3]
r3_3 <- ScheduledReceiptT_3[3]
r3_2 <- ScheduledReceiptT_2[3]
r3_1 <- ScheduledReceiptT_1[3]
r3_0 <- ScheduledReceipt[3]

r4_5 <- ScheduledReceiptT_5[4]
r4_4 <- ScheduledReceiptT_4[4]
r4_3 <- ScheduledReceiptT_3[4]
r4_2 <- ScheduledReceiptT_2[4]
r4_1 <- ScheduledReceiptT_1[4]
r4_0 <- ScheduledReceipt[4]

r5_5 <- ScheduledReceiptT_5[5]
r5_4 <- ScheduledReceiptT_4[5]
r5_3 <- ScheduledReceiptT_3[5]
r5_2 <- ScheduledReceiptT_2[5]
r5_1 <- ScheduledReceiptT_1[5]
r5_0 <- ScheduledReceipt[5]

r11 <- as.numeric()
r12 <- as.numeric()
r13 <- as.numeric()
r14 <- as.numeric()
r15 <- as.numeric()

r21 <- as.numeric()
r22 <- as.numeric()
r23 <- as.numeric()
r24 <- as.numeric()
r25 <- as.numeric()

r31 <- as.numeric()
r32 <- as.numeric()
r33 <- as.numeric()
r34 <- as.numeric()
r35 <- as.numeric()

r41 <- as.numeric()
r42 <- as.numeric()
r43 <- as.numeric()
r44 <- as.numeric()
r45 <- as.numeric()

r51 <- as.numeric()
r52 <- as.numeric()
r53 <- as.numeric()
r54 <- as.numeric()
r55 <- as.numeric()

# Inventory and Backlog
I10 <- as.numeric(0)
I20 <- as.numeric(0)
I30 <- as.numeric(0)
I40 <- as.numeric(0)
I50 <- as.numeric(0)

B10 <- as.numeric(0)
B20 <- as.numeric(0)
B30 <- as.numeric(0)
B40 <- as.numeric(0)
B50 <- as.numeric(0)


install.packages("lpSolve")
library(lpSolve)

#PERIOD 1
f.obj <- c(3,3,1,1,1,30,30)
f.con<- matrix(c(
  1,0,0,0,0,-1,0,
  0,1,0,0,0,0,-1,
  0,0,1,0,0,0,0,
  0,0,0,1,0,0,0,
  0,0,0,0,1,0,0,
                    
  0,0,0,0,0,1,0,
  0,0,0,0,0,0,1), nrow = 7, byrow = TRUE)

Constraint1.11 <- I10 - B10 - D10 + r1_1
Constraint1.21 <- I20 - B20 - D20 + r2_1
Constraint1.31 <- I30 - D30 + r3_3
Constraint1.41 <- I40 - D40 + r4_5
Constraint1.51 <- I50 - D50 + r5_1

Constraint2.11 <- B10 + D10
Constraint2.21 <- B20 + D20

f.rhs <- c(Constraint1.11, Constraint1.21, Constraint1.31, Constraint1.41,
               Constraint1.51, Constraint2.11, Constraint2.21)

f.dir <- c("=", "=", "=", "=", "=", "<=", "<=")

optimum <- lp(direction = "min", f.obj,f.con,f.dir,f.rhs)
optimum
optimum$solution

I11 <- optimum$solution[1]; I11
I21 <- optimum$solution[2]
I31 <- optimum$solution[3]
I41 <- optimum$solution[4]
I51 <- optimum$solution[5]
B11 <- optimum$solution[6]
B21 <- optimum$solution[7]

#PERIOD 2
Constraint1.12 <- I11 - B11 - D11 + r1_0; Constraint1.12
Constraint1.22 <- I21 - B21 - D21 + r2_0; Constraint1.22
Constraint1.32 <- I31 - D31 + r3_2
Constraint1.42 <- I41 - D41 + r4_4  
Constraint1.52 <- I51 - D51 + r5_0

Constraint2.12 <- B11 + D11
Constraint2.22 <- B21 + D21

f2.rhs <- c(Constraint1.12, Constraint1.22, Constraint1.32, Constraint1.42,
            Constraint1.52, Constraint2.12, Constraint2.22)
f2.rhs

optimum2 <- lp(direction = "min", f.obj, f.con, f.dir, f2.rhs)
optimum2$solution

I12 <- optimum2$solution[1]; I12
I22 <- optimum2$solution[2]
I32 <- optimum2$solution[3]
I42 <- optimum2$solution[4]
I52 <- optimum2$solution[5]
B12 <- optimum2$solution[6]; B12
B22 <- optimum2$solution[7]


#PERIOD 3: works well when we have only B and I unknown (not r)
Constraint1.13 <- I12 - B12 - D12 + r11
Constraint1.23 <- I22 - B22 - D22 + r21
Constraint1.33 <- I32 - D32 + r3_1
Constraint1.43 <- I42 - D42 + r4_3 
Constraint1.53 <- I52 - D52 + r51

Constraint2.13 <- B12 + D12
Constraint2.23 <- B22 + D22

f3.rhs <- c(Constraint1.13, Constraint1.23, Constraint1.33, Constraint1.43,
            Constraint1.53, Constraint2.13, Constraint2.23)
f3.rhs
optimum3 <- lp(direction = "min", f.obj, f.con, f.dir, f3.rhs)
optimum3$solution

I12 <- optimum2$solution[1]; I12
I22 <- optimum2$solution[2]
I32 <- optimum2$solution[3]
I42 <- optimum2$solution[4]
I52 <- optimum2$solution[5]
B12 <- optimum2$solution[6]
B22 <- optimum2$solution[7]


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source