作者tkcn (小安)
看板Prob_Solve
标题Re: [问题] 乐透号码最佳化的问题
时间Tue Jan 11 15:18:22 2011
先把最重要的结论写在最前头,
那就是我并没有想到什麽神奇的演算法 XD
20 个号码选 5 个开出,
也就是共有 C(20,5) = 15504 个可能的开奖组合,
这个数字实在说不上多,
我想即使是暴力法应该也不会花太多时间。
如果你只需要执行效率,而并不是非要提出一个演算法,
我建议采用 bit mask 来处理这问题,
例如开出 1 2 4 10 13 这五个号码时,
可以用 0001001000001011 (命名为 a) 来表示。
购买 2,10,13 这三个号码则是 0001001000000010 (命名为 b),
要判断这 3 个号码是不是全都包含在开奖号码内,
你只需要检查 (~a & b)==0 即可。 注: ~ 表示 bitwise not。
我相信用这种写法,比起阵列要快个五倍应该不是问题。
另外就是可以消去 C(20,5) 中不可能出现的组合,(即没有半个人中奖的组合)
我的想法是把所有的购买组合中只有一个号码的先拿出来,
重复的号码也只取一个,然後加入另外一个数。
例如数字 7 就会扩充成 (1,7), (2,7), ..., (6,7), (7,8), ..., (7,20)
然後再把所有购买组合种有两个号码的组合再加进去,
一样拿掉所有重复的,并且继续重复至共有 5 个数字,
这样集合中任一个开奖组合,
都可以保证至少有一个购买组合能中奖 (因为都是从购买组合扩充来的)
虽然这作法或许能加速,但并不会减少演算法的复杂度。
※ 引述《shipship (Ship)》之铭言:
: 最近在跑一个模拟,遇到一个最佳化问题请各位板大帮忙看看:
: 现有一个对奖系统,从20个号码中选5个做为这次的中奖号码
: 有一群下注资料,格式如下:
: 978 3 2 10 13 //奖金978元,买了三个号码,分别为2,10,13
: 5921 2 1 14
: 8027 4 1 4 6 9
: 7931 4 5 9 10 15 //奖金7931元,买了四个号码,分别为5,9,10,15
: 4957 2 2 16
: 中奖的条件是该客人所买的号码全中(全部都在5个中奖号码中出现)
: 假设今日开奖号码为1 2 4 10 13 16
: 则总奖金为978+4957
: 请求出,开出哪5个号码,可以使得大家所得到的奖金最高?
: 每个人可以买的号码数量为2~5,资料笔数不超过六千
: 我想了好久,目前都出的演算法,分析一下都还是暴力解。
: 请板大有甚麽意见请踊跃讨论 感谢
--
◤ ◥ ◢ ◣
T$,修好它吧。 ⊙▁⊙─ ─⊙▂⊙ 碰到问题,用SoftICE就对了!
╰ ∕皿﹨ ◥皿◤ ╯
◥█◤◢ ◥ ︶◤
Lee ◤ ︶ ◥◤ ﹨▼∕◥ T$ Chen
MYTHBUGTERS ◥ ◤\◥ by dajidali
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.114.78.231
1F:推 ledia:其实就是有出现过的数字取 5, 重新定 index 的做法 01/11 15:25
2F:推 shipship:抱歉不好意思,这是模拟的资料,真正的资料是C52取6 01/11 16:46
3F:推 shipship:如果暴力会变成 2*10^7*5*10^3(五千笔) *5(最多5个数字) 01/11 16:52
4F:→ shipship:10^12........> < 01/11 16:53
接续我的第二个解法。
在做扩充的时候,把原中奖金额加到扩充後的组合上,
这样开出来的时候,就已经算好总共会中多少钱了。
复杂度还是只有 C(52,6)。
※ 编辑: tkcn 来自: 140.114.78.231 (01/11 17:12)
5F:→ AmosYang:想不出有什麽神奇的办法可以把 big-O 从 O(n!) 降下来... 01/11 19:07
6F:推 ledia:感觉有机会 reduce 到 MAX-SAT ... 或是类似的 NPC 问题 01/11 21:56
7F:→ ledia:如果是这样的话, 就是暴力或估计了 01/11 21:56