python实现车辆重排问题

1. 根据要求完成车辆重排的程序代码

假设一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1n,货运列车按照第n站至第1站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1H2H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。

图1 具有三个缓冲区铁轨的转轨站

编写算法实现火车车厢的重排,模拟具有n节车厢的火车“入轨”和“出轨”过程。

代码:

"""
车厢重排算法
"""
from Task03_Stack import stack1
"""
在所有缓冲轨车厢中选一个缓冲轨放入车厢c
stacks:缓冲轨道
c:待放入的车厢
minVal:缓冲轨道的最小值
minStack:缓冲轨道的最小值所在的缓冲轨道编号
"""
def output(stacks, n):
    global minVal, minStack
    stacks[minStack].pop()
    print('移动车厢 %d 从缓冲铁轨 %d 到出轨。' % (minVal, minStack))
    minVal = n + 2
    minStack = -1
    for index, stack in enumerate(stacks):
        if((not stack.isempty()) and (stack.top() < minVal)):
            minVal = stack.top()
            minStack = index

def inputStack(i, stacks, n):
    global minVal, minStack
    beskStack = -1  # 最小车厢索引值所在的缓冲铁轨编号
    bestTop = n + 1  # 缓冲铁轨中的最小车厢编号
    for index, stack in enumerate(stacks):
        if not stack.isempty():  # 若缓冲铁轨不为空
            # 若缓冲铁轨的栈顶元素大于要放入缓冲铁轨的元素,并且其栈顶元素小于当前缓冲铁轨中的最小编号
            a = stack.top()
            # print('stack.top()的类型是', a)
            if (a > i and bestTop > a):
                bestTop = stack.top()
                beskStack = index
        else:  # 若缓冲铁轨为空
            if beskStack == -1:
                beskStack = index
                break
    if beskStack == -1:
        return False
    stacks[beskStack].push(i)
    print('移动车厢 %d 从入轨到缓冲铁轨 %d。' % (i, beskStack))
    if i < minVal:
        minVal = i
        minStack = beskStack
    return True

def rail_road(list, k):
    global minVal, minStack
    stacks = []
    for i in range(k):
        stack = stack1.ArrayStack()
        stacks.append(stack)
    nowNeed = 1
    n = len(list)
    minVal = n + 1
    minStack = -1
    for i in list:
        if i == nowNeed:
            print('移动车厢 %d 从入轨到出轨。' % i)
            nowNeed += 1
            # print("minVal", minVal)
            while (minVal == nowNeed):
                output(stacks, n)  # 在缓冲栈中查找是否有需求值
                nowNeed += 1
        else:
            if(inputStack(i, stacks, n) == False):
                return False
    return True

if __name__ == "__main__":
    list = [3, 6, 9, 2, 4, 7, 1, 8, 5]
    k = 3
    minVal = len(list) + 1
    minStack = -1
    result = rail_road(list, k)
    while(result == False):
        print('需要更多的缓冲轨道,请输入需要添加的缓冲轨道数量。')
        k = k + int(input())
        result = rail_road(list, k)

下面是问题分析。

2.车辆重排问题分析

现在分析图 1,为了重排车厢,需从前至后依次检查入轨上的所有车厢:

  • 如果正在检查的车厢就是下一个满足排列要求的车厢,可以直接把它放到出轨上去;
  • 如果不是,则把它移动到缓冲铁轨上,直到按输出次序要求轮到它时才将它放到出轨上;
  • 缓冲铁轨上车厢的进和出只能在缓冲铁轨的尾部进行。

在重排车厢过程中,仅允许以下移动:

1、车厢可以从入轨移动到一个缓冲铁轨的尾部或进入出轨接在重排的列车后。

2、车厢可以从一个缓冲铁轨的尾部移动到出轨接在重排的列车后。

考察图1 (a), 3 号车厢在入轨的前部,但由于它必须位于 1 号和 2 号车厢的后面,因此不能立即输出 3 号车厢,可把 3 号车厢送入缓冲铁轨 H1。

下一节车厢是 6 号车厢,也必须送入缓冲铁轨。如果把 6 号车厢送入 H1,那么重排过程将无法完成,因为 3 号车厢位于 6 号车厢的后面,而按照重排的要求,3 号车厢必须在 6 号车厢之前输出。因此可把 6 号车厢送入 H2。

下一节车厢是 9 号车厢,被送入 H3,因为如果把它送入 H1 或 H2,重排过程也将无法完成。

至此,缓冲铁轨的当前状态如图 2 (a) 所示。
图2 缓冲铁轨中间状态

接下来处理 2 号车厢,它可以被送入任一一个缓冲铁轨,因为它能满足缓冲铁轨上车厢编号必须递增排列的要求,不过,应优先把 2 号车厢送入 H1,因为如果把它送入 H3 ,将没有空间来移动 7 号车厢和 8 号车厢。如果把 2号车厢送入 H2,那么接下来的 4 号车厢必须被送入 H3,这样将无法移动后面的 5 号、7 号和 8 号车厢。

新的车厢 u 应送入这样的缓冲铁轨:

其底部的车厢编号 v 满足 v>u,且 v 是所有满足这种条件的缓冲轨顶部车厢编号中最小的一个编号。只有这样才能使后续的车厢重排所受到的限制最小。

接下来处理 4 号车厢时,三个缓冲铁轨顶部的车厢分别为 2 号、6 号、9 号车厢。根据分配规则,4 号车厢应送入H2。

这之后,7 号车厢被送入 H3。图2 (b) 给出了当前的状态。

接下来,1 号车厢被送至出轨,这时,可以把 H1 中的 2 号车厢送至出轨。

之后,从 H1 输出 3 号车厢,H2 输出 4 号车厢。

至此,没有可以立即输出的车厢了。

接下来的 8 号车厢被送入 H1,然后 5 号车厢从入轨处直接输出到出轨处。这之后,从 H2 输出 6 号车厢,从 H3输出 7 号车厢,从 H1 输出 8 号车厢,最后从 H3 输出 9 号车厢。到此为止,“出轨”完毕!

让我们整理一下算法思路:

  • 第一步:若需出轨的编号恰是入轨编号,则直接出轨;
  • 第二步:若需出轨的编号恰是缓冲轨的最小编号,则直接出轨;
  • 第三步:将入轨编号放入缓冲轨。(规则:放到满足小于缓冲轨栈顶元素编号且栈项元素最小的上面。)

参考链接:

王争《数据结果与算法之美》:https://time.geekbang.org/column/article/41222

利用“栈”解决“出轨”问题:https://mp.weixin.qq.com/s/-yjukwKISKuAkr4LL3eFIQ

欢迎关注微信公众号 shinerise,与你一起慢慢进步~

Alt

发布了34 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Shine_rise/article/details/103929581
今日推荐