简体   繁体   English

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

[英]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. 给定一天和每天的骑行,以下哪种组合最便宜。

  • A round trip ticket at cost w per round trip. 往返机票,每次往返费用为w
  • A 7 day ticket at cost x for unlimited rides during 7 consecutive calendar days. 7天连续7天的门票,费用为x ,无限次乘坐。
  • A 30 day ticket at cost y for unlimited rides during 30 consecutive calendar days. 在连续30个日历日内无限次乘坐的30天票价y
  • A 365 day ticket at cost z for unlimited rides during 365 consecutive calendar days. 成本为z的 365天机票,可在365个连续日历日内无限次乘坐。

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? 我可以使用什么算法来确定涵盖所有行程的最便宜的机票组合?

Hints 提示

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种类型的门票:

  • 1 day ticket costs P2, valid for one day only 1天的机票费用为P2,仅限一天
  • 7 days ticket costs P7, valid for 7 consecutive days from day of purchase 7天门票费用P7,自购买之日起连续7天有效
  • 30 days ticket costs P25, valid for 30 days of the month. 30天票价P25,有效期为30个月。

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.

相关问题 寻找最便宜的机票组合 - Finding Cheapest Combination of Tickets 根据选择条件查找最便宜的项目组合 - Finding cheapest combination of items with conditions on the selection 获取阵列中最便宜的项目组合以达到给定值 - Get the most cheapest combination of items in array to reach a given value 如何找到最便宜的地铁订阅组合 - How to find the cheapest combo of metro subscription 如何从多种产品中找到最便宜的组合 - How to find the cheapest combinations from a number of products 确定符号是否是第 i 个组合 nCr 的一部分 - Determine whether a symbol is part of the ith combination nCr 如何确定一组值之和的任何组合是否等于某个值? - How do I determine if any combination of the sum of a set of values is equal to a certain value? 给定大量具有价格和价格的商品列表,请选择10个商品的最便宜组合,其平均价格大于或等于固定值 - Given a big list of items with a price and a value, choose the cheapest combination of 10 items with an average value greater or equal to a fixed val 如果我的资金有限,我如何在DAG中找到最便宜的方式? - How can i find the cheapest way in a DAG if i have limited money? 如何在至少通过某些节点一次的条件下找到最便宜的遍历路径 - How to find the cheapest traversal path with condition of passing certain nodes at least once
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM