在GAMS(General Algebraic Modeling System)中,变量、方程和模型类型是构建和求解优化模型的核心要素。本节将详细介绍这些基本概念,并通过具体例子展示如何在GAMS中使用它们。我们将从变量的定义和类型开始,然后讨论方程的构建方法,最后介绍不同类型的模型及其应用。
在GAMS中,变量用于表示模型中的决策变量或状态变量。变量的定义通常包括变量的名称、类型和范围。定义变量的基本语法如下:
Variable variable_name / initial_value /;
Variable
是变量定义的关键字。
variable_name
是变量的名称,可以使用任意合法的标识符。
initial_value
是变量的初始值(可选)。
GAMS支持多种类型的变量,每种类型有不同的用法和限制:
连续变量(Continuous Variable):可以在任意实数范围内取值。
整数变量(Integer Variable):只能取整数值。
二进制变量(Binary Variable):只能取0或1。
非负变量(Positive Variable):只能取非负值。
自由变量(Free Variable):可以在任意实数范围内取值。
负变量(Negative Variable):只能取非正值。
定义不同类型的变量的语法如下:
Positive Variable x1; // 非负变量
Negative Variable x2; // 负变量
Binary Variable x3; // 二进制变量
Integer Variable x4; // 整数变量
Free Variable x5; // 自由变量
变量的范围可以通过上下界来限制。定义变量范围的语法如下:
x1.lo = 0; // 设置下界
x1.up = 100; // 设置上界
x1.fx = 50; // 固定变量值
lo
表示变量的下界。
up
表示变量的上界。
fx
表示变量的固定值。
在石油化工领域,变量往往需要多维定义,以便表示不同的工艺参数或时间序列。多维变量的定义语法如下:
Set i / 1*3 /; // 定义索引集合
Positive Variable x(i); // 定义多维变量
变量可以初始化为特定值,这对于某些优化问题的求解非常有用。初始化变量的语法如下:
x1 = 10; // 初始化变量
假设我们有一个生产计划问题,需要决定两种产品的生产量,以最大化利润。我们定义两个非负变量 x1
和 x2
分别表示产品1和产品2的生产量。
Positive Variable x1, x2;
方程用于表示模型中的约束条件或目标函数。定义方程的基本语法如下:
Equation equation_name;
equation_name.. expression = type expression;
Equation
是方程定义的关键字。
equation_name
是方程的名称,可以使用任意合法的标识符。
expression
是方程的表达式。
type
是方程的类型,可以是 =e=
(等于)、=l=
(小于等于)或 =g=
(大于等于)。
目标函数用于表示模型的优化目标。定义目标函数的语法如下:
Equation obj;
obj.. z =e= expression;
obj
是目标函数的名称。
z
是目标变量。
expression
是目标函数的表达式。
约束条件用于限制模型中的变量。定义约束条件的语法如下:
Equation constraint_name;
constraint_name.. expression = type expression;
继续上一个例子,假设我们有以下约束条件:
产品1和产品2的生产总量不能超过100。
产品1和产品2的生产量分别不能超过50和70。
Equation total_production, product1_limit, product2_limit;
total_production.. x1 + x2 =l= 100;
product1_limit.. x1 =l= 50;
product2_limit.. x2 =l= 70;
在多维问题中,方程也可以定义为多维的。例如,假设我们有一个多阶段生产计划问题,需要在每个阶段定义约束条件。
Set t / 1*4 /; // 定义时间阶段集合
Equation production_limit(t);
production_limit(t).. x(t) =l= 50;
假设我们有一个多阶段生产计划问题,需要决定每个阶段的生产量,以最大化总利润。我们定义一个非负变量 x(t)
表示每个阶段的生产量,并定义一个目标函数 z
表示总利润。
Set t / 1*4 /; // 定义时间阶段集合
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, x(t) * 10); // 目标函数:总利润
production_limit(t).. x(t) =l= 50; // 约束条件:每个阶段的生产量不能超过50
线性规划模型是最基本的优化模型之一,其目标函数和约束条件都是线性的。定义LP模型的语法如下:
Model model_name / all /;
Solve model_name using LP maximizing z;
混合整数线性规划模型允许部分变量为整数。定义MILP模型的语法如下:
Model model_name / all /;
Solve model_name using MILP maximizing z;
非线性规划模型的目标函数或约束条件包含非线性项。定义NLP模型的语法如下:
Model model_name / all /;
Solve model_name using NLP maximizing z;
混合整数非线性规划模型允许部分变量为整数,并且目标函数或约束条件包含非线性项。定义MINLP模型的语法如下:
Model model_name / all /;
Solve model_name using MINLP maximizing z;
假设我们有一个混合整数线性规划问题,需要决定生产两种产品,并且产品1的生产量必须为整数。我们定义一个整数变量 x1
和一个非负变量 x2
,并定义一个目标函数 z
表示总利润。
Integer Variable x1;
Positive Variable x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= 20 * x1 + 30 * x2;
total_production.. x1 + x2 =l= 100;
product1_limit.. x1 =l= 50;
product2_limit.. x2 =l= 70;
Model production_plan / all /;
Solve production_plan using MILP maximizing z;
假设我们有一个非线性规划问题,需要决定生产两种产品,并且目标函数包含非线性项。我们定义两个非负变量 x1
和 x2
,并定义一个目标函数 z
表示总利润。
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= 20 * x1 + 30 * x2 - 0.1 * x1**2 - 0.05 * x2**2; // 目标函数:总利润
total_production.. x1 + x2 =l= 100;
product1_limit.. x1 =l= 50;
product2_limit.. x2 =l= 70;
Model production_plan / all /;
Solve production_plan using NLP maximizing z;
在多阶段问题中,模型可以定义为多阶段的。例如,假设我们有一个多阶段生产计划问题,需要在每个阶段定义目标函数和约束条件。
Set t / 1*4 /; // 定义时间阶段集合
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, x(t) * 10); // 目标函数:总利润
production_limit(t).. x(t) =l= 50; // 约束条件:每个阶段的生产量不能超过50
Model production_plan / all /;
Solve production_plan using LP maximizing z;
在GAMS中,数据可以通过参数、表格或文件输入。定义参数的语法如下:
Parameter parameter_name / value /;
Parameter
是参数定义的关键字。
parameter_name
是参数的名称,可以使用任意合法的标识符。
value
是参数的值。
假设我们有一个生产计划问题,需要输入产品的单位利润和生产限制。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Solve production_plan using LP maximizing z;
在GAMS中,数据输出可以通过 Display
语句实现。输出数据的语法如下:
Display variable_name, equation_name, parameter_name;
Display
是数据输出的关键字。
variable_name
、equation_name
和 parameter_name
是需要输出的变量、方程和参数的名称。
假设我们已经求解了上面的生产计划问题,需要输出最优解和目标值。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出最优解
假设我们有一个多阶段生产计划问题,需要输入每个阶段的单位利润和生产限制,并输出每个阶段的最优生产量和总利润。
Set t / 1*4 /; // 定义时间阶段集合
Parameter profit(t) / 1 20, 2 30, 3 25, 4 35 /, limit(t) / 1 50, 2 50, 3 50, 4 50 /;
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, profit(t) * x(t)); // 目标函数:总利润
production_limit(t).. x(t) =l= limit(t); // 约束条件:每个阶段的生产量不能超过50
Model production_plan / all /;
Solve production_plan using LP maximizing z;
Display x.l, z.l; // 输出每个阶段的最优生产量和总利润
在GAMS中,求解模型的基本语法如下:
Solve model_name using model_type [maximizing|minimizing] z;
Solve
是求解模型的关键字。
model_name
是模型的名称。
model_type
是模型的类型,如 LP
、MILP
、NLP
或 MINLP
。
maximizing
或 minimizing
表示优化目标是最大化或最小化。
z
是目标变量。
GAMS支持多种求解器,如 CPLEX
、GUROBI
和 CONOPT
等。选择求解器的语法如下:
Option model_type = solver_name;
Option
是设置求解器的关键字。
model_type
是模型的类型。
solver_name
是求解器的名称。
假设我们有一个线性规划问题,需要使用 CPLEX
求解器。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出最优解
假设我们有一个多阶段生产计划问题,需要使用 CONOPT
求解器。
Set t / 1*4 /; // 定义时间阶段集合
Parameter profit(t) / 1 20, 2 30, 3 25, 4 35 /, limit(t) / 1 50, 2 50, 3 50, 4 50 /;
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, profit(t) * x(t)); // 目标函数:总利润
production_limit(t).. x(t) =l= limit(t); // 约束条件:每个阶段的生产量不能超过50
Model production_plan / all /;
Option LP = CONOPT; // 选择求解器
Solve production_plan using LP maximizing z;
Display x.l, z.l; // 输出每个阶段的最优生产量和总利润
在GAMS中,可以通过 Display
语句和 abort
语句来调试模型。Display
语句用于输出中间结果,abort
语句用于在模型出错时终止程序。
GAMS提供了多种诊断工具来帮助诊断模型问题,如 Model.SolveStat
和 Model.ModelStat
。这些工具可以提供求解状态和模型状态的信息。
假设我们有一个线性规划问题,需要调试和诊断模型。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出最优解
* 模型诊断
if (production_plan.ModelStat = 1) then
Display "Model solved to optimality";
else
Display "Model not solved to optimality";
endif;
if (production_plan.SolveStat = 1) then
Display "Solver terminated normally";
else
Display "Solver terminated abnormally";
endif;
假设我们有一个多阶段生产计划问题,需要调试和诊断模型。我们定义一个时间阶段集合 t
,每个阶段的单位利润 profit(t)
和生产限制 limit(t)
,并定义相应的变量和方程。
Set t / 1*4 /; // 定义时间阶段集合
Parameter profit(t) / 1 20, 2 30, 3 25, 4 35 /, limit(t) / 1 50, 2 50, 3 50, 4 50 /;
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, profit(t) * x(t)); // 目标函数:总利润
production_limit(t).. x(t) =l= limit(t); // 约束条件:每个阶段的生产量不能超过50
Model production_plan / all /;
Option LP = CONOPT; // 选择求解器
Solve production_plan using LP maximizing z;
Display x.l, z.l; // 输出每个阶段的最优生产量和总利润
* 模型诊断
if (production_plan.ModelStat = 1) then
Display "Model solved to optimality";
else
Display "Model not solved to optimality";
endif;
if (production_plan.SolveStat = 1) then
Display "Solver terminated normally";
else
Display "Solver terminated abnormally";
endif;
Display
语句Display
语句可以用于输出变量、方程和参数的当前值,以便在模型求解过程中进行检查。例如:
Display x1.l, x2.l, z.l; // 输出变量的最优解
Display profit1, profit2, total_limit, limit1, limit2; // 输出参数的值
abort
语句abort
语句用于在模型出现错误时终止程序,并输出错误信息。例如:
if (x1.l < 0) then
abort "x1 cannot be negative";
endif;
ModelStat
ModelStat
属性提供了模型的求解状态信息。常见的 ModelStat
值及其含义如下:
1
:模型已求解到最优解。
2
:模型已求解到一个可行解,但可能不是最优解。
3
:模型无解。
4
:模型无界。
5
:模型未找到可行解。
6
:求解器因资源限制而终止。
7
:求解过程中出现错误。
SolveStat
SolveStat
属性提供了求解器的终止状态信息。常见的 SolveStat
值及其含义如下:
1
:求解器正常终止。
2
:求解器因资源限制而终止。
3
:求解器因用户中止而终止。
4
:求解器因错误而终止。
假设我们有一个线性规划问题,需要输出模型和求解器的状态信息。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出最优解
* 模型状态信息输出
Display "Model Status: ", production_plan.ModelStat;
Display "Solver Status: ", production_plan.SolveStat;
在模型求解后,可以通过 .l
属性获取变量的最优值。例如:
Display x1.l, x2.l, z.l; // 输出变量的最优解
对偶变量(也称为影子价格)表示约束条件的边际变化对目标函数的影响。可以通过 .m
属性获取对偶变量的值。例如:
Display total_production.m, product1_limit.m, product2_limit.m; // 输出约束条件的对偶变量
假设我们有一个生产计划问题,需要分析约束条件的对偶变量。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出最优解
* 输出对偶变量
Display total_production.m, product1_limit.m, product2_limit.m; // 输出约束条件的对偶变量
灵敏度分析用于研究模型参数变化对最优解的影响。在GAMS中,可以通过改变参数值并重新求解模型来进行灵敏度分析。
假设我们有一个生产计划问题,需要分析总生产限制 total_limit
的变化对最优解的影响。
Parameter profit1 / 20 /, profit2 / 30 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z;
Equation obj, total_production, product1_limit, product2_limit;
obj.. z =e= profit1 * x1 + profit2 * x2;
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
* 基准模型求解
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出基准模型的最优解
* 改变总生产限制进行灵敏度分析
total_limit = 150;
Solve production_plan using LP maximizing z;
Display x1.l, x2.l, z.l; // 输出改变总生产限制后的最优解
* 恢复原始参数值
total_limit = 100;
多目标优化问题涉及多个目标函数,需要在多个目标之间进行权衡。在GAMS中,可以通过加权和法或目标层次法来处理多目标优化问题。
假设我们有一个生产计划问题,需要同时最大化利润和最小化成本。我们定义两个目标函数 z_profit
和 z_cost
,并使用加权和法进行优化。
Parameter profit1 / 20 /, profit2 / 30 /, cost1 / 10 /, cost2 / 15 /, total_limit / 100 /, limit1 / 50 /, limit2 / 70 /;
Positive Variable x1, x2;
Free Variable z_profit, z_cost, z;
Equation obj_profit, obj_cost, total_production, product1_limit, product2_limit;
obj_profit.. z_profit =e= profit1 * x1 + profit2 * x2; // 目标函数:利润
obj_cost.. z_cost =e= cost1 * x1 + cost2 * x2; // 目标函数:成本
total_production.. x1 + x2 =l= total_limit;
product1_limit.. x1 =l= limit1;
product2_limit.. x2 =l= limit2;
Model production_plan / all /;
Option LP = CPLEX; // 选择求解器
* 定义加权和目标函数
Scalar weight_profit / 0.7 /, weight_cost / 0.3 /;
Equation obj;
obj.. z =e= weight_profit * z_profit - weight_cost * z_cost;
* 求解模型
Solve production_plan using LP maximizing z;
* 输出最优解
Display x1.l, x2.l, z_profit.l, z_cost.l, z.l;
动态优化问题涉及时间序列的决策,通常需要在多个时间阶段之间进行优化。在GAMS中,可以通过定义多维变量和方程来处理动态优化问题。
假设我们有一个动态生产计划问题,需要在多个时间阶段内决定生产量,以最大化总利润。我们定义一个时间阶段集合 t
,每个阶段的单位利润 profit(t)
和生产限制 limit(t)
,并定义相应的变量和方程。
Set t / 1*4 /; // 定义时间阶段集合
Parameter profit(t) / 1 20, 2 30, 3 25, 4 35 /, limit(t) / 1 50, 2 50, 3 50, 4 50 /;
Positive Variable x(t); // 定义多维变量
Free Variable z; // 定义目标变量
Equation obj, production_limit(t);
obj.. z =e= sum(t, profit(t) * x(t)); // 目标函数:总利润
production_limit(t).. x(t) =l= limit(t); // 约束条件:每个阶段的生产量不能超过50
Model production_plan / all /;
Option LP = CONOPT; // 选择求解器
Solve production_plan using LP maximizing z;
* 输出最优解
Display x.l, z.l;
* 模型诊断
if (production_plan.ModelStat = 1) then
Display "Model solved to optimality";
else
Display "Model not solved to optimality";
endif;
if (production_plan.SolveStat = 1) then
Display "Solver terminated normally";
else
Display "Solver terminated abnormally";
endif;
在GAMS中,变量、方程和模型类型是构建和求解优化模型的核心要素。通过定义不同类型的变量和方程,可以构建各种复杂的优化模型。模型的求解过程中,可以使用 Display
和 abort
语句进行调试,通过 ModelStat
和 SolveStat
属性进行诊断。此外,GAMS还支持多目标优化和动态优化等高级应用,使用户能够处理更复杂的优化问题。希望以上内容能够帮助读者更好地理解和使用GAMS语言。