昨天读到一个项目,是关于优化求解的。

约束条件如下:

公司里有很多客户,客户之所以不继续用我们的产品了,是因为他账户余额是负的,所以,为了重新赢回这些客户,公司决定发放优惠券cover掉客户账户的负余额。

具体细节:

  • 只有8元,80元,200元的优惠券
  • 发放给一个客户的优惠券总张数不能超过15张
  • 要既能cover掉客户的负余额,又要保证发放给客户的优惠券张数最少
  • 发放给客户的总金额-客户的亏损额不能大于8,且越小越好。(不能送太多便宜了)
####################### 构造一个数据框,里面包含所有可能的送券组合################################
x=data.frame(x=rep(0:15,1)) # 表示 200的券 的张数
y=data.frame(y=rep(0:15,1)) # 表示 80的券 的张数
z=data.frame(z=rep(0:15,1)) # 表示 8的券 的张数
library(sqldf)
# 做笛卡尔积
df <- sqldf('select * from x,y,z')
head(df)
df$coupon_sum <-apply(df,1,sum) # 对行求和
df$amt_sum <- df$x*200+df$y*80+df$z*8 # 加权重求和
#过滤掉 sum>15的 组合
df <- sqldf('select * from df where coupon_sum<=15 order by amt_sum asc')
## step 2
#######################################################
### 下面是给出任意一个 亏损 比如 loss=-987,则 fun2(-987) 返回出用200,80,8各几张,能获得gap最小
fun2 <- function(i){
if(i< -3000){
return(data.frame(loss=i,x=15,y=0,z=0,coupon_sum=15,amt_sum=3000,gap=3000+i))
} else {
df$gap <- i+df$amt_sum
df_positive <- sqldf('select * from df where gap>=0')
res <- sqldf('select * from df
where gap in (select gap from df_positive order by gap limit 1)
order by gap,coupon_sum
limit 1')
return(cbind(loss=i,res))
}
}
## step 3
# #### 建一个 函数 fun3,其中调用了fun2
fun3 <- function(original_df){
final_res <- data.frame()
for(m in 1:length(original_df[,1])){
row.res <- cbind(customID=original_df[m,1],fun2(original_df[m,2]))
final_res <- rbind(final_res,row.res)
}
return(final_res)
} ## step 4
# 构造一个测试数据集 test.df 进行测试
test.df <- data.frame(customID=rep(1:200,1),loss=abs(rnorm(200))*(-2000))
test.df
final_res <- fun3(test.df)
head(final_res)
write.csv(final_res,"final_res.csv",sep = ",")

规划求解

\(\min\ result= 200x+80y+8z\)

\[f(x)=
\begin{cases}
x \le 15 ,\\
y \le 15 ,\\
z& \le 15 ,\\
x+y+z \le 15 ,\\
200x+80y+8z \ge -temp ,\\
\text{x,y,z为正整数}
\end{cases}\]

library(Rglpk)

obj <-c(200,80,8,)
mat<-matrix(c(1,0,0,1,200,0,1,0,1,80,0,0,1,1,8),nrow = 5)
mat
dir<-c(rep("<=",4),">=")
types<-c("I", "I", "I")
max<-F
Rglpk_solve_LP(obj, mat, dir, rhs, types = types, max = F)
resa<-data.frame()
for (i in 1:nrow(test.df)){
temp<-test.df[i,2]
rhs<-c(15,15,15,15,-temp)
if(temp < -3000){
temp1<-cbind(temp,matrix(c(15,0,0,15,3000),ncol=5),temp+3000)
}else{
temp_result<-Rglpk_solve_LP(obj, mat, dir, rhs, types = types, max = F)
temp1<-cbind(temp,matrix(temp_result$auxiliary$primal,ncol = 5),temp+temp_result$auxiliary$primal[5])
}
resa<-rbind(resa,temp1)
}
str(resa)
write.table(resa,"resa3.csv",sep=",")

结果如下

head(resa)
temp V2 V3 V4 V5 V6 V7
1 -2367.9663 11 2 1 14 2368 3.374016e-02
2 -640.3149 0 8 1 9 648 7.685126e+00
3 -1281.4575 6 1 1 8 1288 6.542478e+00
4 -4498.5225 15 0 0 15 3000 -1.498523e+03
5 -2639.6479 12 3 0 15 2640 3.521064e-01
6 -2447.9996 11 3 1 15 2448 4.106828e-04

R语言 批量规划求解的更多相关文章

  1. R语言:规划求解优化ROI

    今天看到一篇文章介绍如何用excel建模对ROI 进行规划求解. 蓝鲸的网站分析笔记 成本 Cost 每次点击费用 CPC 点击量 \[clickRate = \frac{cost}{CPC}\] 转 ...

  2. R语言教程规划

    本文发表在博客园, http://www.cnblogs.com/stackworm/ 尽管进展中出现了意想不到的事情,期间中断1个多月,但我仍然会坚持下去. 首先,这份教程适合所有对R语言有兴趣且希 ...

  3. R语言批量生成变量(变量名中含有参数)

    我们经常会需要生成这样一类的变量,比如a1,a2,a3...... 这时候我们需要用到这两个函数:get()和assign() get()用法 get()函数只是在环境中搜索该变量名的变量,如果该变量 ...

  4. R语言 批量下载财务报表

    getsheets <- function(symbol,type,file){ pre="http://money.finance.sina.com.cn/corp/go.php/v ...

  5. R语言之RCurl实现文件批量下载

    前言: RCurl工具包的作者是由Duncan Temple Lang现任加州大学 U.C. Davis分校副教授.他曾致力于借助统计整合进行信息技术的探索.使用者通过RCurl可以轻易访问网页,进行 ...

  6. 寻找与疾病相关的SNP位点——R语言从SNPedia批量提取搜索数据

    是单核苷酸多态性,人的基因是相似的,有些位点上存在差异,这种某个位点的核苷酸差异就做单核苷酸多态性,它影响着生物的性状,影响着对某些疾病的易感性.SNPedia是一个SNP调査百科,它引用各种已经发布 ...

  7. R语言︱文件读入、读出一些方法罗列(批量xlsx文件、数据库、文本txt、文件夹)

    笔者寄语:小规模的读取数据的方法较为简单并且多样,但是,批量读取目前看到有以下几种方法:xlsx包.RODBC包.批量转化成csv后读入. R语言中还有一些其他较为普遍的读入,比如代码包,R文件,工作 ...

  8. R语言从小木虫网页批量提取考研调剂信息

    一.从URL读取并返回html树     1.1 Rcurl包         使用Rcurl包可以方便的向服务器发出请求,捕获URI,get 和 post 表单.比R socktet连接要提供更高水 ...

  9. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(二,textreuse介绍)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 上一篇(R语言实现︱局部敏感哈希算法(LSH) ...

随机推荐

  1. openstack七大模块概述

    前言 OpenStack主要由七部分组成,分别是Identify, Image, Network, Compute, Block Storage, Object Storage, Dashboard, ...

  2. Junit mockito 测试Controller层方法有Pageable异常

    1.问题 在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的 ...

  3. Practical oral English

    1.如果你继续发烧,我就去请医生过来If your fever continues, I'll send for the doctor.2.在这么大的停车场里,我是永远都找不到我的车的I'll nev ...

  4. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  5. Spring mvc

    1... . 2.spring 的结构图 3.spring mvc 架构 4.Spring mvc 的请求流程 . 文字讲解: request-------->DispatcherServler ...

  6. win10+vs2013+cuda8.0+caffe

    1,首先说下环境和配置 配置: 环境:windows10,vs2013 community,cuda8.0,caffe,cudnn4 注意:先要安装好显卡驱动(我的显卡是1070),这里的例子只开通了 ...

  7. 微信H5中的一些坑

    最近在写微信公众号H5页面 遇到了一些坑,在这里记录一下 记录一下signature的计算 // 首先找到hex_sha1的加密算法,ticket 是后端提供的 var url_local = loc ...

  8. [LeetCode] Pacific Atlantic Water Flow 太平洋大西洋水流

    Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...

  9. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(三):两个Viewmodel搞定增删改查

    前言:之前博主分享过knockoutJS和BootstrapTable的一些基础用法,都是写基础应用,根本谈不上封装,仅仅是避免了html控件的取值和赋值,远远没有将MVVM的精妙展现出来.最近项目打 ...

  10. Ubuntu上基于开源代码PhoneMe的J2ME环境搭建及使用

    测试环境:Ubuntu 14.04.5 LTS J2ME背景知识及PhoneME介绍 J2ME相关介绍 在正式开始介绍J2ME之前,这里我列出一些常见名词,方便与下文参照:J2ME(Java2 Pla ...