0

我目前正在尝试创建一个模型,其中将目标函数的结果应用于问题中的所有行时将用于推荐目的。

    !********************************************************************************
! 1. Import Modules
! 2. This part is used to define result format and directories
!********************************************************************************

model "savings portfolio"
    uses "mmxprs", "mmsheet"

parameters
    CAPITAL = 100000000
    INPUTFILE = "C:/Users/Admin/Downloads/201031_SAVINGS_ACCOUNTS3_v1.0.xlsx"! 3. File directory for data file
    RESULTFILE = "C:/Users/Admin/Downloads/201031_SAVINGRESULTS3_v1.0.xlsx"! 4. File directory for result file
end-parameters

!********************************************************************************
! 5. Declare variable types
! 6. Variable types as well as the mpvar must be declared first before importing data
!********************************************************************************
declarations
    INDEX: set of integer
    PRODUCTNAME: array(INDEX) of string
    MONTH: array(INDEX) of integer
    MONTH2: array(INDEX) of integer
    MININVEST: array(INDEX) of integer
    MININVEST2: array(INDEX) of integer
    PRINCIPAL: array(INDEX) of mpvar  ! 7. mpvar refers to the variable that is to be optimized
    PRINCIPAL2: array(INDEX) of mpvar
    INTEREST: array(INDEX) of real
    INTEREST2: array(INDEX) of real
end-declarations


!********************************************************************************
! 8. "XPRS_VERBOSE" settings: Enable to view problem statistics
!********************************************************************************
setparam("XPRS_VERBOSE", true)

!********************************************************************************
! 9. Read data
!********************************************************************************
initializations from "mmsheet.xlsx:"+INPUTFILE
    [PRODUCTNAME,INTEREST,MONTH,MININVEST,INTEREST2,MONTH2,MININVEST2] as "[Sheet1$A2:H501]" !10.Select data from excel sheet excluding headers, must include index column
end-initializations

!********************************************************************************
! 11. Calculating YEAR
!********************************************************************************
forall(i in INDEX) YEAR(i):=MONTH(i)/12
forall(i in INDEX) YEAR2(i):=MONTH2(i)/12

!********************************************************************************
! 12. Objective Function
!********************************************************************************
SUMDIFF:=sum(i in INDEX) (PRINCIPAL(i)*(1+(INTEREST(i)/MONTH(i)))^(MONTH(i)*getsol(YEAR(i))) - PRINCIPAL2(i)*(1+(INTEREST2(i)/MONTH2(i)))^(MONTH2(i)*getsol(YEAR(i))))

!********************************************************************************
! 13. Constraints
!********************************************************************************
sum(i in INDEX) PRINCIPAL(i) = CAPITAL
sum(i in INDEX) PRINCIPAL2(i) = CAPITAL
forall(i in INDEX) PRINCIPAL(i) >= MININVEST(i)
forall(i in INDEX) PRINCIPAL2(i) >= MININVEST2(i)
SUMDIFF >= 0

!********************************************************************************
! 14. Optimization method
!********************************************************************************
maximize(SUMDIFF)

!********************************************************************************
! 15. Calculate variables
!********************************************************************************
forall(i in INDEX) PRINSTANDIFF(i):=(getsol(PRINCIPAL(i))*(1+(INTEREST(i)/MONTH(i)))^(MONTH(i)*getsol(YEAR(i)))) - (getsol(PRINCIPAL2(i))*(1+(INTEREST2(i)/MONTH2(i)))^(MONTH2(i)*getsol(YEAR(i))))
forall(i in INDEX) INVESTMENT1(i):=getsol(PRINCIPAL(i))
forall(i in INDEX) INVESTMENT2(i):=getsol(PRINCIPAL2(i))


initializations to "mmsheet.xlsx:"+RESULTFILE
    [PRODUCTNAME,INVESTMENT1,INVESTMENT2,PRINSTANDIFF] as "grow;[Sheet1$A2:E2]"
end-initializations

end-model

该模型的目的是使用 PRINSTANDIFF 中的值来决定投资哪个选项。如果结果值为正,则选项 1 (INVESTMENT1) 是更好的选择,而如果值为负,则选项 2 (INVESTMENT2) 是更好的选择。更好的选择。

我的问题是,有没有办法控制我可以通过约束从模型中获得的正值和负值的数量?理想情况下,我希望将正面和负面的数量保持在 6:4 的最小比例和 7:3 的最大比例。

4

1 回答 1

0

详细说明我的评论并将其转化为答案:像您描述的那样的任务可以通过指标约束来实现。

这个想法是引入二进制辅助变量,如果表达式为正则为 1,如果为负则为 0:

declarations
    SIGN: array(INDEX) of mpvar
end-declarations
forall(i in INDEX) SIGN(i) is_binary

然后通过指示符约束将它们与表达式的符号连接起来

forall(i in INDEX) indicator(1, SIGN(i), EXPR(i) >= 0)
forall(i in INDEX) indicator(-1, SIGN(i), EXPR(i) <= 0)

这样,如果是非负数,SIGN(i)则为 1 ,如果非正数,则为 0 。EXPR(i)SIGN(i)EXPR(i)

现在您可以将正表达式的数量写为sum(i in INDEX) SIGN(i),将负表达式的数量写为sum(i in INDEX) (1 - SIGN(i))。因此,可以通过以下方式强制执行两者的比率

4 * sum(i in INDEX) SIGN(i) >= 6 * sum(i in INDEX)(1 - SIGN(i)) ! minimum ratio: sum_of_positive/sum_of_negative >= 6/4
3 * sum(i in INDEX) SIGN(i) <= 7 * sum(i in INDEX)(1 - SIGN(i)) ! maximum ratio: sum_of_positive/sum_of_negative <= 7/3

剩下的唯一问题是EXPR(i)适当地定义为 mpvars 中的表达式。这可能是一个问题,因为它似乎涉及一些非线性。

于 2021-03-04T07:21:18.503 回答