IT宅来解答所谓的12306的售票所谓库存算法难题

【引言】 在天涯上看到有人发帖,也在Iteye上看到相同论调,本人对某些人所谓的“库存”难题的思路不以为然,对此,鄙人给出个算法模型,献丑,只为打某些人的脸!

一下是iteye上一篇文章提出的问题

[quote]好了,讲了这半天淘宝,可以说12306了吧?

我以北京西到深圳北的G71次高铁为例(这里只考虑南下的方向,不考虑深圳北到北京西的,那是另外一个车次,叫G72),它有17个站(北京西是01号站,深圳北是17号站),3种座位(商务、一等、二等)。表面看起来,这不就是3个商品吗?G71商务座、G71一等座、G71二等座。大部分轻易喷12306的技术人员(包括某些中等规模公司的专家、CTO)就是在这里栽第一个跟头的。

实际上,G71有136*3=408种商品(408个SKU),怎么算来的?请看:

如果卖北京西始发的,有16种卖法(因为后面有16个站),北京西到:保定、石家庄、郑州、武汉、长沙、广州、虎门、深圳。。。。都是一个独立的商品,

同理,石家庄上车的,有15种下车的可能,以此类推,单以上下车的站来计算,有136种票:16+15+14….+2+1=136。每种票都有3种座位,一共是408个商品。

好了,再看出票时怎么减库存,由于商务、一等、二等三种座位数是独立的,库存操作也是一样的,下文我就不再提座位的差别的,只讨论出发与到达站。另外,下文说的是理论世界的模型,不是说12306的数据库就是这么设计的。

旅客A买了一张北京西(01号站)到保定东(02号站)的,那【北京西到保定东】这个商品的库存就要减一,同时,北京西到石家庄、郑州、武汉、长沙、广州、虎门、深圳等15个站台的商品库存也要减一,也就是说,出一张北京到保定东的票,实际上要减16个商品的库存!

这还不是最复杂的,如果旅客B买了一张北京西(01号站)到深圳北(17号站)的票,除了【北京西到深圳北】这个商品的库存要减一,北京西到保定东、石家庄、郑州、武汉、长沙、广州、虎门等15个站台的商品库存也要减1,保定东到石家庄、郑州、武汉、长沙、广州、虎门、深圳北等15个站台的商品库存要减1。。。总计要减库存的商品数是16+15+14+……+1=120个。

当然,也不是每一张票都的库存都完全这样实时计算,可以根据往年的运营情况,在黄金周这样的高峯时段,预先对票做一些分配,比如北京到武汉的长途多一点,保定到石家庄的短途少一点。我没有证据证实铁道部这样做了,但我相信,在还没有12306网站的时候,铁道部就有这种人工预分配的策略了。

[/quote]

这里是我给出的模型思路

  1.假设一列车从 A站驶往Z站 ,车上共有500个座位,也就是500张票

  途径站点示意图如下:(用专业的话说,一个长度26的数组)

  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

  有乘客甲购买了从 C –> R 站的车票,则在本列车对应站点的数组位置 +1,这里注意R站下车,R站不加1

  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

  0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

  乘客乙购买了从 H–》V 的车票 ,同样在本列车对应站点的数组位置 +1

  A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

  0 0 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1

  那么当乘客丙要购买从 A –》 P 站的票时,系统只要计算,从数组A –> P位置上乘客数量是否都小于500即可

  请问,这样的算法很逻辑很复杂么??!!加一操作现在很多NoSQL数据库都能支持原子性操作的。

  另外给出12306在系统架构上的2点可能可行的建议

  第一,按不同列车划分服务器,需要同步的是列车的数据,不同列车可以分布在不同服务器计算

  第二,同一列列车的票务计算应该分服务器,以“分销商”形式进行分布式结算

  以上述例子为例,如果将500张票,从总服务器预售给5台子服务器,每台子服务器售出自己的100张票后,在向总服务器结算,并从其他子服务器进行重新调度,这样同样避免了中央服务器的负担,同时能保证数据一致性问题。

上述设计只是个框架性草案,只想告诉大家,12306的设计虽然复杂,但绝对没有某些人吹嘘的那样不能解决。我的这些算法估计在淘宝工程师面前,只是小儿科,别跟我较真。

总之,想铁道部那么大的机构,搞不定这样的问题,只能喷它管理不善,

点赞