箱の中に右下から長方形を配置していきたい

左下から長方形を配置するプログラム(Bottom-Left法)を右下から配置するプログラム(Bottom-Right法)に置き換えたいです。

全ソースコード

import matplotlib.pyplot as plt import matplotlib.patches as patches import pandas as pd import csv import tkinter import time import numpy as np def intersection_NFP(p, q): if q[0][0] < p[0][1] < q[0][1] and p[1][0] < q[1][1] < p[1][1]: return (p[0][1], q[1][1]) if p[0][0] < q[0][1] < p[0][1] and q[1][0] < p[1][1] < q[1][1]: return (q[0][1], p[1][1]) return False #p=[(x1,x2),(y1,y2)] NFPとx軸の交点を求め、 BL点候補点とする。 def intersection_x(p): if p[0][0] < 0: return (0, p[1][1]) return False #p=[(x1,x2),(y1,y2)] NFPとy軸の交点を求め、 BL点候補点とする。 def intersection_y(p): if p[1][0] < 0: return (p[0][1], 0) return False #p=(a,b) q=[(x1,x2),(y1,y2)] 点pが領域q内に含まれているか、いないか。(境界線は含まない) def include_p(p, q): return q[0][0] < p[0] < q[0][1] and q[1][0] < p[1] < q[1][1] #p=(a,b) q=[(x1,x2),(y1,y2)] 点pが領域q内に含まれているか、いないか。(境界線は含む) def include_p_e(p, q): return q[0][0] <= p[0] <= q[0][1] and q[1][0] <= p[1] <= q[1][1] #p=(a,b) q=[{(x1,x2),(y1,y2)},{(x3,x4),(y3,y4)},...] #点pが領域配列qのいずれか1つに含まれているか、いないか。(境界線は含まない) def include_p_n(p, q, n): for i in range(n): if include_p(p, q[i]) == True: ans = True break ans = False return ans class Rect: def __init__(self, x, y, w, h, weight,name): self.x = x self.y = y self.w = w self.h = h self.weight=weight self.name=name #未配置の長方形jの高さhb横幅wb配列 既に配置されている長方形iの高さha横幅ba配列 def NFP(self, b): return [(self.x-b.w, self.x+self.w), (self.y-b.h, self.y+self.h)] #箱の中に収まる範囲 UBはHの上界値 def include_room(self, W, H): return [(0, W-self.w), (0, H-self.h)] #長方形nにおいて既存に配置されている長方形とのNFPを計算 def NFP_r2(self, rects_after): cand = [] if not rects_after: return cand else: for rect in rects_after: p = Rect.NFP(rect, self) cand.append(p) return cand #p=(a,b) [(x1,y1),(x2,y2),...(xn, yn)] 求めたBL候補点pが既に使われていないか。 def point_search(rects_after, p): for rect in rects_after: if p[0] == rect.x and p[1] == rect.y: return True return False def BL_method(self, rects_after, W, UB): if not rects_after: return (0, 0) BL_point = [] a = self.NFP_r2(rects_after) m = len(rects_after) for i in range(m): if not intersection_y(a[i]) == False \ and include_p_e(intersection_y(a[i]), self.include_room(W, UB)) == True \ and Rect.point_search(rects_after, intersection_y(a[i])) == False: BL_point.append(intersection_y(a[i])) if not intersection_x(a[i]) == False \ and include_p_e(intersection_x(a[i]), self.include_room(W, UB)) == True \ and Rect.point_search(rects_after, intersection_x(a[i])) == False: BL_point.append(intersection_x(a[i])) for j in range(i): if not intersection_NFP(a[j], a[i]) == False \ and include_p_e(intersection_NFP(a[j], a[i]), self.include_room(W, UB)) == True \ and Rect.point_search(rects_after, intersection_NFP(a[j], a[i])) == False: BL_point.append(intersection_NFP(a[j], a[i])) BL_point = sorted(BL_point, key=lambda t:t[0]) BL_point = sorted(BL_point, key=lambda t:t[1]) for BL in BL_point: if include_p_n(BL, a, m) == False: p = (BL[0],BL[1]) break return p def __str__(self): return "({}, {}, {}, {},{},{})".format(self.x, self.y, self.w, self.h, self.weight,self.name) n=10 W=44.5 sort_key="weight" h = pd.read_csv("具体的な数値.csv", usecols=[1]).squeeze('columns').values print('高さ') print(h[:n]) print('--------------------') w = pd.read_csv("具体的な数値.csv", usecols=[2]).squeeze('columns').values print('横幅') print(w[:n]) print('--------------------') weight= pd.read_csv("具体的な数値.csv", usecols=[3]).squeeze('columns').values #item= pd.read_csv("具体的な数値.csv", usecols=[4]).squeeze('columns').values item=(np.random.randint(0,4,10)+1)//2 print(item) name=pd.read_csv("具体的な数値.csv", usecols=[0]).squeeze('columns').values before_list = [] for i in range(len(item)): for j in range(item[i]): before_list.append((w[i], h[i], weight[i],name[i])) n = len(before_list) print('before sort') print(before_list) print('--------------------') UB=n*max(h) rects_before=[] for i in range(n): new_rect = Rect(None, None, before_list[i][0], before_list[i][1],before_list[i][2],before_list[i][3]) rects_before.append(new_rect) rects_before = sorted(rects_before, key=lambda t:t.h, reverse=True) rects_before = sorted(rects_before, key=lambda t:t.w, reverse=True) rects_before = sorted(rects_before, key=lambda t:t.weight, reverse=True) print('配置前') for rect in rects_before: print(rect) start = time.time() rects_after = [] for rect in rects_before: BL_point = Rect.BL_method(rect, rects_after, W, UB) rect1 = Rect(BL_point[0], BL_point[1], rect.w, rect.h ,rect.weight,rect.name) rects_after.append(rect1) print('-----------------') print('配置後') for rect in rects_after: print(rect) H = max(rects_after[i].y+rects_after[i].h for i in range(n)) print(f'H={H}') elapsed_time = time.time() - start print("実行時間 = {:.3f} (秒)".format(elapsed_time)) %matplotlib inline fig = plt.figure(figsize=(6,6)) ax = fig.add_subplot(111,aspect='equal') ax.set_xlim ([0,W]) ax.set_ylim ([0,H]) name = 0 for rect in rects_after: name = name + 1 if rect.y <= 24.9: ax.text(rect.x+rect.w/2, rect.y+rect.h/2, f'{name}', horizontalalignment="center", verticalalignment="center") rect_color = 'burlywood' else: ax.text(rect.x+rect.w/2, rect.y+rect.h/2, f'{name}', horizontalalignment="center", verticalalignment="center", color='white') rect_color = 'lightblue' rect1 = plt.Rectangle((rect.x,rect.y),rect.w,rect.h,fc=rect_color,ec="black") ax.add_patch(rect1) ax.text(0, H+1, f'H={H}', horizontalalignment="center") ax.text(W+1, 0, f'W={W}', verticalalignment="center") ax.axhline(y=25, color='red', linestyle='--') #plt.savefig(f"picture_BFnfp2_{n}.pdf") plt.show()

試してみたこと

intersection_x_rightと intersection_y_upを新しく定義し、point_searchに@staticmethodを加えて、BL_method内に
intersect_x = intersection_x_right(a[i], W)
intersect_y = intersection_y_up(a[i], UB)
と付け加えました。

python

1def intersection_x_right(p, W):2 if p[0][1] > W:3 return (W, p[1][0])4 return False5 6def intersection_y_up(p, UB):7 if p[1][1] > UB:8 return (p[0][0], UB)9 return False10 11@staticmethod12 def point_search(rects_after, p):13 for rect in rects_after:14 if p[0] == rect.x and p[1] == rect.y:15 return True16 return False17 18 def BL_method(self, rects_after, W, UB):19 if not rects_after:20 return (W - self.w, 0)21 BL_point = []22 a = self.NFP_r2(rects_after)23 m = len(rects_after)24 25 26 for i in range(m):27 intersect_x = intersection_x_right(a[i], W)28 intersect_y = intersection_y_up(a[i], UB)29 30#以下コード同じ31

エラー文

UnboundLocalError Traceback (most recent call last) Input In [5], in <cell line: 53>() 51 rects_after = [] 53 for rect in rects_before: ---> 54 BL_point = Rect.BL_method(rect, rects_after, W, UB) 55 rect1 = Rect(BL_point[0], BL_point[1], rect.w, rect.h ,rect.weight,rect.name) 56 rects_after.append(rect1) Input In [4], in Rect.BL_method(self, rects_after, W, UB) 118 p = (BL[0],BL[1]) 119 break --> 120 return p UnboundLocalError: local variable 'p' referenced before assignment

[具体的な数値.csv]
イメージ説明

コメントを投稿

0 コメント