如何确定最便宜的通勤票组合

时间:2014-09-12 18:36:09

标签: algorithm dynamic-programming knapsack-problem

我的local train service最近为透析通勤添加了一个选项。我正在尝试确定在给定日期找到给定一组往返旅程中最便宜的机票组合的算法。

这是英文问题。给定一天和每天的骑行,以下哪种组合最便宜。

  • 往返机票,费用 w 每次往返。
  • 7天票,成本 x ,可连续7个日历日无限次乘坐。
  • 30天的成本 y ,可以连续30个日历日无限次骑行。
  • 成本 z 的365天门票,可在365个连续日历日内无限次骑行。

由于我很乐意将此限制为一次仅解决一年,我认为日期列表可以很容易地存储在一个看起来像这样的数组中。

{0,0,1,1,1,0,0,2,1,0,0,0,4,0,1,1,...,0,1,1,5}

数字等于每日往返次数。

我可以使用什么算法来确定涵盖所有行程的最便宜的票组合?

2 个答案:

答案 0 :(得分:5)

提示

你可以通过解决子问题来做到这一点:

What is the cheapest combination C[k] to cover all trips from day 0 up to day k?

要计算此子问题的答案,您可以简单地考虑购买故障单类型的每种情况。通过解决从0开始并一直工作到365的问题,您可以在解决子问题时使用以前的结果。

例如,假设在第100天你不需要旅行。那么答案将是C [99],这是前几天旅行中最便宜的方式。

然而,假设在第101天你需要进行3次旅行。那么C [101]的答案将是最便宜的:

Buy round trip tickets today: cost 3*w+C[100]
Buy a 7 day ticket 7 days ago: cost x+C[101-7]
Buy a 30 day ticket 30 days ago: cost y+C[101-30]

当您计算出C [365]时,您可以将其与全年票证的成本z进行比较。

(如果在此过程中您发现自己要求成本C [i] i小于0,则C [i]的值为0.)

答案 1 :(得分:0)

这是我在python中的解决方案。但首先,让我给出一些背景知识,以便下面的代码有意义。

问题陈述:

您想购买即将上市的公共交通票 月。你知道你将要旅行的日子。 这个月有30天,有3种票:

  • 1天票价P2,仅限一天
  • 7天票价P7,自购买之日起连续7天有效
  • 30天票价P25,有效期为30个月。

实施例,

month_travel_days = [1,2,4,5,7,29,30]

从示例旅行日起,最低成本为P11 一个7天的票,花费P7,然后单独购买 剩下两天的29日和30日费用P4。

解决最小化购票成本的问题 旅行日列表。

from operator import itemgetter

#travel_dates = [1,2,4,5,7,29,30]
travel_dates = [1,3,5,8,9,10]
#travel_dates = range(30)

def normalize(data):
    L = 30
    d1 = []
    for i in xrange(L):
        d1.append(1 if (i+1) in data else 0)
    return d1

def group_func(d):
    L = len(d)
    result = []
    for i in xrange(L):
        s = sum(d[i:i+7])
        result.append((i,s))
    return result

d1 = normalize(travel_dates)
mincost = 0
while True:
    a = group_func(d1)
    a.sort(key = itemgetter(1))
    m = a[-1][1]
    if m < 4:
        break
    for q in a:
        if q[1] == m:
            w = q
            break
    d1[w[0]:w[0]+7] = [0]*7
    mincost = mincost + 7 
mincost = mincost + d1.count(1) * 2
answer = min(25,mincost)
print "minimum cost = " + str(answer)