NX Lab

Tìm giá trị tham số thỏa mục tiêu khối lượng bằng tìm kiếm nhị phân: chọn độ dày để đạt 0.5 kg

#Python#Tối ưu#Khối lượng1 lượt xem

  1. Quản trị viênQuản trị· 0 điểm

    Câu hỏi ·

    Bài toán thường gặp: chọn độ dày sao cho chi tiết nặng đúng 0.5 kg. Khối lượng tăng đơn điệu theo độ dày nên tìm kiếm nhị phân hội tụ nhanh: sửa expression, cập nhật, đo khối lượng, thu hẹp khoảng.

    Tìm giá trị tham số thỏa mục tiêu khối… Tìm giá trị tham số thỏa mục tiêu khối…

    Các bước thực hiện

    1. Xác định khoảng tìm. Độ dày nhỏ nhất và lớn nhất cho phép.
    2. Hàm đo. Sửa expression, cập nhật, đo khối lượng.
    3. Chia đôi khoảng. So khối lượng với mục tiêu.
    4. Dừng khi đủ sát. Sai số hoặc số vòng tối đa.
    5. Đặt giá trị tìm được. Và khôi phục nếu không hội tụ.

    Code tham khảo (Python)

    import NXOpen
    
    def do_khoi_luong(part, mat_do=7.85e-6):
        bodies = [b for b in part.Bodies if b.IsSolidBody]
        for b in bodies:
            b.Density = mat_do
        uc = part.UnitCollection
        don_vi = [uc.FindObject("SquareMilliMeter"), uc.FindObject("CubicMilliMeter"),
                  uc.FindObject("Kilogram"), uc.FindObject("MilliMeter"), uc.FindObject("Kilogram")]
        return part.MeasureManager.NewMassProperties(don_vi, 0.99, bodies).Mass
    
    def dat_va_do(session, part, ten_exp, gia_tri):
        mark = session.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Thu")
        part.Expressions.Edit(part.Expressions.FindObject(ten_exp), "%.6f" % gia_tri)
        ma = session.UpdateManager.DoUpdate(mark)
        session.DeleteUndoMark(mark, "Thu")
        if ma != 0:
            raise RuntimeError("DoUpdate lỗi %d tại %s = %g" % (ma, ten_exp, gia_tri))
        return do_khoi_luong(part)
    
    def tim_nhi_phan(session, part, ten_exp, muc_tieu_kg, thap, cao, sai_so=1e-3, toi_da=30):
        km_thap, km_cao = dat_va_do(session, part, ten_exp, thap), dat_va_do(session, part, ten_exp, cao)
        if not (km_thap <= muc_tieu_kg <= km_cao):
            raise ValueError("Mục tiêu %.3f kg ngoài khoảng đạt được [%.3f, %.3f]" % (muc_tieu_kg, km_thap, km_cao))
        for _ in range(toi_da):
            giua = (thap + cao) / 2.0
            km = dat_va_do(session, part, ten_exp, giua)
            if abs(km - muc_tieu_kg) <= sai_so:
                return giua, km
            if km < muc_tieu_kg:
                thap = giua
            else:
                cao = giua
        return giua, km
    
    def main():
        session = NXOpen.Session.GetSession()
        lw = session.ListingWindow
        lw.Open()
        part = session.Parts.Work
        if part is None:
            return
        gia_tri_cu = part.Expressions.FindObject("day").Value
        session.SetUndoMark(NXOpen.Session.MarkVisibility.Visible, "Tim do day")
        try:
            day, km = tim_nhi_phan(session, part, "day", muc_tieu_kg=0.5, thap=1.0, cao=30.0)
            lw.WriteLine("Độ dày tìm được: %.4f mm -> khối lượng %.4f kg" % (day, km))
        except Exception as ex:
            lw.WriteLine("Không tìm được: %s" % ex)
            dat_va_do(session, part, "day", gia_tri_cu)
            lw.WriteLine("Đã khôi phục độ dày %.3f" % gia_tri_cu)
    
    if __name__ == "__main__":
        main()
    

    Giải thích code

    • Tìm kiếm nhị phân cần hàm đơn điệu: khối lượng tăng khi độ dày tăng.
    • Kiểm tra mục tiêu có nằm giữa hai đầu khoảng trước khi lặp để báo lỗi rõ ràng.
    • Mỗi vòng gọi một lần cập nhật và đo, nên 30 vòng có thể mất vài phút ở mô hình nặng.

    Lỗi thường gặp

    • Hàm không đơn điệu (hình học đổi dạng theo độ dày) làm nhị phân cho kết quả sai; kiểm tra bằng quét giá trị trước.
    • Mật độ đặt là thép; đổi theo vật liệu thật.

    Code mang tính tham khảo, viết cho NX 12 trở lên (Python journal). Tên menu và một số lớp có thể khác theo phiên bản NX; hãy chạy thử trên bản sao của chi tiết trước khi dùng cho dữ liệu thật.

    Điểm: 0

Trả lời

Đăng nhập để tham gia thảo luận.