2022 National Graduate Mathematical Modeling Competition Huawei Cup Problem B Square Parts Assembly Batch Optimization Problem Solving Documentation and Procedures for the Whole Process

2022 National Graduate Mathematical Modeling Competition Huawei Cup

Problem B: square parts assembly batch optimization problem

Original title reproduced:

  Background Introduction
  Intelligent manufacturing is listed as the main direction of "Made in China 2025", and personalized customization, shorter product and system life cycles, interconnected service models, etc. have become the main competition points for enterprises in the transformation of intelligent manufacturing. Take products in the discrete industry as an example, such as electronic devices, automobiles, aerospace parts, etc. These products all rely on mechanical design, can be decentralized processing, can be flexibly assembled, and have many styles of similar products. For such products, customers may have inexhaustible product demands, unpredictable order sizes, and extremely high product quality requirements. At this time, the service demand for "personalized customization" requires enterprises to have efficient and fast demand analysis and product design capabilities, a flexible and lean production process, and complete and sophisticated full-process production control capabilities.
  Square parts products (also called plate products) are a type of product formed by using plates as the main original piece and assembling several plate accessories after plane processing. Common square parts product manufacturing companies, such as 3C (computing, communications, consumer electronics), panel furniture, glass, sheet metal parts and other industries, mostly adopt "multi-variety and small batch" personalized customized production. Due to the large number of corporate orders, production Organizations usually adopt the "order batching + mass production + order sorting" model, which uses order batching to achieve batch cutting and improve the utilization rate of raw materials. After processing is completed, it is sorted according to different customer orders.
  The optimization of order batching and layout in the above-mentioned personalized customized production model is crucial. Order batching is to combine different orders into several batches to achieve batch production of orders. When batch production of small batches, multiple varieties, and large-scale orders, if the batch is too small, the material utilization rate will be low, and the production efficiency will be low; if the batch is too large, the material utilization rate will increase, but Order delivery time cannot be guaranteed, order sorting becomes more difficult, production efficiency decreases, and buffer capacity is insufficient causing congestion. The contradiction between personalization and production efficiency needs to be resolved.
  Layout optimization is essentially a blanking problem (also known as cutting and filling problem). The purpose of optimization is to reasonably plan the layout of square parts on the plate to reduce the waste of plate during the blanking process and simplify the cutting process. This problem is a combinatorial optimization problem with high computational complexity and is also an important branch of operations research. As the first step in the production of products and parts in the production chain of many manufacturing companies, blanking consumes materials and resources that cannot be underestimated. How to improve material utilization and reduce raw material consumption is an important step for companies to reduce resource and energy waste and assume environmental responsibilities. key issues to be solved.
  Problem Description
  Order batching problem: Optimize the batching of production orders taking into account factors such as order delivery time, equipment capacity load, storage capacity, material utilization, production efficiency, production process constraints, etc. Orders with the same material, similar delivery date, and similar process are arranged in the same production batch. Order batch optimization is used to ensure the delivery date, improve the utilization rate of raw materials, and improve equipment production efficiency, etc. In order to facilitate unified processing of data and reflect the essence of the problem, the delivery dates of all orders in this competition are the same and no distinction is made. A batch is defined as a collection of orders that completes all tasks of several orders and does not contain any incomplete order tasks.
  Blanking optimization problem (also called layout optimization problem): According to the size and quantity of square parts in the same production batch, select the specifications and quantity of the original pieces, optimize the blanking and layout, and maximize the utilization rate of the original sheets. According to the process requirements of the cutting process, the layout plan must meet the "one size fits all" (also known as Guillotine cut) constraint (any straight line cutting must ensure that the board is separable, in other words, each straight line cut separates the board into two pieces) . The blanking optimization problem belongs to the plate profile square part layout optimization problem with "one size fits all" constraints.
  Considering the different ways of cutting process, it can be divided into guillotine cut and non-guillotine cut (as shown in Figure 1). Guillotine cut can be subdivided into precise method and non-precise method (involving the number of cutting stages, as shown in Figure 2). ). The three-stage layout method in Figure 2 mainly has three different types: three-stage non-exact layout method (3NE), three-stage homogeneous layout method (3E), three-stage homogeneous layout method (3H) . Among them, the 3E and 3H layout methods can cut square parts with accurate dimensions in three stages, so they are both accurate layout methods. In the 3NE layout method, some square parts require an additional fourth stage of cutting to meet the size requirements.
Insert image description here
  Due to the different number of stages involved, different documents have different names for each stage of cutting. In order to facilitate understanding and unify the expression form, English is used to describe the description of the key stage modules. For details, see Figure 3 (in the actual cutting process, the A knife may be perpendicular to the long side or perpendicular to the short side. Figure 3 takes perpendicular to one of the sides as an example).
Insert image description here
  Because the common stages are 3-4 at most, taking the 3-stage cutting method as an example (Figure 3), the transverse cutting generation module in the first stage is called stripe, such as Stripe1 and Strip2; the second stage The vertical cutting generation module in the stage is called stack (stack), for example, Strip1 continues to be cut into Stack1, Stack2, and Stack3; the third stage horizontal cutting generation module is called item (product item), such as Stack1 continues to be cut into Item1, Item2 and Item3.
  This competition question
  consists of two sub-problems. The constraints of the second sub-problem are based on and compatible with the first sub-problem, but the data provided by the two sub-problems are not relevant. If the concept definition and process description are different from those in the industry, this competition question shall prevail. This question assumes:
  1. Only the cutting method of flush cutting is considered (straight-line cutting, the cutting direction is perpendicular to one edge of the board, and it is ensured that the board can be separated into two pieces during each straight-line cutting); 2. The number of cutting stages does not exceed 3, and the
  same The cutting directions at each stage are the same;
  3. The layout method is precise layout;
  4. It is assumed that the original sheet has only one specification and sufficient quantity;
  5. The layout plan does not need to consider the influence of saw kerf width (that is, the width of the cutting gap).
  Sub-problem 1: Layout optimization problem. It is required to establish a mixed integer programming model to reduce the amount of plate material as much as possible while meeting the production order requirements and related constraints.
  Constraints:
  1. The width (or length) of product items in the same stack should be the same;
  2. The product items generated by the final cutting are complete and not spliced.
  This sub-problem requires programming, taking data set A as input, and the output requirements are shown in Part 5.
  Sub-problem 2: Order batching problem. It is required to establish a mixed integer programming model to group all the orders in data set B into batches, and then arrange each batch independently, so that the amount of original sheets used is as small as possible while meeting the order requirements and related constraints.
  On the basis of satisfying the constraints of sub-problem 1, further requirements are required:
  1) Each order must and only appear in a batch;
  2) Product items (items) of the same material in each batch can use the same plate raw material. slices for layout;
  3) In order to ensure rapid flow of processing links, the total number of product items (items) in each batch cannot exceed the limit;
  4) Due to factory capacity limitations, the total area of ​​each batch of product items (items) cannot exceed Limit value;
this sub-question requires programming, takes data set B as input, and the output result requirements are shown in Part 5.

Overview of the overall solution process (abstract)

  This paper studies the arrangement optimization and batching problems of square parts by using the iterative method and K-Means cluster analysis method to solve the mixed integer programming model.
  In Problem 1, the cutting problem of panels is treated as a stacking problem of project parts. First, using the minimum amount of original film consumables as the objective function, a mixed integer programming model I with given constraints is established. It is stipulated that each item must be stacked once, and the height of the stack must be reasonable. Therefore, dummy variables α, β, and γ are set to determine whether item, stack, stripe, and bin are included in sequence. The stacking height of the item is limited to beite. Should exceed the height of the stack, the width of the stack must not exceed the width of the original piece, and the height of the strip must not exceed the height of the original piece. In practical applications, the height h of the item is used as the basis for layout and put into model I to obtain the dummy variable parameter values ​​α, β, γ, . Since the numerical index of stack is unknown, the adjustment parameters H, mean, and median are set to optimize the model. Finally, it is found that the model using height for sorting, mean, and median as adjustment parameters has the best fitting effect. In data set A The average plate utilization rate reached 94.06%.
  In question two, it is necessary to consider solving the batching problem of constrained order parts when the amount of data is large on the basis that the order number cannot be batched and the plate material is different. First, put the same order numbers together, set the material-related index construction matrix as the basis for K-Means clustering, and constrain the total number of product items in a single batch to 1,000 pieces and the total upper limit of the area of ​​a single batch of products to 250 square meters. Divide cluster families through Euclidean distance and class average distance, find the minimum number of categories K that meets the classification requirements, and continuously adjust the hyperparameters max_order, min_order, and K until the optimal feasible solution is found and the product items are batched. After the product items are completed in batches, the product items of different materials in each batch are grouped, and the layout optimization method in Model I is used separately for each group, and the final output result is 83.32%.
  The iterative method solution code in question 1 of this article does not call a third-party library, and is all written and encapsulated by itself. It has the characteristics of fast operation speed and strong modifiability. In this article, the results of order batching and layout optimization modeling of square parts are relatively robust, and can provide certain guidance for luggage problems and blanking problems. It is also practical for PCB circuit boards, Banshi furniture, 3C home appliances and other fields. The application has certain reference value.

Model assumptions:

  1. The original pieces have uniform specifications and materials are evenly distributed, with no impurity areas;
  2. The cutting process adopts a head-to-head cutting method;
  3. The finished parts are independent of each other, and there is no overlap between product items [3];
  4. The cut products are complete, It cannot be made by splicing;
  5. The first cut is parallel to the horizontal direction of the short side of the original piece;
  6. Each cut is always perpendicular to the cutting direction of the previous cut [4];
  7. Only three stages of cutting are considered at most;
  8. Layout The method only considers accurate layout;

problem analysis:

  Analysis of Problem 1 Problem
  1 requires the establishment of a mixed integer programming model to optimize the layout of the plates and obtain the smallest possible consumption of the original plates. In order to achieve this goal, we regard the minimum amount of original film consumables as the objective function, and on the basis of fully considering the constraints, find bin (original film), stripe (strip), stack (stack), item (product item) ), by interpreting the specific connections between each cutting stage and setting matching parameters, a system of equations related to the goal of this question can be constructed. Using the backward thinking method, the cutting problem of the original film is regarded as the combination problem of order parts. The required order parts are stacked, the items are combined into stacks, the stacks are combined into stripes, and then the stripes are stacked and combined to make up for the remaining parts. After collecting the information, the original film set by the title is finally formed. After determining the model, first consider using the iterative method to find the local optimal solution by continuously inputting order requirements.
  Analysis of Question 2
  Based on Question 1, Question 2 adds new constraints. The first is the restriction on batch items, which requires that the number of product items in each batch shall not be greater than 1,000 and the total area of ​​a single batch of product items shall not be greater than 1,000. It must not be larger than 250 square meters. Second, the order number and material are given as the basis for batch division. It is required that the same order cannot be split into different batches, and the materials of each order may be different. This requires us to first classify the orders according to the constraints, and then optimize the layout of each classified batch individually. If layout optimization is regarded as a main problem, the batching problem can be regarded as a sub-problem of three-stage layout. Faced with the order batching problem [1], we consider first classifying the product parts into one category according to the order number, and then perform K-Means clustering with constraints. In the process of K-Means clustering, in order to make the plates The utilization rate of original films is high, and the same materials should be included in the same batch as much as possible. After completing the clustering, each category is classified into a batch, and the mixed integer programming model in question 1 is used to iterate on the product items of different materials in each batch, and finally the approximate solution of each batch is obtained [2 ].

Model establishment and solution overall paper thumbnail

Insert image description here

Insert image description here

For all the papers, please see "Only modeling QQ business cards" below. Just click on the QQ business card.

code:

Some Python programs are as follows:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import os
import time
import pandas as pd
from demo import Cycle_solution_A
# 衡量指标
def metrics(data, number, max_length, max_width):
 """
 :parameter
 data:[[序号:index, 订单 id:item_id, 订单材料:item_material, 订单所需要数
量:item_num, 材料长度:item_length, 材料宽度:item_width, 订单号:item_order]*size]
 number:消耗的总板材
 max_length:板材长
 max_width:板材宽
 """
 total_item = 0.
 for vector in data:
 total_item += vector[4] * vector[5]
 run_rate = total_item / (number*max_length*max_width)
 return run_rate
# 问题一
# 加载数据
file_A = []
for i in range(1, 5):
 file_path = os.path.join(r"E:\python document\challenge\2022 年 B 题\子问题 1-数
据集 A", "dataA"+str(i)+".csv")
 if os.path.exists(file_path):
 file_A.append(pd.read_csv(file_path))
data_A_lis = []
avg_length = []
for i in file_A:
 avg_length.append(i['item_length'].mean())
 j = i.sort_values(by='item_length', ascending=False)
 j = j.values.tolist()
 data_A_lis.append(j)
# [序号:index, 订单 id:item_id, 订单材料:item_material, 订单所需要数量:item_num, 
材料长度:item_length, 材料宽度:item_width, 订单号:item_order]
print(data_A_lis)
# 参数
max_length = 2440
max_width = 1220
path = r"E:\python document\challenge\2022 年 B 题\solution_A"
f_txt = open(r"E:\python document\challenge\2022 年 B 题\solution_A\min_n.txt", "w")
# 求解
min_n_data_A = []
rate_A_lis = []
run_time_lis = []
_time = time.time()
for A_index, data_set in enumerate(data_A_lis):
 data_size = len(data_set)
 paths = os.path.join(path, "A{0}".format(A_index+1))
 solution = Cycle_solution_A(data_size, paths, avg_length[A_index], max_length, 
max_width)
 min_n, cut_program = solution.cycle_com(data_set)
 cut_program.to_csv(r"E:\python document\challenge\2022 年 B 题
\solution_A\A{
    
    0}\data_A{
    
    0}_cut_program.csv".format(A_index+1), index=None, 
encoding='utf_8_sig')
 rate = metrics(data_set, min_n, max_length, max_width)
 run_time_lis.append(time.time() - _time)
 min_n_data_A.append(min_n)
 rate_A_lis.append(rate)
 print("data_A{0}:finish".format(A_index+1))
f_txt.write("min_n_data_A:" + "\n")
f_txt.write(str(min_n_data_A) + "\n" + "\n")
f_txt.write("rate_A_lis:" + "\n")
f_txt.write(str(rate_A_lis) + "\n" + "\n")
f_txt.write("run_time:" + "\n")
f_txt.write(str(run_time_lis) + "\n" + "\n")
print(min_n_data_A)
print(rate_A_lis)
class Cycle_solution_A():
def __init__(self, data_size, path, average_length, max_length=2440, 
max_width=1220):
 self.max_length = max_length
 self.path = path
 self.average_length = average_length
 self.max_width = max_width
 self.data_size = data_size
 # alpha、beta、gamma 的定义
 self.alpha = []
 self.beta = []
 self.gamma = []
 for j in range(data_size):
 self.alpha.append([0 if j > i else 1 for i in range(data_size)])
 for j in range(data_size):
 self.beta.append([0 if j > i else 1 for i in range(data_size)])
 for j in range(data_size):
 self.gamma.append([0 if j > i else 1 for i in range(data_size)])
 def cycle_com(self, data):
 """
 :parameter
 data:[[序号:index, 订单 id:item_id, 订单材料:item_material, 订单所需要
数 量 :item_num, 材 料 长 度 :item_length, 材料宽度 :item_width, 订 单
号:item_order]*size]
 """
 stack_lis, info_stack_lis, alpha = self.item_into_stack(data, self.alpha)
 stripe_lis, stripe_index_lis, info_stripe_lis, beta = 
self.stack_into_stripe(stack_lis, info_stack_lis, self.beta)
 bin_lis, bin_lis_index, info_bin_lis, gamma = self.stripe_into_bin(stripe_lis, 
info_stripe_lis, self.gamma)
 file = self.picture(data, stack_lis, info_stack_lis, stripe_lis, info_stripe_lis, 
bin_lis)
 min_number = 0
 for index, i in enumerate(gamma):
 min_number += i[index]
 return min_number, file
 def item_into_stack(self, data, alpha):
 # 构造出 stack stak:[list1, list2,....],list 的第一个元素为 stack 的计算标号
 stack_lis = []
 for item_index, item in enumerate(data):
 if len(stack_lis) == 0:
stack_lis.append([item_index+1])
 else:
 for index, i in enumerate(stack_lis):
 if data[i[0] - 1][5] == item[5]:
 stack_length = 0
for j in i:
 stack_length += data[j-1][4]
 if stack_length + item[4] <= self.average_length:
 stack_lis[index].append(item_index+1)
 else:
 # 转换 h 和 w
 # if data[i[0] - 1][5] == item[4]:
 # data[item_index][4], data[item_index][5] = 
data[item_index][5], data[item_index][4]
 # if stack_length + item[4] <= 
self.average_length:
 # stack_lis[index].append(item_index + 1)
 # else:
 # stack_lis.append([item_index+1])
stack_lis.append([item_index+1])
break
 else:
 continue
 sum = 0
 for i in stack_lis:
 for j in i:
 if item_index + 1 == j:
 sum += 1
 if sum == 0:
 stack_lis.append([item_index + 1])
 # 处理 alpha
 for vector in stack_lis:
 # 计算序号变为 python 序号
 set_vector = []
 for number in vector:
 set_vector.append(number - 1)
 cycle_set = list(set(range(self.data_size)) - set(set_vector))
 for j in cycle_set:
 alpha[vector[0] - 1][j] = 0
 if len(vector) > 1:
 for j in vector[1:]:
 for k in range(self.data_size):
 alpha[j - 1][k] = 0
 # 输出 stack 的高度和宽度信息(先高后宽)
info_stack = [[],[]]
 for i in stack_lis:
 stack_length = 0
 for j in i:
 stack_length += data[j - 1][4]
 info_stack[0].append(stack_length)
 info_stack[1].append(data[i[0] - 1][5])
 return stack_lis, info_stack, alpha
 def stack_into_stripe(self, stack, info_stack, beta):
 # 先对 stack 做一次排序
 stack_length = info_stack[0]
 stack_width = info_stack[1]
 sort_stack = []
 for index, i in enumerate(stack_width):
 sort_stack.append([stack_length[index], i, stack[index]])
 # 排序
 n = len(sort_stack)
 for i in range(n):
 min = i
 for j in range(i+1, n):
 if sort_stack[j][0] < sort_stack[min][0]:
 min = j
 sort_stack[min], sort_stack[i] = sort_stack[i], sort_stack[min]
 sort_stack = sort_stack[::-1]
 # 分出数据
 finish_sort_stack = []
 sort_info_stack = []
 for i in sort_stack:
 sort_info_stack.append([i[0], i[1]])
 finish_sort_stack.append(i[2])
 # 构造出 stripe, stripe:[[number,element1, element2, ....], .....],number 为其
序号,element 为包含的 stack 序号
 stripe_lis = []
 for item_index, item in enumerate(finish_sort_stack):
 if len(stripe_lis) == 0:
 stripe_lis.append([item_index])
 else:
 for i_index, i in enumerate(stripe_lis):
 stripe_width = 0
for j in i:
 stripe_width += sort_info_stack[j][1]
 if stripe_width + sort_info_stack[item_index][1] <= 
self.max_width:
 stripe_lis[i_index].append(item_index)
break
 else:
 continue
 sum = 0
 for i in stripe_lis:
 for j in i:
 if item_index == j:
 sum += 1
 if sum == 0:
 stripe_lis.append([item_index])
 # 输出 stripe 的宽度信息
 info_stripe = []
 max_length_index = []
 for v_index, vector in enumerate(stripe_lis):
 stripe_width = 0
 stripe_length = []
 for j_index, j in enumerate(vector):
 stripe_length.append(sort_info_stack[j][0])
 stripe_width += sort_info_stack[j][1]
 info_stripe.append([max(stripe_length), stripe_width])
 max_length_index.append(stripe_length.index(max(stripe_length)))
 # 将 stripe 做序号转变
 true_stripe_lis = []
 for v_index, vector in enumerate(stripe_lis):
 max_index = max_length_index[v_index]
 true_stripe_lis.append([finish_sort_stack[vector[max_index]][0]])
 for j_index, j in enumerate(vector):
 true_stripe_lis[v_index].append(finish_sort_stack[j][0])
 # 处理 beta
 first_vector = []
 for vector in true_stripe_lis:
 # 计算序号变为 python 序号
 first_vector.append(vector[0]-1)
 set_vector = []
 for number in vector[1:]:
 set_vector.append(number - 1)
 cycle_set = list(set(range(self.data_size)) - set(set_vector))
 for j in cycle_set:
 beta[vector[0] - 1][j] = 0
 zero_lis = list(set(range(self.data_size)) - set(first_vector))
 for i in zero_lis:
 for j in range(self.data_size):
 beta[i][j] = 0
 return true_stripe_lis, stripe_lis, info_stripe, beta
 def stripe_into_bin(self, stripe, info_stripe, gamma):
# 先对 stack 做一次排序
 sort_stripe = []
 for index, i in enumerate(stripe):
 sort_stripe.append([info_stripe[index][0], info_stripe[index][1], i])
 # 排序
 n = len(sort_stripe)
 for i in range(n):
 min = i
 for j in range(i + 1, n):
 if sort_stripe[j][0] < sort_stripe[min][0]:
 min = j
 sort_stripe[min], sort_stripe[i] = sort_stripe[i], sort_stripe[min]
 sort_stripe = sort_stripe[::-1]
 # 分出数据
 finish_sort_stripe = []
 sort_info_stripe = []
 for i in sort_stripe:
 sort_info_stripe.append([i[0], i[1]])
 finish_sort_stripe.append(i[2])
 # 构造出 bin, bin:[[number,element1, element2, ....], .....],number 为其序,element 为包含的 bin 序号
 bin_lis = []
 for item_index, item in enumerate(finish_sort_stripe):
 if len(bin_lis) == 0:
 bin_lis.append([item_index])
 else:
 for i_index, i in enumerate(bin_lis):
 bin_length = 0
for j in i:
 bin_length += sort_info_stripe[j][0]
 if bin_length + sort_info_stripe[item_index][0] <= 
self.max_length:
 bin_lis[i_index].append(item_index)
break
 else:
 continue
 sum = 0
 for i in bin_lis:
 for j in i:
 if item_index == j:
 sum += 1
 if sum == 0:
 bin_lis.append([item_index])
 # 输出 bin 的高宽信息
 info_bin = []
max_length_index = []
 for v_index, vector in enumerate(bin_lis):
 bin_width = []
 bin_length = 0
 for j_index, j in enumerate(vector):
 bin_width.append(sort_info_stripe[j][1])
 bin_length += sort_info_stripe[j][0]
 info_bin.append([bin_length, max(bin_width)])
 max_length_index.append(bin_width.index(max(bin_width)))
 # 将 bin 做序号转变
 true_bin_lis = []
 for v_index, vector in enumerate(bin_lis):
 
true_bin_lis.append([finish_sort_stripe[vector[max_length_index[v_index]]][0]])
 for j_index, j in enumerate(vector):
 true_bin_lis[v_index].append(finish_sort_stripe[j][0])
 # 处理 gamma
 first_vector = []
 for vector in true_bin_lis:
 # 计算序号变为 python 序号
 first_vector.append(vector[0] - 1)
 set_vector = []
 for number in vector[1:]:
 set_vector.append(number - 1)
 cycle_set = list(set(range(self.data_size)) - set(set_vector))
 for j in cycle_set:
 gamma[vector[0] - 1][j] = 0
 zero_lis = list(set(range(self.data_size)) - set(first_vector))
 for i in zero_lis:
 for j in range(self.data_size):
 gamma[i][j] = 0
 return true_bin_lis, bin_lis, info_bin, gamma
 def picture(self, data, stack_lis, info_stack_lis, stripe_lis, info_stripe_lis, bin_lis):
 # 找出每个 bin 所含的订单 id
 # 制作 bin、stripe、stack 的高宽信息字典
 info_stack_dict = {
    
    }
 for stack_index, stack_i in enumerate(stack_lis):
 info_stack_dict[stack_i[0]] = [info_stack_lis[0][stack_index], 
info_stack_lis[1][stack_index]]
 info_stripe_dict = {
    
    }
 for stripe_index, stripe_i in enumerate(stripe_lis):
 info_stripe_dict[stripe_i[0]] = info_stripe_lis[stripe_index]
 stripe_dict = {
    
    }
 for v_index, vector in enumerate(stripe_lis):
tem in enumerate(stack):
 all_bin_lis[b_index][sp_index + 1][sc_index + 1][it_index] 
= [item, stack_dict.get(item)]
 # 制作 cut_program.csv 表
 # 小心计算序号是 1 到 n,引用序号要变成 0 到 n-1
 # [材质, bin_index, item_index, 起点 x 坐标, 起点 y 坐标, x 方向长度(width), 
y 方向长度(length)]
 cut_program_lis = []
 for bin_index, bin in enumerate(all_bin_lis):
 # 整个图
 fig, ax = plt.subplots()
 ax.spines['right'].set_visible(False)
 ax.spines['top'].set_visible(False)
 ax.spines['left'].set_visible(False)
 ax.spines['bottom'].set_visible(False)
 ax.plot([0, 1220], [0, 0], color="k", linewidth=2.5)
 ax.plot([1220, 1220], [0, 2440], color="k", linewidth=2.5)
 ax.plot([0, 0], [0, 2440], color="k", linewidth=2.5)
 ax.plot([0, 1220], [2440, 2440], color="k", linewidth=2.5)
 # stripe 的直线位置
 total_stripe_length = 0.
 for stripe_index, stripe in enumerate(bin[1:]):
 stripe_length, stripe_width = info_stripe_dict.get(stripe[0])[0], 
info_stripe_dict.get(stripe[0])[1]
 total_stripe_length += stripe_length
 ax.plot([0, 1220], [total_stripe_length, total_stripe_length], color="k", 
linewidth=2)
 # stack 的竖线位置
 total_stack_width = 0.
 for stack_index, stack in enumerate(*stripe[1:]):
stack_length, stack_width = info_stack_dict.get(stack[0])[0], 
info_stack_dict.get(stack[0])[1]
 total_stack_width += stack_width
ax.plot([total_stack_width, total_stack_width], 
[total_stripe_length - stripe_length, total_stripe_length], color="g", linewidth=1.5)
 # item 的位置
 total_item_length = 0.
 for item_index, item in enumerate(*stack[1:]):
 item_length, item_width = data[item - 1][4], data[item - 1][5]
 total_item_length += item_length
 cut_program_lis.append([data[item - 1][2], bin[0], data[item - 1][1], 
total_stack_width - stack_width, total_item_length - item_length + total_stripe_length -
stripe_length, stack_width, item_length])
 ax.plot([total_stack_width - stack_width, total_stack_width], 
[total_item_length + total_stripe_length - stripe_length, total_item_length+ 
total_stripe_length - stripe_length], color="y", linewidth=1)
 adjust_text([ax.text(x=(total_stack_width - stack_width + 
total_stack_width) / 2, y= (total_item_length - 3*item_length/10) + total_stripe_length -
stripe_length , rotation=60, s="id:{0}".format(data[item - 1][1]), ha="left")])
 ax.fill_between([total_stack_width - stack_width, total_stack_width], 
total_item_length + total_stripe_length - stripe_length, stripe_length + total_stripe_length 
- stripe_length, facecolor='dimgray', alpha=1)
 ax.fill_between([total_stack_width, 1220], total_stripe_length - stripe_length, 
total_stripe_length, facecolor='dimgray', alpha=1)
 ax.fill_between([0, 1220], total_stripe_length, 2440, facecolor='dimgray', alpha=1)
 paths = os.path.join(self.path, "cutting_pic{0}.jpg".format(bin[0]))
 plt.savefig(paths)
 plt.close()
cut_program = pd.DataFrame(cut_program_lis)
cut_program.columns = ['原片材质', '原片序号', '产品 id', '产品 x 坐标', '产品 y 坐标', '
产品 x 方向长度', '产品 y 方向长度']
return cut_program
For all the papers, please see "Only modeling QQ business cards" below. Just click on the QQ business card.

Guess you like

Origin blog.csdn.net/weixin_43292788/article/details/132834908