「达摩院MindOpt APL 建模语言」语法说明 print 将结果写表格文件

用法简述

不同的编程语言写入表格文件的方式均不相同,下面将展示MindOpt APL建模语言的方式。

# 覆盖式样写csv文件
print "{}, {}, {}" % "日期", "班次", "员工编号" : "file.csv";
close "file.csv";

# append追加式样写csv文件
print "{}, {}, {}" % d,s,e >> "Schedule_Results.csv";
close "Schedule_Results.csv";

说明

建模语言介绍

  • MindOpt建模语言(MindOpt APL, 简称为MAPL)是MindOpt团队研发的一种代数建模语言。用MAPL描述数学规划模型与用数学公式进行描述非常类似。

语法

读数据

MAPL目前 read as读数据的方式支持两种数据格式 ns,即数值和字符串。数字表示要读入字段的索引,而 类型则表示按照何种类型来读入该字段。skip n表示跳过表格的第 n行内容。

写数据

任意MAPL支持的print语句+写入模式+文件名称即可将决策变量的取值打印成csv格式

  • 合法的 print/format print 语句
    • 任意MAPL支持的print语句,如 print A[1,2,3]
  • filename
    • 文本文件名,如 "result.txt""result.csv"等文本方式写
  • 两种写模式
    • : 表示第一次打开后是覆盖(overwrite)方式写,打开后在后续是拼接(append)方式写,如果不存在则新建文件。
    • >> 表示打开后都是拼接(append)方式写,如果不存在则新建文件。

更多使用方法可以参考MAPL文档:https://www.yuque.com/mindopt/apl/dw9pmekz73dxfxgd

应用

在优化问题中,人员排班就是个比较好的例子,排班表非常的适合以表格的方式展示结果。
代码:

clear model;

set Schedule = {read "班次.csv" as "<1s>" skip 1}; # 读取班次的名称

set Day = {read "需求人数.csv" as "<1n>" skip 1}; #读取排班的日期
param maxDay = max(Day);
print "待排",maxDay,"天的班";

param NumDemand = read "需求人数-长列表.csv" as "<1n,2s> 3n" skip 1; #读取每天各个班次的需求人数,原横纵表拉成长列表为了读取数据方便

param totalSlots = sum {<d,s> in Day*Schedule} NumDemand[d,s];
print "总共有",totalSlots,"个班次待排";

#预估上班人数
param maxEmployee = ceil(totalSlots/5) + 1; #如果班次需求特殊导致不可解的时候,可以增加员工
print "设置参与排班人数:",maxEmployee;
set Employee = {1..maxEmployee};

#声明变量 
var x[Day*Schedule*Employee] binary; 

#约束
subto constraint_0 :
    forall {<d,s> in Day*Schedule}
         sum {e in Employee} x[d,s,e] >= NumDemand[d,s]; #满足用工需求

subto constraint_1 : 
    forall {<d,e> in Day*Employee}
            sum {s in Schedule} x[d,s,e] <= 1;  #每人每天只排一个班次
          
set DayPre = Day without {<maxDay>}; #去掉最后一天
subto constraint_2 : 
    forall {e in Employee}
        forall {d in DayPre}
            x[d,"夜班0-8点",e] + x[d+1,"早班8-16点",e] <= 1; #前一天晚班的,第二天不排早班

subto constraint_3 : 
    forall {e in Employee}
        sum {<d,s> in Day*Schedule} x[d,s,e] <= 5; #待排的7天里只上5天班
      
      
minimize minOnduty: sum {<d,s,e> in Day*Schedule*Employee} x[d,s,e];


#求解
option solver mindopt;     # (可选)指定求解用的求解器,默认是MindOpt
option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印
solve;         # 求解

# 结果打印和检查结果
print "-----------------Display---------------";
#display; #打印太多,注释了
# 将结果打印为数据表格
print "{}, {}, {}" % "日期", "班次", "员工编号" : "Schedule_Results.csv";
close "Schedule_Results.csv";

forall {<d,s,e> in Day*Schedule*Employee with x[d,s,e] >0}
    print "{}, {}, {}" % d, s,e >> "Schedule_Results.csv";

close "Schedule_Results.csv";

结果:

待排7天的班
总共有99个班次待排
设置参与排班人数:21
Running mindoptampl
wantsol=1
print=0
MindOpt Version 1.0.0 (Build date: 20231013)
Copyright (c) 2020-2023 Alibaba Cloud.

Start license validation (current time : 17-NOV-2023 16:52:20).
License validation terminated. Time : 0.004s


OPTIMAL; objective 99.00

Completed.

输出的 Schedule_Results.csv表格部分结果:
image.png

更多应用示例

案例代码均可点击链接查看

  1. 物流运输 将每条通道分别运输多少商品写成表格

将结果输出为表格:

print "{},{},{} "% "起点","途径点","商品数量" : "Results.csv";
close "Results.csv";

forall {<i, j> in LINKS}
    print "{},{},{}" % i,j,Ship[i,j]  >> "Results.csv";

close "Results.csv";

结果如下:
image.png

  1. 排产排程 将每月每种油脂的处理方式、生产计划写成表格

将结果输出为表格:

print "{}, {}, {}, {}" % "油脂", "月份", "处理方案","数量" : "每月油脂处理方式.csv";
close "每月油脂处理方式.csv";

forall {<j,m,n> in O*M*N}
    print "{}, {}, {}, {}" % j, m, n, x[j,m,n] >> "每月油脂的处理方式.csv";

close "每月油脂处理方式.csv";

print "{}, {}" % "月份", "生产计划" : "Results_.csv";
close "Results_.csv";

forall {<m> in M}
    print "{}, {}" % m,y[m] >> "Results_.csv";

close "Results_.csv";

结果如下:

image.pngimage.png
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值