[英]How to Determine Cheapest Commute Ticket Combination
My local train service recently added an option for dialy commute. 我当地的火车服务最近添加了一个透析通勤选项。 I am trying to determine the algorithm for finding the cheapest combination of tickets for a given set of round trips on given days. 我正在尝试确定在给定日期找到给定一组往返旅行的最便宜的票组合的算法。
Here is the problem in english. 这是英文问题。 Given a set of days and and rides per day what combination of the following is the cheapest. 给定一天和每天的骑行,以下哪种组合最便宜。
Since I am happy to restrict this to only solving for one year at a time, I think that the list of days could easily be stored in an array that looks something like this. 由于我很乐意将此限制为一次仅解决一年,我认为日期列表可以很容易地存储在看起来像这样的数组中。
{0,0,1,1,1,0,0,2,1,0,0,0,4,0,1,1,...,0,1,1,5}
Where the number is equal to the number of round trips per day. 数量等于每天往返次数。
What algorithm can I use to determine the cheapest combination of tickets that covers all of the trips? 我可以使用什么算法来确定涵盖所有行程的最便宜的机票组合?
You can do this by solving the sub-problem: 你可以通过解决子问题来做到这一点:
What is the cheapest combination C[k] to cover all trips from day 0 up to day k?
To compute the answer to this sub-problem you can simply consider each of the cases of buying a ticket type. 要计算此子问题的答案,您可以简单地考虑购买故障单类型的每种情况。 By solving the problems starting at 0 and working all the way up to 365 you are allowed to use previous results when solving a sub-problem. 通过解决从0开始并一直工作到365的问题,您可以在解决子问题时使用以前的结果。
For example, suppose on day 100 you need to make no trips. 例如,假设在第100天您不需要旅行。 Then the answer will be C[99] which is the cheapest way of doing the trips on the previous days. 那么答案将是C [99],这是前几天旅行中最便宜的方式。
However, suppose on day 101 you need to make 3 trips. 但是,假设在第101天你需要进行3次旅行。 Then the answer for C[101] will be the cheapest of: 那么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]
When you have computed C[365] you can compare this to cost z for the all year ticket. 计算出C [365]后,您可以将其与全年票证的成本z进行比较。
(If during this process you ever find yourself requiring the cost C[i] for i less than 0, the value of C[i] is 0.) (如果在此过程中您发现自己要求成本C [i] i小于0,则C [i]的值为0.)
Here is my solution in python. 这是我在python中的解决方案。 But first, let me give some context so that the code below shall make sense. 但首先,让我给出一些背景信息,以便下面的代码有意义。
Problem statement: 问题陈述:
You want to buy public transport tickets for the upcoming month. 您想购买即将到来的月份的公共交通票。 You know the days on which you will be travelling. 你知道你将要旅行的日子。 The month has 30 days and there are 3 types of tickets: 这个月有30天,有3种类型的门票:
Example, 例,
month_travel_days = [1,2,4,5,7,29,30]
From the example travel days, the minimum cost is P11 by buying a 7-days ticket costing P7 and then buying separately for the remaining two days of 29th and 30th costing P4. 从示例旅行天数来看,最低成本为P11,购买7天票价为P7,然后分别购买29日和30日剩余的两天票价P4。
Solve the problem of minimizing the cost of ticket purchase given any list of travel days. 解决在任何旅行天数列表中最小化购票成本的问题。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.