在生活中,以及计算机程序,AGV交通管理中,我们会碰到类似A->B的逻辑。如"A事件会导致B事件","A集合包含B集合","A车被B车阻挡"等。
有时,由于程序编写错误,或运行方式不合理,会导致出现逻辑死循环,如A->B, B->C, C->A,这样的三条逻辑如果同时成立,会导致A->B->C->A->B->...的永无休止的逻辑链。计算机程序如果这样运行,会导致无法完成程序;AGV如果出现这样的逻辑,会导致车辆相互阻挡,谁也无法让谁,导致交通堵塞且无法解除。所以,本文介绍一个算法,可以根据已输入的逻辑,找出里面是否存在死循环,若有就给出提醒,提前避免这样的现象。
算法的大致思路:对于每一条A->B形式的二元逻辑,构建一条从A开始的逻辑链。首先,A->B是逻辑链的第一环,然后有了A->B,要寻找以B开头的二元逻辑。这样的寻找,会有三种情况:
-
找不到以B开头的逻辑。这样,逻辑链从A到B就停止了,不存在从这一条逻辑开始的死循环逻辑。
-
有以B开头的逻辑,但逻辑的下一个元素并不在当前逻辑链中已有的的任何一环。例如现在逻辑链里有AB但找到的逻辑是B->C (
),那么逻辑链尚没有结束,也尚没有形成死锁。此时从C开始继续找。
-
有以B开头的逻辑,且逻辑的下一个元素在当前的逻辑链里已经存在了。例如,有了A->B,B->C,此时当前逻辑链已有ABC,然后找以C开头的逻辑,找到了C->A,因此逻辑的下一个元素A在当前逻辑链里存在。那么就说明有死循环了。
那么,死循环在哪里呢?从哪开始了呢?显然,如果逻辑组是A->B,B->C,C->D,D->B,那么逻辑链就会是ABCDB...,当发现B在ABCD里已出现时就可判断死循环存在。而B是ABCD中的第二个元素。所以,死循环应当是从已有逻辑链的第二个元素开始,即BCD。
现在,用python程序实现逻辑链死循环判断。
假定目前的二元逻辑组用python字典储存:
python
{'a': ['b'], 'c':['d']}
以上代表存在逻辑a->b,c->d。例如,a车被b车挡住,c车被d车挡住。
那么判断是否存在逻辑链死循环的python程序这样写
python
def deadlockDetection(blockage_dict:dict):
"""
This function identify the deadlock from traffic blockage graph
:param blockage_dict: Dictionary with format {'a': ['b'], 'c':['d']}
which means a is blocked by b, c is blocked by d
:return: A list of vehicles in a deadlock chain. If no deadlock, return []
"""
for k in blockage_dict.keys():
chain = [k]
current_key = k
while(True):
if blockage_dict[current_key][0] in chain: # deadlock found
idx = chain.index(blockage_dict[current_key][0])
chain.append(blockage_dict[current_key][0])
chain = chain[idx:]
return chain
else:
chain.append(blockage_dict[current_key][0])
if blockage_dict[current_key][0] in blockage_dict.keys(): # deadlock not found yet but the chain is still ongoing
current_key = blockage_dict[current_key][0]
else: # the chain stopped, no deadlock
break
return []
程序里,if下的情况是第三种情况(死循环找到),else里的if下是第二种情况(没找到死循环但逻辑链未结束),else里的else下是第一种情况(没找到死循环,逻辑链已结束),所以会break。
但要注意,从一个二元逻辑没找到死循环,不代表从第二个,第三个二元逻辑中也不会找到死循环。所以每一个二元逻辑都要过。
程序输入:
python
{"c":["d"], "d":["b"], "a":["b"], "a":["e"], "e":["a"]}
输出:
python
["a","e"]