字典,其中值可以是列表或列表的列表

问题描述 投票:0回答:2

我正在尝试使用 networkx 库绘制卡车路线优化的结果。首先我必须准备数据,但我被困住了。

这是初始数据的小示例:

Vehicle       Route  
0       V0   [0,3](V0) 
1       V0   [3,0](V0)  
2       V1   [0,3](V1) 
3       V1   [0,8](V1) 
4       V1   [2,0](V1) 
5       V1   [3,2](V1) 
6       V1   [8,0](V1) 

有两辆卡车:V0 和 V1。 V0 的路线是:0 到 3 到 0。但是 V1 有两条路线:0 到 8 到 0 和 0 到 3 到 2 到 0。

每次游览必须在节点 0 开始和结束。

我必须解决两个问题:

  1. 对于每辆卡车(V0,V1),我必须找到给定列表中以零开头和结尾的所有旅行
  2. 游览流程不能有中断:每个子游览的结束 [0,8] 必须是下一个 [8,0] 的开始

最终结果一定是这样的:

{'V0': [0,3,0], 'V1': [[0,3,2,0], [0,8,0]]}

我有一个代码,但它没有产生我想要的东西:

tours = {'V0': ['0,3', '3,0'], 'V1': ['0,3', '0,8', '2,0', '3,2', '8,0']}


def convert_to_list(s):
    return list(map(int, s.split(',')))

# Function to process each value in the 'tours' dictionary
def process_value(value):
    result = []
    current_list = []

    for pair in value:
        pair_list = convert_to_list(pair)

        if not current_list or pair_list[0] == 0:
            current_list.extend(pair_list)
        elif pair_list[1] == 0:
            current_list.append(pair_list[0])
            current_list.append(0)
            result.append(current_list)
            current_list = [0]
        else:
            current_list.append(pair_list[0])

    if current_list:
        current_list.append(0)
        result.append(current_list)

    return result

# Create the 'tours1' dictionary using the processing functions
tours1 = {key: process_value(value) for key, value in tours.items()}

# Print the result
print(tours1)

输出:

{'V0': [[0, 3, 3, 0], [0, 0]], 'V1': [[0, 3, 0, 8, 2, 0], [0, 3, 8, 0], [0, 0]]}

有什么想法吗?

谢谢!

python list dictionary nested-lists
2个回答
0
投票

主要思想是将数据组织成树,然后进行深度优先搜索以检索有效路线。

将数据组织成树:

tours = {'V0': ['0,3', '3,0'], 'V1': ['0,3', '0,8', '2,0', '3,2', '8,0']}

tours2 = {}

for vehicle, routes in tours.items():
    route_tree = {}
    for route in routes:
        frm,to = route.split(',')
        frm = int(frm)
        to = int(to)
        
        if frm in route_tree:
            route_tree[frm].append(to)
        else:
            route_tree[frm] = [to]
    tours2[vehicle] = route_tree

旅游2:

{'V0': {0: [3], 3: [0]}, 'V1': {0: [3, 8], 2: [0], 3: [2], 8: [0]}}

DFS有效路线:

routes = {}

for vehicle in tours2:
    running_routes = [[0]]
    completed_routes = []

    while running_routes:
        running_route = running_routes.pop()
        
        if running_route[-1] == 0 and len(running_route) > 1:
            completed_routes.append(running_route)
        else:
            for nxt_node in tours2[vehicle][running_route[-1]]:
                running_routes.append(running_route + [nxt_node])

    routes[vehicle] = completed_routes

路线:

{'V0': [[0, 3, 0]], 'V1': [[0, 8, 0], [0, 3, 2, 0]]} 

0
投票

这是一个 O(N^2) 的可行解决方案,其中 N 是节点数(如果没有点可以到达两次)。

tours = {'V0': ['0,3', '3,0'], 'V1': ['0,3', '0,8', '2,0', '3,2', '8,0']}


def process(value):
    result = []  # the final result

    nodes = {}  # a dictionary in the form of start_node: end_node
    starts = []  # a list of pairs (start, end) where start is 0

    for val in value:  # goes through each step
        a, b = val.split(",")  # get start and end
        nodes[a] = b  # add the node to nodes
        if a == "0":  # if the step is a start, add it to starts
            starts.append((a, b))

    for a, b in starts:  # go through each starts
        inter = [a, b]  # list representing one route
        while b != "0":  # as long as we didn't return to 0, continue
            b = nodes[b]  # get the next node
            inter.append(b)  # add it to the route
        result.append(inter)

    return result


def convert():
    """
    Goes through each truck and process it's routes.
    """
    result = {}
    for k, v in tours.items():
        result[k] = process(v)
    return result


print(convert())

这给出了结果:

{'V0': [['0', '3', '0']], 'V1': [['0', '3', '2', '0'], ['0', '8', '0']]}

如果你希望第二个列表的维度为 1,你可以在 process 方法中添加一个 if 检查,如下所示:

def process(value):
    result = []  # the final result

    nodes = {}  # a dictionary in the form of start_node: end_node
    starts = []  # a list of pairs (start, end) where start is 0

    for val in value:  # goes through each step
        a, b = val.split(",")  # get start and end
        nodes[a] = b  # add the node to nodes
        if a == "0":  # if the step is a start, add it to starts
            starts.append((a, b))

    for a, b in starts:  # go through each starts
        inter = [a, b]  # list representing one route
        while b != "0":  # as long as we didn't return to 0, continue
            b = nodes[b]  # get the next node
            inter.append(b)  # add it to the route
        result.append(inter)

    if len(result) == 1:
        return result[0]
    return result

© www.soinside.com 2019 - 2024. All rights reserved.