Supplement - heap box + python(DFS)

Posted by kiltannen on Mon, 03 Jan 2022 14:35:19 +0100

Title Description:

Given the length, width and height information of n boxes (the order is uncertain, that is, the boxes can be turned over), stack them vertically to find the maximum height that can be stacked.

Requirement: the bottom surface of the upper box shall not exceed the bottom surface of the lower box.

Others: aim at the maximum height that can be obtained without using all boxes.

I. problem solving ideas

#0) still convert data into matrix; The topic design seeks all feasible schemes and considers using DFS programming to solve them.

#1. The three attribute information of the box are arranged and combined into three groups. In each group, the first two attribute elements are used as the bottom edge length and the third attribute element is used as the height.

##Example: arrange and combine the three attribute information "85 35 23" of the box, and the three groups of data are: [85 35 23], [85 23 35], [35 23 85]; So that all three attribute values have the opportunity to be high.

##1.1 store box information with matrix: each line represents a box information, and each box information contains 3 combined data.

#2 when stacking cuboids, each cuboid may be placed at the bottom; Therefore, for n boxes to be stacked, N cycles are required here

##2.1 When a box is stacked at the bottom, each side of it may be as high, that is, there are three placement methods; Therefore, three cycles are required

#3 judgment conditions: used for (pruning) early termination of infeasible scheme

#3.1 the length and width of the bottom surface of the newly stacked cuboids (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower cuboids respectively

#4 termination conditions

#Terminate when all boxes have been accessed

#6 in particular: in order to obtain the maximum height, it is not necessary to stack all boxes, that is, boxes that do not meet the conditions of 3.1 can be discarded.

#6.1 DFS full search can automatically include this situation.

II. Code implementation

# Supplementary escape:

# 1. The three attribute information of the box are arranged and combined into three groups. In each group, the first two attribute elements are used as the bottom edge length and the third attribute element is used as the height.
## Example: arrange and combine the three attribute information "85 35 23" of the box, and the three groups of data are: [85 35 23], [85 23 35], [35 23 85]; So that all three attribute values have the opportunity to be high.
## 1.1 store box information with matrix: each line represents a box information, and each box information contains 3 combined data.
# 2 when stacking cuboids, each cuboid may be placed at the bottom; Therefore, for n boxes to be stacked, N cycles are required here
##2.1 When a box is stacked at the bottom, each side of it may be as high, that is, there are three placement methods; Therefore, three cycles are required
# 3 judgment conditions: used for (pruning) early termination of infeasible scheme
# 3.1 the length and width of the bottom surface of the newly stacked cuboids (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower cuboids respectively
# 4 termination conditions
# Terminate when all boxes have been accessed
# 5 finally return to the maximum height that can be obtained
# 6 in particular: in order to obtain the maximum height, it is not necessary to stack all boxes, that is, boxes that do not meet the conditions of 3.1 can be discarded.
# 6.1 DFS full search can automatically include this situation.

import collections
import math
#### data processing
def proData(size,subdata):
new_data = []
### Arrange and combine each original data into 3 pieces of data
for i in range(size):
temp0 = subdata[i]
temp1 = subdata[i]
temp2 = subdata[i]
temp = [[temp0,temp1,temp2],[temp0,temp2,temp1],[temp1,temp2,temp0]] # 3 combined data
new_data.append(temp) # Each row represents a box of data
return new_data

### DFS processing
class Solution:
def DFS(self):
self.Max_height = [] # The maximum height that can be obtained by storing each scheme
####
######### Each box is placed as the bottom layer, with a total of size
for i in range(size):
#### Get details
node = new_data[i]
for j in range(3):
start = node[j]
## Set initial information
sum = 0 # Cumulative height
self.ways = 0 # Initialize the box height that can be obtained by this scheme
queue = [] # Store visited boxes; Line number i (each line number represents a box)
queue.append(i) # Add the accessed box, i.e. line number I
step = 1 # Count, that is, record the number of boxes visited
pre_start = [math.inf,math.inf,math.inf] # To compare the length and width of the bottom edge of two adjacent boxes, you need to set a variable to save the information of the box below
self.dfs(pre_start,start,sum,step,queue)
#### Current bin height
self.Max_height.append(self.ways)
#### initialization
return max(self.Max_height) ## Returns the maximum height in all scenarios

def dfs(self,pre_start,start,sum,step,queue):
### 1. Judge whether the stacking conditions are met
pre_infor = pre_start[0:2] # The first two elements are the length and width of the bottom edge, and the third element is the height
cur_infro = start[0:2]
if max(cur_infro)>max(pre_infor) or min(cur_infro) > min(pre_infor): #The length and width of the bottom surface of the newly stacked box (i.e. the maximum and minimum values of the first two elements in the combined data, which correspond to the length and width of the bottom surface respectively) must be less than the length and width of the bottom surface of the lower box respectively
return # Otherwise, it indicates that it cannot be stacked and returns directly
### 2 update box Height
if sum + start >self.ways:
self.ways = sum + start
### 3. Judge whether to terminate
if step >= size:
return
#### 4 enter DFS recursion
###4.1 first, check the boxes that have been visited
new_queue = []
new_queue.append('*') # To ensure the order of the queue, add an element in advance and delete it later
for qi in queue:
new_queue.append(qi)
new_queue.pop(0)
###4.2 entering the cycle
for i in range(size):
if i not in new_queue:#If it has not been accessed, it can be accessed
new_queue.append(i)# Join the accessed queue
for j in range(3):# Process the three cases of the current box in turn
new_start = new_data[i][j]
self.dfs(start,new_start,sum+start,step+1,new_queue)
#### Before the next for loop, pop up the previously accessed box so that all boxes can be used as the second bottom box
new_queue.pop() # This step is particularly important
return
## Welcome data
# Total number of test cases
N = int(input().strip())
data = []
data_size = []
for case in range(N):
size = int(input().strip())
data_size.append(size)
###
temp = []
for di in range(size):
temp.append(list(map(int,input().strip().split(' '))))
data.append(temp)
# print(data)
############# handle ##############
for case in range(N):
### Extract information
size = data_size[case]
subdata = data[case]
#### data processing
new_data = proData(size,subdata)
# print(new_data)
#### DFS handle #########
test = Solution()
ans = test.DFS()
#### Print results
print('#'+str(case+1)+' '+str(ans))

Input:

2
2
76 25 3
24 23 4
3
85 20 23
43 18 90
29 12 45

Output:

#1 76
#2 158 Topics: Python