0

我正在尝试将社团分配给送货卡车。卡车可以承受有限的负载并且有有限的时间。一个社会有一个交付时间。我也有仓库之间的旅行时间(卡车只从这里出发)和一个数据框,其中包含从每个社会到其他社会的旅行时间。

代码运行良好,但是当数据很大时会花费很多时间。有一个简单的方法吗?

1 辆卡车最大装载量:350 个订单。

1 辆卡车最长交货时间:135 分钟

下面是数据表。

Order_Count : 社会订单数

仓库时间:从仓库到社会的旅行时间

DeliveryTime : 在社会上交付订单的时间。

Society_ID  Order_Count warehouse_time  DeliveryTime
    1   305            1722             4122
    2   168            1409             4557
    3   231            1331             7026
    7   216            1466             4684
    8   212            1202             3929
    9   65             1050             2341
    10  59             1355             2580
    11  199            1417             4957
    12  54             1380             1352
    14  117            1498             3388

另一个数据框有来自每个社会的旅行时间。

s1  s2  Time
1   1   0
2   1   914
3   1   898
7   1   1000
8   1   1024
9   1   1044
10  1   1140
11  1   1173
12  1   822
14  1   1013
1   2   907
2   2   0
3   2   1076
7   2   1054
8   2   1013
9   2   1033
10  2   623
11  2   656
12  2   804
14  2   1173
1   3   675
2   3   824
3   3   0
7   3   514
8   3   633
9   3   653
10  3   1049
11  3   1083
12  3   296
14  3   633
1   7   767
2   7   958
3   7   507
7   7   0
8   7   768
9   7   787
10  7   1184
11  7   1217
12  7   431
14  7   604
1   8   1009
2   8   1159
3   8   896
7   8   875
8   8   0
9   8   303
10  8   1384
11  8   1417
12  8   631
14  8   994
1   9   903
2   9   1052
3   9   790
7   9   769
8   9   131
9   9   0
10  9   1278
11  9   1311
12  9   525
14  9   888
1   10  900
2   10  661
3   10  1069
7   10  1048
8   10  1006
9   10  1026
10  10  0
11  10  242
12  10  798
14  10  1167
1   11  963
2   11  723
3   11  1131
7   11  1110
8   11  1069
9   11  1089
10  11  261
11  11  0
12  11  860
14  11  1229
1   12  562
2   12  711
3   12  744
7   12  723
8   12  681
9   12  701
10  12  937
11  12  970
12  12  0
14  12  842
1   14  805
2   14  990
3   14  539
7   14  654
8   14  799
9   14  819
10  14  1221
11  14  1254
12  14  463
14  14  0

目前我已经编写了一个逻辑,但是当数据大小增加时需要时间。下面是相同的代码。

# stored the order count, if exceeding 350 then find remainder 
orderCount  = defaultdict( lambda: 0 )

# will store how many fully loaded trucks shall be sent to society with 350 orders
fullyLoadedTrucks = defaultdict( lambda: 0 )

for index, row in wdf.iterrows():
    orderCount[row['Society_ID']] = (int(row['Order_Count']))

# implementation of above mentioned comments.
for i in orderCount:
    if orderCount[i] > maxOrderCount:
        fullyLoadedTrucks[i] = orderCount[i]// maxOrderCount
        orderCount[i] %= maxOrderCount

# quotient = no. of fully loaded truck for eg. OrderCount for some society id = 1225, then we need to send 3 
#fullyloaded trucks and one partially filled with 175 orders 1225//350 = 3, 1225 % 350 = 175


# time spent from going from wh to society
timeFromWH   = OrderedDict()

# time spent during delivery within the society
deliveryTime = dict()


for _, row in wdf.iterrows():
    sid = int(row['Society_ID'])
    timeFromWH[sid] = int(row['total_time'])

    deliveryTime[sid] = int(row['Delivery_Time'])

for _, row in sdf.iterrows():
    sid = int(row['society_1'])
    sdf.at[_, 'Time'] =  deliveryTime[sid] + int(row['Time'])
    # set 'time' of i'th society equal to time spent in delivering goods in that society + time spent on traveling

sdf.head()

time = defaultdict(OrderedDict)
for _, row in sdf.iterrows():
    _from = int(row['society_2'])
    _to = int(row['society_1'])
    if _from == _to: continue
    time[_from][_to] = int(row['Time'])                     
    # MOST IMPORTANT: if we decide to go from society x to y then how much time will we require on travel and delivering goods in society y,
    # NOTE: we don't consider the time spent in societey x in time[x][y], we assume we have already somehow reached x
    # this loop is the reason why overall time complexity of this code reaches O(n**2)

visited = defaultdict(lambda : False) # No society is visited
CountOfVisited = 0 # initially 0 societies are visited
path = defaultdict(lambda : [])
truck = 1 # This variable will give the total number of trucks required
truckNumber = defaultdict(lambda: []) # This dict will store the trucknumber of i'th society
truckOrder = defaultdict(lambda: [])
considered = defaultdict(lambda: True)

while CountOfVisited != len(wdf):
    # until all societies are visited
    if not len(timeFromWH): break
    society, timereq = timeFromWH.popitem(last=False)     
    '''  ^^^^^^
    pops out closest society and timereq for both: going from warehouse to the society and delivering goods in the society 

    '''
    while visited[society]:
        society, timereq = timeFromWH.popitem(last=False)    # closest society has already been visited then find next closest

    if timereq > maxTime or orderCount[society]>maxOrderCount:           
        # if total time required is more than MaxTime, then we don't consider going to this society
        considered[society] = False
        visited[society] = True
        truckNumber[society] = -1  # not considering
        truckOrder[society ] = -1  # not considering
        CountOfVisited += 1
        continue

    ordersf = orderCount[society]
    timesf = timereq               # we went to closest society and time_so_far = delivery time + travel time
    queue = 1                      # this society is where the truck shall go first (truck Order)
    while timesf < maxTime and ordersf < maxOrderCount: 
        # if we have more time left then continue finding the closest society and deliver goods.
        visited[society] = True    # mark as current society visited
        CountOfVisited  += 1

        truckNumber[society] = truck    
        truckOrder[society]  = queue
        queue += 1

        society, timreq = time[society].popitem(last=False)
        while visited[society]:
            society, timereq = time[society].popitem(last=False) #find next closest and repeat.
        timesf += timereq
        ordersf += orderCount[society]

    # if we are here, then truck went back from societies due to time limit, and we need to send other trucks there to
    # deliver goods and hence increment the truck number by one and repeat this whole process
    truck += 1              

下面是所需的输出。这个社会被分配了这辆卡车。

Society_ID  Order_Count warehouse_time  DeliveryTime  Truck
    1   305            1722             4122        1
    2   168            1409             4557        2
    3   231            1331             7026        3
    7   216            1466             4684        4
    8   212            1202             3929        5
    9   65             1050             2341        2
    10  59             1355             2580        2
    11  199            1417             4957        6
    12  54             1380             1352        3
    14  117            1498             3388        4
4

0 回答 0