火车票购票问题2
来源:互联网 发布:古希腊神话 知乎 编辑:程序博客网 时间:2024/05/10 13:38
看过火车票购票问题1
的朋友可能已经发现,还有可以优化的方案
方案1:
在处理购票请求的后期,某些站点区间可用的票数已经为0,
那么后续再有类似请求时,可以直接返回失败
这里的特殊情况是,如果有人退票,则某个站点区间又会有可卖的票,可以通过在购票高峰期限制退票来排除这个特殊情况。
对应文件 sell2.py
# -*- coding: utf-8 -*-############################################################# 假定站点编号从 1 ~ 10# 共20节车厢, 每个车厢20排# 编号形如# 1A 1B 1C 1D 1F# 2A 2B 2C 2D 2F# ...# 20A 20B 20C 20D 20F# 20 * 5 * 20 = 2000个座位# 其实座位编号完全可以从 0 ~ 1999, 并不影响我们对问题本身的分析############################################################import timeMAX_CARRIAGE_NUM = 20MAX_ROW_NUM = 20MAX_SITE_INDEX = 10class Seg(object): def __init__(self, carriage_no, seat_no, start_site, end_site): # 车厢编号 self.carriage_no = carriage_no # 座位编号 self.seat_no = seat_no # 完整编号 self.no = str(carriage_no) + '-' + seat_no # 能够售卖的开始站序号 int self.start_site = start_site # 能够售卖的终点站序号 int self.end_site = end_site def __str__(self): return str((self.no, self.start_site, self.end_site))def init(): ticket_dict = {} for i in range(1, MAX_SITE_INDEX): for j in range(i + 1, MAX_SITE_INDEX + 1): ticket_dict[(i, j)] = [] for i in range(1, MAX_CARRIAGE_NUM + 1): for row in range(1, MAX_ROW_NUM + 1): for col in ['A', 'B', 'C', 'D', 'F']: # 每个座位都可以出售从s1 到 s10的车票 key = (1, 10) # print Seg(i, str(row) + col, 1, 10) ticket_dict[key].append(Seg(i, str(row) + col, 1, 10)) return ticket_dictdef sell(ticket_dict, start, end, sellout_dict): ''' :param ticket_dict: :param start: 购票的起始站 :param end: 购票的终点站 :return: ''' if sellout_dict.get((start, end), False): return None # 需要找到一个有票的站点区间覆盖目标站点区间 # 所有可能的起始站 site_start = [] x = 1 while x <= start: site_start.append(x) x += 1 site_start.reverse() # 所有可能的终点站 site_end = [] y = end while y <= MAX_SITE_INDEX: site_end.append(y) y += 1 ticket = None for x in site_start: for y in site_end: if len(ticket_dict[(x, y)]) > 0: ticket = ticket_dict[(x, y)].pop() if ticket: # 判断一下这个座位的站点区间是否被完全用完了 # 如果没有还需要把新生成的余票间存回去 if start > x: temp = Seg(ticket.carriage_no, ticket.seat_no, x, start) ticket_dict[(x, start)].append(temp) if y > end: temp = Seg(ticket.carriage_no, ticket.seat_no, end, y) ticket_dict[(end, y)].append(temp) return Seg(ticket.carriage_no, ticket.seat_no, start, end) # 对于(start, end), 没有可以卖的票 # 那说明所有覆盖 (start, end) 的站点区间都没有票了 for x in site_start: for y in site_end: sellout_dict[(x, y)] = True return Nonedef print_residual(ticket_dict): print '------------余票情况-------------' for key in ticket_dict: if ticket_dict[key]: print key, len(ticket_dict[key])if __name__ == '__main__': ticket_dict = init() sellout_dict = {} t1 = time.time() with open('req.csv') as fp: for line in fp: ll = line.split(',') user = ll[0] start = int(ll[1]) end = int(ll[2]) ticket = sell(ticket_dict, start, end, sellout_dict) print '#' * 100 print line.strip() if ticket: print user, "bought", ticket print_residual(ticket_dict) # time.sleep(2) t2 = time.time() print t2 - t1
经过测试,速度又提升了20% ,处理10w请求只用了1秒多
方案2:考虑多线程并发处理
经过测试,速度反而下降了60倍,很有可能是因为计算量不大,且资源竞争以及频繁的上下文切换,反而影响了性能
对应文件 sell3.py
完整代码地址:
https://github.com/vearne/train_ticket
后记:
本文只是对购票过程的一个模拟,但是将不同的车次分而治之的处理,确实是一个提高并发能力的一个好方法。并且可以考虑内存处理 + 数据库处理相结合的办法,或者直接将数据移植到数据库中进行操作以确保事务性。
0 0
- 火车票购票问题2
- 火车票购票问题1
- 火车票购票指南
- 火车票购票指南
- 火车票互联网购票流程
- 火车票购票系统模拟
- 火车票购票系统模拟
- 火车票购票系统模式
- 火车票购票系统模拟
- 火车票购票系统模拟
- 火车票购票系统模拟
- 火车票购票系统模拟
- 火车票购票系统模拟
- my12306 火车票购票软件使用方法
- 铁道部12306火车票购票网站浅析
- 12306.cn 春运火车票“秒杀”购票心得
- 对铁道部12306火车票购票网站的浅析
- 模拟火车票购票系统的简单多线程程序
- Application onCreate函数多次被调用
- ngx_slab_pool
- JAVA NIO之浅谈内存映射文件原理与DirectMemory
- 初步体验微信后台开发
- 使用webpack打包Vue工程
- 火车票购票问题2
- HDU1157 POJ2338 Who's in the Middle
- orcale 包,包体,函数,游标.(未完)
- iOS-webView上加载HTML视频不显示缩略图
- 人民币小写转换成大写
- 常见电脑截屏技巧汇总
- 从今天开始写博客
- ios::sync_with_stdio(false);
- java多聚合,少继承,低耦合,高内聚