算法:初探12306售票算法。

以G71列車爲例,首先對車次站臺進行佔位編碼(從1開始到最後一站遞加)

       

   對以上佔位簡單描述以下:G71總共18個站點那麼我們的單個座位的座位標識可以用十八位長度的二進制字符串表示10000000000000000每一位代表一個站點,每天放票前初始化到下面的訂票表中,數據如下餘票根據座位標識中的0的個數決定最大餘票數量

 訂票表中的始發受限站點和終到受限站點可以靈活搭配(這個就可以實現限制站點發售)

 限售渠道十進制 7 代表 1(車站)| 2(互聯網)|4(電話)=7 即該票允許  車站, 互聯網, 電話同時出售

    那麼還可以是 1|4 = 5  即該票只接受在車站和電話預定

   擴展 8(代售點) 16 (手機端) 

查詢餘票

如果我們要用互聯網渠道查詢日期爲2016-06-11,始發站保定東站(3)到韶關站(15)的G71二等座F座位餘票情況只需要執行如下sql(該SQL可以實現選座位和選車廂等功能)

select GUID,車次編碼,車次類型,座位類型,車廂號碼,座位編碼,座位位置,車票版本號 from 訂票表
where  座位標識=~((~座標標識)|000111111111111000)
and 發車日期='2016-06-11'
and 車次編碼='G71'
and 始發受限車站=始發受限車站|000100000000000000
and 終到受限車站=終到受限車站|000000000000001000
and 車次類型='二等座'
and 座位位置='F'and 受限渠道=2|受限渠道order by 餘票數量 asc ,車廂 asc  --先賣餘票少的,防止打亂更多的長途票

預定票

  • 根據第二步中查詢條件獲取一條記錄然後將車票狀態改爲鎖定
  • 待鎖定成功後進行支付
update 訂票表 set 座位標識=座位標識 | 000111111111111000,車票版本號=車票版本號+1,餘票數量 = 餘票數量-(15-3)
      where GUID = Md5(車次+座位編碼+發車日期) and 座位標識=~((~座標標識)|000111111111111000)--樂觀鎖

        根據更新結果是否爲1則可以判定購票成功
  •  支付成功後然後將保定到韶關的票保存到另外一張客戶的車票表中
  • 如果指定時間沒有支付,那麼直接調用退票sql

退票

  獲得該車次保定到韶關的票 (000111111111111000)與對應的票進行異或^運算,則即可迴歸票池子了

選座

       

update 訂票表 set 座位標識=座位標識 ^000111111111111000,餘票數量 = 餘票數量+(15-3),車票版本號=車票版本號+1 where GUID = Md5(車次+座位編碼+發車日期)  and 車票版本號=取得的版本號 --樂觀鎖


      根據返回結果爲1則標識退票成功

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章