求教一个组合促销的最佳组合算法

fox_blue 2003-09-11 10:51:04
假如客户购买了四种商品 A、B、C、D 而商家规定了 ABC、ABD、BCD 三种不同的促销方案,假如对于客户来讲,BCD的方案最省钱,那么如何确定这个方案呢?请各位大侠给个思路
...全文
281 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
ShallowShrimp 2003-09-20
  • 打赏
  • 举报
回复
主要是看用在什么情况下,从应用的角度上看,动态规划还是比较实用的。
ZhangYv 2003-09-20
  • 打赏
  • 举报
回复
BlueSky2008() 的方法是贪心算法,因为无法证明局部最优就是全局最优,但还算是比较简单和好用的近似方法
ShallowShrimp(浅水虾) 的算法就是穷举了,可以说对于稍大一点点的规模算法就会失效了。因为这时候组合方案就暴增,求解域太大了!
ShallowShrimp 2003-09-20
  • 打赏
  • 举报
回复
你有更好的方法吗?不妨说来听听...
SoftWare1999 2003-09-19
  • 打赏
  • 举报
回复
求解维数解决了,

空间还是没有解决

你仍然要
a^maxa*b^maxb*...z^maxz,增长太快
ShallowShrimp 2003-09-19
  • 打赏
  • 举报
回复
只要改成递归,就有弹性了:)
ShallowShrimp 2003-09-18
  • 打赏
  • 举报
回复
假设客户购买了maxa个a,maxb个b,maxc个c,maxd个d.

fillchar(things,sizeof(things),maxint);

//基本价
things[0,0,0,0]:=0;
things[1,0,0,0]:=10; //A's prize
things[0,1,0,0]:=15; //B's prize
things[0,0,1,0]:=20; //C's prize
things[0,0,0,1]:=30; //D's prize

//优惠组合
things[1,1,1,0]:=35; //A-B-C
things[0,1,1,1]:=50; //B-C-D
things[1,1,1,1]:=60; //A-B-C-D
things[2,1,1,2]:=70; //2A-B-C-2D
...

for a:=0 to maxa do
for b:=0 to maxb do
for c:=0 to maxc do
for d:=0 to maxd do
begin
for i:=0 to a do
for j:=0 to b do
for k:=0 to c do
for l:=0 to d do
if things[a,b,c,d]>things[i,j,k,l]+things[a-i,b-j,c-k,d-l] then
things[a,b,c,d]:=things[i,j,k,l]+things[a-i,b-j,c-k,d-l];
end;

things[maxa,maxb,maxc,maxd]即为最优组合。
ShallowShrimp 2003-09-18
  • 打赏
  • 举报
回复
不会占很大的空间。
如果买得最多时是购买所有商品各一百件。
那么只需要建立一个四维数据things[0..100,0..100,0..100,0..100]即可。

things[a,b,c,d]=max{ things[i,j,k,l]+things[a-i,b-j,c-k,d-l] }
0<=i<=a
0<=j<=b
0<=k<=c
0<=l<=d
SoftWare1999 2003-09-18
  • 打赏
  • 举报
回复
你这是某年ioi的题目类似,他规定的规模刚好是申请数组的最大值。
这也是竞赛题判断是否,一点可以投机取巧的办法。
原来可以这样子,现在不知道还行不行。

如果有6件物品,10件物品呢,你怎么办?
ZhangYv 2003-09-16
  • 打赏
  • 举报
回复
这个问题似乎属于“子集和”问题,我不敢断定这个问题是否NP难的,但当商品数和优惠方案很多时会明显会出现组合爆炸,用些搜索算法看看能否解决。我再回去想想,不过楼主最后别把问题考虑复杂化,也要有采用近似算法的准备。
fox_blue 2003-09-16
  • 打赏
  • 举报
回复
To: BlueSky2008()
穷举所有算法效率可能不能够接受
比如说吧,商家经常用的“买越多越便宜”的促销方案 对商品A 单价 50
(1)一次买2A 90 (2)一次买3A 120 如果顾客一次买了100A
那么这样
' 100A
' (1)/ \(2)
' 98A 97A
' (1) / \(2) (1)/ \(2)
' 96A 95A 95A 94A
' / \ / \ / \ / \
' ... ... ... ... ... ... ...
每录入一笔交易,都需要重新计算一次 这样取下来耗费的时间很难满足要求
fox_blue 2003-09-16
  • 打赏
  • 举报
回复
To ShallowShrimp(浅水虾)

我对算法不是很熟悉,不够这两天看了一下动态规划法,它使用的条件其中有一条是 “无后向性”即:将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。

而我遇到的问题不满足这个条件 比如
有三种组合
组合1 可折扣3元
组合2 可折扣6元
组合3 可折扣4元
在一笔交易中,顾客的商品列表满足两种优惠方式 (1)组合1 + 组合2 或者 (2)组合3 + 组合3
如果按照每一阶段都选择最优的方案 那么第一步应该选 组合1 然后再选就只能满足组合2, 但是这种方式并不比两个组合3更优惠。


请各位大侠再帮小地想想办法,谢谢了

SoftWare1999 2003-09-16
  • 打赏
  • 举报
回复
题目规模不大用动规一定没问题,否则空间会不够的,几天前本来我已经发了回复。结果CSDN丢失我的回复。
也就没有再发。

今天看到 BlueSky2008的想法,是对的。

但是写的时候,应该还要注意一点,如:
A 10
B 20
AAB 30

要购买3A2B
可以选择:AAB+A+B=30+10+20=60
也可以选择:AAB+AAB=30+30=60的。
显然第2种好些,这样的话,动规的最后结束集合就要扩大。

因为你的题目,假设比较少,属于自己建模的类型。自己可以再加些合理的限定条件

BlueSky2008 2003-09-16
  • 打赏
  • 举报
回复
前面没太看懂楼主的意思,现在明白了。
你的意思就是说假如客户购买了A、A、B、B四个商品、而商家规定AA,BB,AB三种组合方式,
则客户可以用(AA)(BB)的组合方式,也可以用(AB)(AB)的组合方式是吧?

这个确实是有动态规划的性质的。
首先,为了便于描述,我们定义“块”是:每个种类的单独的一个商品 或 商家规定的组合方式。
这样,顾客购买的商品一定能够分解成“块”的组合。

现在问题就是:对给定的一些商品,找一个最优块分解。
使得按照这个分解方式计算总价值最小。
最优块分解有一个重要性质:从最优块分解中去掉一个块,剩下的仍是相对于剩下的商品的一个最优块分解。现在程序应该不难写了吧?


fox_blue 2003-09-15
  • 打赏
  • 举报
回复
谢谢提醒 我去找资料好好学习学习
fox_blue 2003-09-12
  • 打赏
  • 举报
回复
各种组合方式有商家定义,这对程序来讲是不确定的,假如有一笔交易,满足四重组合方式 1、2、3、4 中的任意两种 12,13,14,23,24,34 那么怎么确定选择哪种方案呢?也就是选择那两种组合方式对顾客进行优惠?随着顾客购买的商品种类增多,达成组合的几率也会增大,因为交易每增加一条明细纪录,都需要重新检查一下各种组合,穷举所有的组合方案效率会不会成问题?
ShallowShrimp 2003-09-12
  • 打赏
  • 举报
回复
典型的动态规划法,查一下往届IOI竞赛题就知了.
BlueSky2008 2003-09-11
  • 打赏
  • 举报
回复
穷举一下所有方案不就行了?

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧