import type { Big_bang, Con, Inv, xbang } from './bang' import { LineType } from './bang' export class RectOptimizeMachine { private _Stop = false public CallBack: (best: Inv, yl: Big_bang[], fit: number, info: any) => void | Promise Stop(d?:any) { console.log('优化 stop=》RectOptimizeMachine',d) this._Stop = true } /** * @param xbangs 小板 * @param bigBang 大板(N个元素,前N-1个元素表示余料板且余料板须为矩形,第N个元素表示大板) * @param bigBangSL 余料板数量(bigBang中前N-1个元素对应的数量,如果bigBang中只有一个元素即只有大板没有余料板,则为空数组) * @param xyhcs 新优化次数 * @param isdtwosided 双面加工的小板是否优先排入 * @param gap 排版缝隙 = 开料刀直径 + 缝隙 * @param hssf 规则排版 * @param YuLiaoBoardDo2FaceBlock 余料板是否排入双面加工的小板 */ async Start(xbangs: xbang[], bigBang: Big_bang[], bigBangSL: number[], xyhcs: number, isdtwosided: boolean, gap: number, hssf: boolean, YuLiaoBoardDo2FaceBlock: boolean) { this._Stop = false // let bestFit = Infinity; //最佳的利用率 35*10 + 最后一张板 let bestFit = Number.POSITIVE_INFINITY // 最佳的利用率 35*10 + 最后一张板 let bestInv: Inv let i = 0 let inv; let re_ylb; let fit: any = null while (!this._Stop) { const qfsh = hssf ? false : i % 2 === 0 // 电子锯算法, 永远不合并空间 let tempArr = SnameYH(xbangs.slice(), bigBang, bigBangSL, xyhcs, qfsh, isdtwosided, gap, YuLiaoBoardDo2FaceBlock) inv = tempArr[0] re_ylb = tempArr[1] if (xbangs.length > 1000) { // debugger } fit = GetInvFit(inv) let info = { times: i, type: 'loop' } if (fit < bestFit) { bestFit = fit bestInv = inv this.CallBack(inv, re_ylb, fit, info) } /** 优化次数限制 逻辑 */ // if (xyhcs == i) { // await this.Stop(info); // info.type = 'stop' // this.CallBack(inv, re_ylb, fit, info) // } await Sleep(Math.max(5, 20 - Math.floor(xbangs.length / 10000))) i++ } } } // 优化所有余料 function YLYH_all(xbangs: xbang[], yuliao_bang: Big_bang[], ylzs: number[], xyhcs: number, qfsh: boolean, isdtwosided: boolean, gap: number, YuLiaoBoardDo2FaceBlock: boolean): [Inv, xbang[], Big_bang[]] // 余料优化 { let get_regelt: Inv = [] let temp_yan_bang: Big_bang[] = [] let re_Bigbang: Big_bang[] = [] temp_yan_bang = [] // console.log('余料总数:', ylzs) for (let i = 0; i < ylzs.length; i++) { if (xbangs.length == 0) { break } else { temp_yan_bang = [] for (let sl = 0; sl < ylzs[i]; sl++) { temp_yan_bang.push(yuliao_bang[i]) } let temp:any = [] temp = ylyh(xbangs, temp_yan_bang, xyhcs, qfsh, isdtwosided, gap, YuLiaoBoardDo2FaceBlock) for (let yhsl = 0; yhsl < temp[0].length; yhsl++) { get_regelt.push(temp[0][yhsl]) } for (let ylsl = 0; ylsl < temp[2].length; ylsl++) { re_Bigbang.push(temp[2][ylsl]) } xbangs = temp[1].slice() // re_Bigbang.push(temp[2].slice()); } } return [get_regelt, xbangs, re_Bigbang] } // 优化余料中的一个尺寸的小板 function ylyh(xbangs: xbang[], yuliao_bang: Big_bang[], xyhcs: number, qfsh: boolean, isdtwosided: boolean, gap: number, YuLiaoBoardDo2FaceBlock: boolean): [Inv, xbang[], Big_bang[]] // 余料优化 { let finbang: xbang[] let yh_result: Inv = [] let l: number let w: number let ylzs: number// 余料张数 let temp_yan_bang: Big_bang[] = [] let re_yan_bang: Big_bang[] = [] let temp_max_YH: Inv = [] temp_yan_bang = [] temp_yan_bang.push(yuliao_bang[0]) l = yuliao_bang[0].l w = yuliao_bang[0].w if (YuLiaoBoardDo2FaceBlock) // 余料板允许加入双面小板 { finbang = find_bang_k_g(l, w, xbangs, false).slice() } else { finbang = find_bang_k_g(l, w, xbangs, true).slice() } if (finbang.length > 0) { if (YuLiaoBoardDo2FaceBlock) // 余料板允许加入双面小板 { temp_max_YH = YHJS(finbang, temp_yan_bang, xyhcs, qfsh, isdtwosided, gap) // 余料板 不优先 双面加工板 } else { temp_max_YH = YHJS(finbang, temp_yan_bang, xyhcs, qfsh, false, gap) } if (yuliao_bang.length > temp_max_YH.length) { ylzs = temp_max_YH.length } else { ylzs = yuliao_bang.length } for (let i = 0; i < ylzs; i++) { yh_result.push(temp_max_YH[i]) re_yan_bang.push(yuliao_bang[0]) for (let n = 0; n < temp_max_YH[i].length; n++) { for (let bsl = xbangs.length - 1; bsl >= 0; bsl--) if (temp_max_YH[i][n].bangid == xbangs[bsl].id) { xbangs.splice(bsl, 1) } } } } return [yh_result, xbangs, re_yan_bang] } // 相同板材优化 function SnameYH(xbangs: xbang[], B_bang: Big_bang[], ylsl: number[], xyhcs: number, qfsh: boolean, isdtwosided: boolean, gap: number, YuLiaoBoardDo2FaceBlock: boolean): [Inv, Big_bang[]] { let same_yh_bang: Inv = [] let temp_max_YH: Inv = [] let ylbang_max_yh: Big_bang[] = [] let temp_same_yh: [Inv, xbang[]] let isend: boolean = false let Bigbang: Big_bang[] = [] Bigbang.push(B_bang[B_bang.length - 1]) let ylbang: Big_bang[] = B_bang.slice() ylbang.pop() let tempresult = [] tempresult = YLYH_all(xbangs, ylbang, ylsl, xyhcs, qfsh, isdtwosided, gap, YuLiaoBoardDo2FaceBlock) // 余料优化 for (let i = 0; i < tempresult[0].length; i++) { same_yh_bang.push(tempresult[0][i]) } xbangs = tempresult[1].slice() ylbang_max_yh = tempresult[2].slice() while (isend === false) { if (xbangs.length == 0) { break } temp_max_YH = YHJS(xbangs, Bigbang, xyhcs, qfsh, isdtwosided, gap) temp_same_yh = Get_bs_bang(temp_max_YH, xbangs, isdtwosided) for (let i = 0; i < temp_same_yh[0].length; i++) { same_yh_bang.push(temp_same_yh[0][i]) xbangs = temp_same_yh[1].slice() } } return [same_yh_bang, ylbang_max_yh] } // 优化计算. function YHJS(xbangs: xbang[], B_bang: Big_bang[], cs: number, qfsh: boolean, isdtwosided: boolean, gap: number): Inv { let xbangs_bak = xbangs.slice() let bestFit = Number.POSITIVE_INFINITY // let bestFit = Infinity; let bestInv: Inv for (let i = 0; i < cs; i++) { xbangs = xbangs_bak.slice() let result_yh: Inv if (qfsh) result_yh = CBJS(xbangs, B_bang, gap, isdtwosided) else result_yh = CBJS1(xbangs, B_bang, gap, isdtwosided) let fit = GetInvFit(result_yh) if (fit < bestFit) { bestFit = fit bestInv = result_yh } } return bestInv } // 得到利用率最高板材,及返回倍数板及剩下的小板 function Get_bs_bang(inv: Inv, listbang: xbang[], isdtwosided: boolean): [Inv, xbang[]] { let [bestCon] = arrayMax(inv, GetConFit)// 最优大板 let temp_yh_bang: Con = [] let temp_list_yh_bang: Inv = [] let isfindend: boolean = false while (isfindend == false) { if (listbang.length == 0) { break } let unPlacelist = listbang.slice() for (let br of bestCon) { let temp_result = find_same_bang(br.pbg, br.pbk, unPlacelist, isdtwosided) if (temp_result.findid > -1) // 找到合适的板 { temp_yh_bang.push( { bangid: temp_result.id, line: temp_result.line, x: br.x, y: br.y, pbg: temp_result.pbg, pbk: temp_result.pbk, }, ) unPlacelist.splice(temp_result.findid, 1)// 这里不会错误的原因是 必然会有一次成功 并且下面会备份这个数组 } else // 没找到 合适的板 退出 { isfindend = true break } } if (isfindend == false) // 找到合适的 { temp_list_yh_bang.push(temp_yh_bang) temp_yh_bang = [] listbang = unPlacelist.slice()// 备份数组 } } return [temp_list_yh_bang, listbang] } function GetInvFit(inv: Inv) { let fit = (inv.length - 1) * 10 fit += GetConFit(arrayLast(inv)) return fit } function GetConFit(con: Con) { let fit = 0 for (let p of con) fit += p.pbg * p.pbk * 1e-6 return fit } // 初步优化计算 横竖算法,无空间合并 function CBJS1(Listbang: xbang[], yanbang: Big_bang[], dt: number, isdtwosided: boolean): Inv // [(YHB_LST)[], (Big_bang[])[], (Big_bang[])[]] { let yanbang_bk: Big_bang[] = yanbang.slice() // let zfkj: Big_bang[] = []; // let list_zfkj: (Big_bang[])[] = []; let list_yh_bng: Inv = [] // let list_yang_bang: (Big_bang[])[] = []; let result_yh: Con = [] while (Listbang.length > 0) { // zfkj = []; yanbang = yanbang_bk.slice() result_yh = [] while (yanbang.length > 0) { let lx: number = Math.floor(Math.random() * 3) // lx:0 面积最大 1 最高 2 最宽 let fs: boolean // fs:留板方式,0:左右 1:上下 if (Math.floor(Math.random() * 2) == 0) { fs = false } else { fs = true } let get_result = [] get_result = jsyb(yanbang[0], lx, fs, dt, Listbang, isdtwosided) // lx:0面积最大 1最高 2最宽 fs:取板方式,false:左右(取同宽) true:上下(取同高) dt:刀头间隙 yanbang.shift() if (get_result[0] > 0) { for (let i = 0; i < get_result[0]; i++) yanbang.push(get_result[2][i]) } if (get_result[1] > 0) { for (let i = 0; i < get_result[1]; i++) result_yh.push(get_result[3][i]) } Listbang = get_result[4].slice() if (Listbang.length == 0) { break } } // list_zfkj.push(zfkj); list_yh_bng.push(result_yh) // list_yang_bang.push(yanbang); // list_zfkj.push(zfkj); // Draw_Yan_bang(yanbang, 3, 0); // Draw_Yan_bang(zfkj, 5, 0); } // return [list_yh_bng, list_zfkj, list_yang_bang]; return list_yh_bng } // 初步优化计算 交叉算法,有空间合并 function CBJS(Listbang: xbang[], yanbang: Big_bang[], dt: number, isdtwosided: boolean): Inv // [(YHB_LST)[], (Big_bang[])[], (Big_bang[])[]] { let yanbang_bk: Big_bang[] = yanbang.slice() // let zfkj: Big_bang[] = []; // let list_zfkj: (Big_bang[])[] = []; let list_yh_bng: Inv = [] // let list_yang_bang: (Big_bang[])[] = []; let result_yh: Con = [] // let temp: number = 0; while (Listbang.length > 0)// while (temp < 2)// { // temp++; // zfkj = []; yanbang = yanbang_bk.slice() result_yh = [] while (yanbang.length > 0) { let lx: number = Math.floor(Math.random() * 3) // lx:0 面积最大 1 最高 2 最宽 let fs: boolean // fs:留板方式,0:左右 1:上下 if (Math.floor(Math.random() * 2) == 0) { fs = false } else { fs = true } let get_result = [] let temp_yanbang = [] temp_yanbang = HBKJ(yanbang, Listbang, dt) yanbang = temp_yanbang[0] get_result = jsyb1(yanbang[temp_yanbang[1]], lx, fs, dt, Listbang, isdtwosided) // lx:0面积最大 1最高 2最宽 fs:取板方式,false:取同宽) true:取同高) dt:刀头间隙 yanbang.splice(temp_yanbang[1], 1) if (get_result[0] > 0) { for (let i = 0; i < get_result[0]; i++) yanbang.push(get_result[2][i]) } if (get_result[1] > 0) { for (let i = 0; i < get_result[1]; i++) result_yh.push(get_result[3][i]) } Listbang = get_result[4].slice() if (Listbang.length == 0) { break } } // list_zfkj.push(zfkj); list_yh_bng.push(result_yh) // list_yang_bang.push(yanbang); // list_zfkj.push(zfkj); // Draw_Yan_bang(yanbang, 3, 0); // Draw_Yan_bang(zfkj, 5, 0); } // return [list_yh_bng, list_zfkj, list_yang_bang]; return list_yh_bng } // 空间合并(相加) function hb(yanbang: Big_bang[], dt: number): Big_bang[] { let i: number = -1 yanbang.sort((a1, a2) => a1.x - a2.x) while (true) { i++ if (yanbang.length < 2 || i === yanbang.length - 1) break if (yanbang[i].y === yanbang[i + 1].y && yanbang[i].x + yanbang[i].w + dt === yanbang[i + 1].x && yanbang[i].l === yanbang[i + 1].l) { yanbang[i].w = yanbang[i].w + yanbang[i + 1].w + dt yanbang.splice(i + 1, 1) i = -1 } } return yanbang } // 整理空间 function zlkj(yanbang: Big_bang[], listbang: xbang[], dt: number): [Big_bang[], boolean] // false 继续合并 ture 不在合并 { let k: number let g: number let isjshb: boolean = true// false 继续合并 ture 不在合并 let minY: number = 100000 let yanindex: number if (listbang.length == 0) return [yanbang, true] for (let i = 0; i < yanbang.length; i++) { if (yanbang[i].y < minY) { minY = yanbang[i].y yanindex = i } } k = yanbang[yanindex].w g = yanbang[yanindex].l if (yanindex == 0 && yanbang.length > 1) { if (yanbang[yanindex].x + yanbang[yanindex].w + dt == yanbang[yanindex + 1].x)// && yanbang[i].y + yanbang[i].l == yanbang[i + 1].y + yanbang[i + 1].l) { if (find_max_mz(g, k, listbang, false).findid == -1) { yanbang[yanindex].y = yanbang[yanindex + 1].y yanbang[yanindex].l = yanbang[yanindex + 1].l isjshb = false } } } else if (yanindex == yanbang.length - 1 && yanbang.length > 1) { if (yanbang[yanindex - 1].x + yanbang[yanindex - 1].w + dt == yanbang[yanindex].x && yanbang.length > 1)// && yanbang[i].y + yanbang[i].l == yanbang[i - 1].y + yanbang[i - 1].l && (yanbang[i - 1].x + yanbang[i - 1].w + dt == yanbang[i].x)) { if (find_max_mz(g, k, listbang, false).findid == -1) { yanbang[yanindex].y = yanbang[yanindex - 1].y yanbang[yanindex].l = yanbang[yanindex - 1].l isjshb = false } } } else if (yanbang.length > 1) { if (yanbang[yanindex - 1].y > yanbang[yanindex + 1].y) { if (yanbang[yanindex].x + yanbang[yanindex].w + dt == yanbang[yanindex + 1].x)// && yanbang[i].y + yanbang[i].l == yanbang[i + 1].y + yanbang[i + 1].l) { if (find_max_mz(g, k, listbang, false).findid == -1) { yanbang[yanindex].y = yanbang[yanindex + 1].y yanbang[yanindex].l = yanbang[yanindex + 1].l isjshb = false } } } else { if (yanbang[yanindex - 1].x + yanbang[yanindex - 1].w + dt == yanbang[yanindex].x)// && yanbang.length > 1 && yanbang[i].y + yanbang[i].l == yanbang[i - 1].y + yanbang[i - 1].l && (yanbang[i - 1].x + yanbang[i - 1].w + dt == yanbang[i].x)) { if (find_max_mz(g, k, listbang, false).findid == -1) { yanbang[yanindex].y = yanbang[yanindex - 1].y yanbang[yanindex].l = yanbang[yanindex - 1].l isjshb = false } } } } // console.log("zlkj"); // console.log(g, k); // console.log(yanbang); // console.log(listbang); // Sleep(0); return [yanbang, isjshb] } // 合并空间 function HBKJ(yanbang: Big_bang[], listbang: xbang[], dt: number): [Big_bang[], number] { let get_result: Big_bang[] let minY: number = 10000 let yanindex: number get_result = hb(yanbang, dt) yanbang = get_result let isend: boolean = false while (isend == false) { if (yanbang.length == 1) { break } for (let i = 0; i < yanbang.length; i++) { let temp_result = [] temp_result = zlkj(yanbang, listbang, dt) if (temp_result[1] == false) { yanbang = temp_result[0] get_result = hb(yanbang, dt) yanbang = get_result } else isend = true } } for (let i = 0; i < yanbang.length; i++) { if (yanbang[i].y < minY) { minY = yanbang[i].y yanindex = i } } return [yanbang, yanindex] } // 寻找符合面积的板 function find_bang_k_g(g: number, k: number, Listbang: xbang[], oneFaceBlock: boolean): xbang[] // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 isdtwosided: boolean true 翻板提前 { let finbang: xbang[] = [] if (oneFaceBlock == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && Listbang[i].isdtwosided == false) { finbang.push(Listbang[i]) } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && Listbang[i].isdtwosided == false) { finbang.push(Listbang[i]) } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && Listbang[i].isdtwosided == false) { finbang.push(Listbang[i]) } else if (Listbang[i].l <= k && Listbang[i].w <= g && Listbang[i].isdtwosided == false) { finbang.push(Listbang[i]) } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k) { finbang.push(Listbang[i]) } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g) { finbang.push(Listbang[i]) } } else { if (Listbang[i].l <= g && Listbang[i].w <= k) { finbang.push(Listbang[i]) } else if (Listbang[i].l <= k && Listbang[i].w <= g) { finbang.push(Listbang[i]) } } } } return finbang } // 寻找面积最的板 // 寻找面积最大的板 function find_max_mz(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 isdtwosided: boolean true 翻板提前 { let max: number = 0 let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 let temp_max: number if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { temp_max = Listbang[i].l * Listbang[i].w / 1000000 if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max && Listbang[i].isdtwosided == true) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max && Listbang[i].isdtwosided == true) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max && Listbang[i].isdtwosided == true) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max && Listbang[i].isdtwosided == true) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { temp_max = Listbang[i].l * Listbang[i].w / 1000000 if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } } else { for (let i = 0; i < Listbang.length; i++) { temp_max = Listbang[i].l * Listbang[i].w / 1000000 if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < temp_max) { max = temp_max bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < temp_max) { max = temp_max bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } } // 寻找面积最的板 // 寻找最高的板 function find_max_g(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 { let max: number = 0 let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l && Listbang[i].isdtwosided == true) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w && Listbang[i].isdtwosided == true) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l && Listbang[i].isdtwosided == true) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w && Listbang[i].isdtwosided == true) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } } // 寻找同高的板 function find_same_g(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 { let max: number = g let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].l) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].w) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } }// 寻找同高的板 // 寻找最宽的板 function find_max_k(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 { let max: number = 0 let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w && Listbang[i].isdtwosided == true) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l && Listbang[i].isdtwosided == true) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w && Listbang[i].isdtwosided == true) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l && Listbang[i].isdtwosided == true) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max < Listbang[i].w) { max = Listbang[i].w bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id } else if (Listbang[i].l <= k && Listbang[i].w <= g && max < Listbang[i].l) { max = Listbang[i].l bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } } // 寻找最高的板 // 寻同宽的板 function find_same_k(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 lx:0 面积最大 1 最高 2 最宽 { let max: number = k let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l <= g && Listbang[i].w <= k && max == Listbang[i].w) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l <= k && Listbang[i].w <= g && max == Listbang[i].l) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } } // 寻同宽的板 // 找到同样大小尺寸的板材 && Listbang[i].isdtwosided == true) function find_same_bang(g: number, k: number, Listbang: xbang[], isdtwosided: boolean): findbang // g 高 k 宽 listbang:小板列表 1 同高 2 同宽 { let bangindex: number = -1 let line: LineType = LineType.Positive let pbg: number = 0 let pbk: number = 0 let bangid: number = 0 if (isdtwosided == true) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l == g && Listbang[i].w == k && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l == k && Listbang[i].w == g && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l == g && Listbang[i].w == k && Listbang[i].isdtwosided == true) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l == k && Listbang[i].w == g && Listbang[i].isdtwosided == true) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } if (bangindex == -1) { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l == g && Listbang[i].w == k) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l == k && Listbang[i].w == g) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l == g && Listbang[i].w == k) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l == k && Listbang[i].w == g) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } } else { for (let i = 0; i < Listbang.length; i++) { if (Listbang[i].line == 0) { if (Listbang[i].l == g && Listbang[i].w == k) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } } else if (Listbang[i].line == 1) { if (Listbang[i].l == k && Listbang[i].w == g) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } else { if (Listbang[i].l == g && Listbang[i].w == k) { bangindex = i line = 0 pbg = Listbang[i].l pbk = Listbang[i].w bangid = Listbang[i].id break } else if (Listbang[i].l == k && Listbang[i].w == g) { bangindex = i line = 1 pbg = Listbang[i].w pbk = Listbang[i].l bangid = Listbang[i].id break } } } } return { findid: bangindex, line, pbg, pbk, id: bangid, } } // 寻找同高或同宽的板 // 计算生成的余板 返回 余板数组,连带的板 小板数组 // lx:0面积最大 1最高 2最宽 fs:取板方式,false:左右(取同宽) true:上下(取同高) dt:刀头间隙 function jsyb(bigbang: Big_bang, lx: number, fs: boolean, dt: number, listbang: xbang[], isdtwosided: boolean): [number, number, Big_bang[], Con, xbang[], number, Big_bang[]] { let x: number = bigbang.x let y: number = bigbang.y let k: number = bigbang.w let g: number = bigbang.l let isend: boolean = false let ybg: number = g let ybk: number = k let x1: number = x let y1: number = y let yb: Big_bang[] = [] // #余板 坐标跟高宽; let yhxbang: Con = [] // #连带小板的Id,及坐标 let zfkj: Big_bang[] = [] // 作废的空间 let l: number let w: number let get_result: findbang let temp_get: findbang if (lx === 0) { // get_result = find_max_mz(g, k, listbang); get_result = find_max_mz(g, k, listbang, isdtwosided) } else if (lx == 1) { // get_result = find_max_g(g, k, listbang); get_result = find_max_g(g, k, listbang, isdtwosided) } else { // get_result = find_max_k(g, k, listbang); get_result = find_max_k(g, k, listbang, isdtwosided) } if (get_result.findid > -1) { yhxbang.push({ bangid: get_result.id, line: get_result.line, x, y, pbg: get_result.pbg, pbk: get_result.pbk, }) listbang.splice(get_result.findid, 1) l = get_result.pbg w = get_result.pbk if (fs == false) // false:左右(取同宽) true:上下(取同高) { ybg = g - l - dt y1 = y + l + dt while (isend == false) { // temp_get = find_same_k(ybg, w, listbang); temp_get = find_same_k(ybg, w, listbang, isdtwosided) if (temp_get.findid > -1) { yhxbang.push({ bangid: temp_get.id, line: temp_get.line, x, y: y1, pbg: temp_get.pbg, pbk: temp_get.pbk, }) y1 = y1 + temp_get.pbg + dt ybg = ybg - temp_get.pbg - dt listbang.splice(temp_get.findid, 1) } else { if (ybg > 0) { yb.push({ l: ybg, w, x, y: y1, }) } if (k - w - dt > 0) { yb.push({ l: g, w: k - w - dt, x: x + w + dt, y, }) } break } } } else // true:上下(取同高) { ybk = k - w - dt x1 = x + w + dt while (isend == false) { temp_get = find_same_g(l, ybk, listbang, isdtwosided) if (temp_get.findid > -1) { yhxbang.push({ bangid: temp_get.id, line: temp_get.line, x: x1, y, pbg: temp_get.pbg, pbk: temp_get.pbk, }) x1 = x1 + temp_get.pbk + dt ybk = ybk - temp_get.pbk - dt listbang.splice(temp_get.findid, 1) } else { if (ybk > 0) { yb.push({ l, w: ybk, x: x1, y, }) } if (g - l - dt > 0) { yb.push({ l: g - l - dt, w: k, x, y: y + l + dt, }) } break } } } // false:左右(取同宽) true:上下(取同高) let ybsl: number = 0 let yhsl: number = 0 if (yb.length > 0) { ybsl = yb.length } if (yhxbang.length > 0) { yhsl = yhxbang.length } return [ybsl, yhsl, yb, yhxbang, listbang, 0, zfkj] } else { zfkj.push({ l: g, w: k, x, y, }) let ybsl: number = 0 let yhsl: number = 0 if (yb.length > 0) { ybsl = yb.length } if (yhxbang.length > 0) { yhsl = yhxbang.length } return [ybsl, yhsl, yb, yhxbang, listbang, 1, zfkj] } } // 计算生成的余板 返回 余板数组,连带的板 小板数组 都是左右分隔空间,后面再来空间合并 // lx:0面积最大 1最高 2最宽 fs:取板方式,false:取同宽 true:取同高 dt:刀头间隙 function jsyb1(bigbang: Big_bang, lx: number, fs: boolean, dt: number, listbang: xbang[], isdtwosided: boolean): [number, number, Big_bang[], Con, xbang[], number, Big_bang[]] { let x: number = bigbang.x let y: number = bigbang.y let k: number = bigbang.w let g: number = bigbang.l let isend: boolean = false let ybg: number = g let ybk: number = k let x1: number = x let y1: number = y let yb: Big_bang[] = [] // #余板 坐标跟高宽; let yhxbang: Con = []// #连带小板的Id,及坐标 let zfkj: Big_bang[] = [] // 作废的空间 let l: number let w: number let get_result: findbang let temp_get: findbang if (lx == 0) { // get_result = find_max_mz(g, k, listbang); get_result = find_max_mz(g, k, listbang, isdtwosided) } else if (lx == 1) { // get_result = find_max_g(g, k, listbang); get_result = find_max_g(g, k, listbang, isdtwosided) } else { // get_result = find_max_k(g, k, listbang); get_result = find_max_k(g, k, listbang, isdtwosided) } if (get_result.findid > -1) { yhxbang.push({ bangid: get_result.id, line: get_result.line, x, y, pbg: get_result.pbg, pbk: get_result.pbk, }) listbang.splice(get_result.findid, 1) ////////////// l = get_result.pbg w = get_result.pbk if (fs == false) // false:左右(取同宽) true:上下(取同高) { ybg = g - l - dt y1 = y + l + dt while (isend == false) { temp_get = find_same_k(ybg, w, listbang, isdtwosided) if (temp_get.findid > -1) { yhxbang.push({ bangid: temp_get.id, line: temp_get.line, x, y: y1, pbg: temp_get.pbg, pbk: temp_get.pbk, }) y1 = y1 + temp_get.pbg + dt ybg = ybg - temp_get.pbg - dt listbang.splice(temp_get.findid, 1) } else { if (ybg > 0) { yb.push({ l: ybg, w, x, y: y1, }) } if (k - w - dt > 0) { yb.push({ l: g, w: k - w - dt, x: x + w + dt, y, }) } break } } } else // true:上下(取同高) { ybk = k - w - dt x1 = x + w + dt while (isend == false) { temp_get = find_same_g(l, ybk, listbang, isdtwosided) if (temp_get.findid > -1) { yhxbang.push({ bangid: temp_get.id, line: temp_get.line, x: x1, y, pbg: temp_get.pbg, pbk: temp_get.pbk, }) x1 = x1 + temp_get.pbk + dt ybk = ybk - temp_get.pbk - dt listbang.splice(temp_get.findid, 1) } else { if (ybk > 0) { yb.push({ l: g, w: ybk, x: x1, y, }) } if (g - l - dt > 0) { yb.push({ l: g - l - dt, w: k - ybk - dt, x, y: y + l + dt, }) } break } } } // false:左右(取同宽) true:上下(取同高) //////////////////////////////////////////////////////////////////////////// let ybsl: number = 0 let yhsl: number = 0 if (yb.length > 0) { ybsl = yb.length } if (yhxbang.length > 0) { yhsl = yhxbang.length } return [ybsl, yhsl, yb, yhxbang, listbang, 0, zfkj] } else { zfkj.push({ l: g, w: k, x, y, }) let ybsl: number = 0 let yhsl: number = 0 if (yb.length > 0) { ybsl = yb.length } if (yhxbang.length > 0) { yhsl = yhxbang.length } return [ybsl, yhsl, yb, yhxbang, listbang, 1, zfkj] } } interface findbang { findid: number line: LineType pbg: number pbk: number id: number } interface Lyr { pfs: number// 平方数 lry: number// 利用率 ys: number// 页数 } /** 获取数组最后一个元素 */ function arrayLast(arr: { [key: number]: T; length: number }): T { return arr[arr.length - 1] } /** 查找数组中最大的元素 */ function arrayMax(arr: T[], f: (item: T) => number = a => (a as unknown as number)): [T, number] { let max = Number.NEGATIVE_INFINITY let maxIndex = -1 for (let i = 0; i < arr.length; i++) { let item = arr[i] let v = f(item) if (v > max) { maxIndex = i max = v } } return [arr[maxIndex], maxIndex] } async function Sleep(time: number) { return new Promise((res) => { setTimeout(res, time) }) }