You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Lingo中定义依赖集合?附订单分配建模场景

如何在Lingo中定义依赖于工厂的机器集合?

某企业拥有5个工厂,各工厂的机器数量分别为3、4、5、2、3台,需将20份订单分配至各工厂的对应机器,成本仅与订单所属工厂相关。当前建模默认所有工厂都拥有17台机器,实际需求为:

  • 1号工厂对应本地机器编号1-3(或全局编号1-3)
  • 2号工厂对应本地机器编号1-4(或全局编号4-7)
  • 3号工厂对应本地机器编号1-5(或全局编号8-12)
  • 4号工厂对应本地机器编号1-2(或全局编号13-14)
  • 5号工厂对应本地机器编号1-3(或全局编号15-17)

需要定义依赖于工厂的机器集合,避免无效的工厂-机器组合。


原模型代码

Model:
Sets:
orders/1..20/:;
plants/1..5/:;
machines/1..17/:;
allocation(orders, plants): c;
assign(orders, plants, machines): x;
end sets

data:
c =  1  2  3  4  5
     6  7  8  9 10
    10  9  8  7  6
     5  4  3  2  1
     1  2  3  4  5
     6  7  8  9 10
    10  9  8  7  6
     5  4  3  2  1
     1  2  3  4  5
     6  7  8  9 10
    10  9  8  7  6
     5  4  3  2  1
     1  2  3  4  5
     6  7  8  9 10
    10  9  8  7  6
     5  4  3  2  1
     1  2  3  4  5
     6  7  8  9 10
    10  9  8  7  6
     5  4  3  2  1;
end data
min = @sum(assign(i, j, k): c(i, j) * x(i, j, k));
@for(orders(i): @sum(plants(j): @sum(machines(k): x(i, j, k))) = 1);
@for(assign(i, j, k): @bin(x(i, j, k)));
end

解决方案

方案一:使用本地机器编号(嵌套派生集合)

给每个工厂分配独立的本地机器编号(从1开始计数),通过嵌套派生集合实现依赖关系:

Model:
Sets:
    orders/1..20/:;
    plants/1..5/: machine_count;  // 存储每个工厂的机器数量
    // 嵌套集合:每个工厂j对应的本地机器编号1到machine_count(j)
    machines_by_plant(plants, *):;  
    allocation(orders, plants): c;
    // 订单分配到工厂j的本地机器k
    assign(orders, machines_by_plant): x;  
End Sets

Data:
    machine_count = 3 4 5 2 3;  // 各工厂的机器数量
    c =  1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1;
End Data

// 生成每个工厂对应的本地机器集合
@for(plants(j): machines_by_plant(j, 1..machine_count(j)));

// 目标函数:最小化总分配成本
min = @sum(assign(i, j, k): c(i, j) * x(i, j, k));

// 约束1:每个订单必须分配到一台机器
@for(orders(i): @sum(machines_by_plant(j, k): x(i, j, k)) = 1);

// 约束2:分配变量为二进制(0=未分配,1=已分配)
@for(assign(i, j, k): @bin(x(i, j, k)));
end

方案二:使用全局机器编号(带过滤条件的派生集合)

如果需要保留全局机器编号(1-17),通过过滤条件定义仅包含工厂对应全局机器范围的集合:

Model:
Sets:
    orders/1..20/:;
    plants/1..5/: start_machine, end_machine;  // 每个工厂对应的全局机器起止编号
    machines/1..17/:;
    allocation(orders, plants): c;
    // 过滤条件:仅包含工厂j对应的全局机器k(k在start到end之间)
    assign(orders, plants, machines) | k #ge# start_machine(j) #and# k #le# end_machine(j): x;  
End Sets

Data:
    // 各工厂对应的全局机器范围
    start_machine = 1 4 8 13 15;
    end_machine = 3 7 12 14 17;
    c =  1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1
         1  2  3  4  5
         6  7  8  9 10
        10  9  8  7  6
         5  4  3  2  1;
End Data

// 目标函数:最小化总分配成本
min = @sum(assign(i, j, k): c(i, j) * x(i, j, k));

// 约束1:每个订单必须分配到一台机器
@for(orders(i): @sum(assign(i, j, k): x(i, j, k)) = 1);

// 约束2:分配变量为二进制
@for(assign(i, j, k): @bin(x(i, j, k)));
end

两种方案的区别

  • 方案一用本地编号,逻辑更直观,适合无需跟踪全局机器编号的场景;
  • 方案二保留全局编号,适合需要明确对应具体物理机器的场景。

内容的提问来源于stack exchange,提问作者Ceria FM Tantrika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:54:56