Tiện ích tính toán để tiết kiệm khi cắt tấm, cắt thanh.

Liên hệ QC

huuthang_bd

Chuyên gia GPE
Tham gia
10/9/08
Bài viết
8,708
Được thích
10,810
Donate (Momo)
Donate
Giới tính
Nam
Nghề nghiệp
Thợ đụng
Lần trước tôi đã gửi một file dùng để tính toán các sắp xếp tối ưu những hình chữ nhật nhỏ có cùng kích thước trong một hình chữ nhật lớn để số lượng hình chữ nhật nhỏ được xếp là lớn nhất. Tiện ích này sẽ giúp các bạn tiết kiệm không gian khi sắp xếp hàng hóa, tiết kiệm nguyên liệu khi cắt một tấm lớn ra thành nhiều tấm nhỏ.

Lần này tôi gửi tặng các bạn thành viên GPE một tiệt ích dùng để tiết kiệm khi cắt các thanh nguyên liệu ra thành nhiều thanh ngắn hơn có độ dài khác nhau.

Tôi đã gộp cả hai tiện ích trên vào trong một file đính kèm bên dưới. Để sử dụng, bạn chỉ cần nhập số liệu phù hợp vào các ô màu xanh và bấm nút.

Hi vọng sẽ có ích cho nhiều người.
 

File đính kèm

  • Toi uu hoa v1.1.xls
    72 KB · Đọc: 1,229
Lần chỉnh sửa cuối:
Tôi đã gộp cả hai tiện ích trên vào trong một file đính kèm bên dưới. Để sử dụng, bạn chỉ cần nhập số liệu phù hợp vào các ô màu xanh và bấm nút.

Hi vọng sẽ có ích cho nhiều người.[/QUOTE]
Hiện tại trên thị trường thép thanh chủ yếu có 3 loại. 6000, 9000, 11700, mình đã thử khảo sát thấy 2 loại 11700 và 9000 hiệu quả cao, nhưng còn loại 6000 thì có vẻ hiệu quả chưa cao . Mình gửi kèm file để bạn xem thử .
 

File đính kèm

  • Toi uu hoa.xls
    85.5 KB · Đọc: 460
Tôi đã gộp cả hai tiện ích trên vào trong một file đính kèm bên dưới. Để sử dụng, bạn chỉ cần nhập số liệu phù hợp vào các ô màu xanh và bấm nút.

Hi vọng sẽ có ích cho nhiều người.
Hiện tại trên thị trường thép thanh chủ yếu có 3 loại. 6000, 9000, 11700, mình đã thử khảo sát thấy 2 loại 11700 và 9000 hiệu quả cao, nhưng còn loại 6000 thì có vẻ hiệu quả chưa cao . Mình gửi kèm file để bạn xem thử .[/QUOTE]

Nếu bạn để ý sẽ thấy trong kết quả của tôi thanh được cắt trước luôn có đoạn thừa nhỏ hơn hoặc bằng thanh cắt sau. Và thuật toán của tôi là như vậy, tức là tối ưu hóa ở từng cây 1.

Như tôi đã nói ở bài #1, nếu xét về tổng thể thì có thể có trường hợp không phải là phương pháp tối ưu (thường xảy ra khi các thanh cần cắt có kích thước lẻ).

Hiện tại tôi cũng chưa có thuật toán khác tốt hơn.
 
tối ưu hoá cắt thanh

nếu bạn có thời gian thì cộng dồn các cột giống nhau lại.
mình gửi file này để các bạn xem . mình thấy nó tiện ích hơn (có thể copy dữ liệu từ excel đổ vào và chạy tốt)
file này mình tìm thấy trên diễn đàn của bạn "thanhlanh" post lên rất hay .
thực tế mình thử nghiệm thì nó chỉ đáp ứng được định lượng cho lập kế hoạch dự trù trước NVL còn không thể áp dụng để thi công được vì hao hụt quá cao. bạn có thể tối ưu hoá hơn được không.
 

File đính kèm

  • CatNhom_sua.xls
    73.5 KB · Đọc: 337
nếu bạn có thời gian thì cộng dồn các cột giống nhau lại.
mình gửi file này để các bạn xem . mình thấy nó tiện ích hơn (có thể copy dữ liệu từ excel đổ vào và chạy tốt)
file này mình tìm thấy trên diễn đàn của bạn "thanhlanh" post lên rất hay .
thực tế mình thử nghiệm thì nó chỉ đáp ứng được định lượng cho lập kế hoạch dự trù trước NVL còn không thể áp dụng để thi công được vì hao hụt quá cao. bạn có thể tối ưu hoá hơn được không.

Ngay từ đầu tôi đã nói trong một số trường hợp phương án của tôi không phải là phương án tối ưu. Và cái file bạn post lên cũng thế.

Bạn thử với bộ số liệu này ở 2 file xem.
8|3500
10|3000
4|2000
3|1800
4|1600
5|1500
6|1000
7|200
Số liệu tôi lấy ngẫu nhiên chứ không phải chọn đâu nhé. Bạn có thể thử với nhiều bộ số liệu rồi tự mình nhận xét.
 
Hiện tại trên thị trường thép thanh chủ yếu có 3 loại. 6000, 9000, 11700, mình đã thử khảo sát thấy 2 loại 11700 và 9000 hiệu quả cao, nhưng còn loại 6000 thì có vẻ hiệu quả chưa cao . Mình gửi kèm file để bạn xem thử .
Tôi đã cập nhật lại file ở bài #1. Viết thêm một đoạn code xử lý kết quả sao cho tiết kiệm nhất. Bạn test thử còn trường hợp nào chưa tối ưu không.
 
Tôi đã cập nhật lại file ở bài #1. Viết thêm một đoạn code xử lý kết quả sao cho tiết kiệm nhất. Bạn test thử còn trường hợp nào chưa tối ưu không.
Mình text thử thầy tốt rồi, không biết sau này có gặp trường hợp khác không. xin cám ơn bạn !
 
Hiện tại trên thị trường thép thanh chủ yếu có 3 loại. 6000, 9000, 11700, mình đã thử khảo sát thấy 2 loại 11700 và 9000 hiệu quả cao, nhưng còn loại 6000 thì có vẻ hiệu quả chưa cao . Mình gửi kèm file để bạn xem thử .

Bạn có vẻ đủ kiên nhẫn để test các code thì phải.

Nhờ bạn test hộ code của tôi. Đơn giản thôi. Tối ưu hóa thì có nhiều khía cạnh. Tôi đi theo hướng cắt sao cho số thanh nguyên dùng để cắt các thanh nhỏ là ít nhất. Nhưng tôi không dám chắc thuật toán là tối ưu. Thôi thì gọi là một cách cắt.

Mã:
Private Sub cat(ByVal length As Double, Arr)
'    cac lan cat tu 1 thanh nguyen
Dim index As Long, currCount As Long
    For index = LBound(Arr) To UBound(Arr)
'        so thanh co do dai lon nhat co the cat duoc
        currCount = length \ Arr(index, LBound(Arr, 2))
        If currCount > Arr(index, LBound(Arr, 2) + 1) Then
            currCount = Arr(index, LBound(Arr, 2) + 1)
        End If
        If currCount > 0 Then Exit For
    Next index
    If index <= UBound(Arr) Then
        Arr(index, UBound(Arr, 2)) = currCount
        Arr(index, LBound(Arr, 2) + 1) = 0
        cat length - Arr(index, LBound(Arr, 2)) * currCount, Arr
    End If
End Sub

Public Function cat_thanh(Arr, dodaithanh As Double)
'    Range du lieu gom 2 cot. Cot dau chua lan luot kich thuoc cua cac thanh can cat, cot 2 la so luong can cat tuong ung
'    dodaithanh - do dai cua moi thanh nguyen ma tu do can cat cac thanh nho
'    ham tra ve mang 2 chieu
'    cat_thanh(r, c) la so thanh thu r cat duoc tu thanh nguyen thu c
Dim r As Long, DoContinue As Boolean, sothanh() As Long, result
    ReDim Preserve Arr(1 To UBound(Arr), 1 To UBound(Arr, 2) + 1)
    ReDim sothanh(1 To UBound(Arr))
    For r = 1 To UBound(Arr)
'       Kiem tra du lieu cho chac chan - de phong truong hop du lieu chua thanh can cat dai hon thanh nguyen
        If Arr(r, LBound(Arr, 2)) > dodaithanh Then
            sothanh(r) = 0
        Else
            sothanh(r) = Arr(r, LBound(Arr, 2) + 1)
        End If
    Next r
    ReDim result(1 To UBound(Arr), 1 To 1)
    Do
        DoContinue = False
'        cat thanh nguyen
        cat dodaithanh, Arr
        For r = 1 To UBound(Arr)
            result(r, UBound(result, 2)) = Arr(r, UBound(Arr, 2))
            sothanh(r) = sothanh(r) - Arr(r, UBound(Arr, 2))
            Arr(r, UBound(Arr, 2)) = Empty
            Arr(r, LBound(Arr, 2) + 1) = sothanh(r)
            If sothanh(r) > 0 Then
                DoContinue = True
            End If
        Next r
        
        If DoContinue Then
            ReDim Preserve result(1 To UBound(result), 1 To UBound(result, 2) + 1)
        End If
    Loop Until Not DoContinue
    
    cat_thanh = result
End Function

Sub cat_cat_cat()
Dim Arr, result
    With Range([B4], [C14].End(xlUp))
        .Sort .Cells(1, 1), xlDescending
        Arr = .Value
    End With
    result = cat_thanh(Arr, [C1].Value)
    [F4].Resize(UBound(result), UBound(result, 2)).Value = result
End Sub
 

File đính kèm

  • cat.xls
    42 KB · Đọc: 265
Bạn có vẻ đủ kiên nhẫn để test các code thì phải.

Nhờ bạn test hộ code của tôi. Đơn giản thôi. Tối ưu hóa thì có nhiều khía cạnh. Tôi đi theo hướng cắt sao cho số thanh nguyên dùng để cắt các thanh nhỏ là ít nhất. Nhưng tôi không dám chắc thuật toán là tối ưu. Thôi thì gọi là một cách cắt.

Tôi test thấy có vài trường hợp như trong file.
 

File đính kèm

  • Test.xls
    37.5 KB · Đọc: 119
Bạn có vẻ đủ kiên nhẫn để test các code thì phải.

Nhờ bạn test hộ code của tôi. Đơn giản thôi. Tối ưu hóa thì có nhiều khía cạnh. Tôi đi theo hướng cắt sao cho số thanh nguyên dùng để cắt các thanh nhỏ là ít nhất. Nhưng tôi không dám chắc thuật toán là tối ưu. Thôi thì gọi là một cách cắt.

[/CODE]
Thưa thày siwtom, nếu thấy chủ đề hay nhà em hay down các bài viết của các thày và các bạn về để học hỏi . Nếu không text thử thì không thể biết code hay ở chỗ nào . Thực tế có nhiều trường hợp bạn viết cẩu thả , hoặc bạn sửa code của người khác , rồi không text thử nên code không chạy . Vì vậy nhà em cứ text thử, khi code cho kết quả thì kiểm tra kết quả, sau đó mới mở xem code và học cách viết của các thầy . Nếu cùng chủ đề thì xem bài viết nào ngắn gọn, dễ hiểu hơn, code nào cho kết quả nhanh hơn , chạy có vẻ "êm" hơn . Về chủ đề này , nhà em không hiểu về thuật toán và code thì chỗ hiểu , chỗ không vì kiến thức có hạn . Nhà em đã text thử ở tập tin đính kèm .
 

File đính kèm

  • cat.xls
    42.5 KB · Đọc: 119
Thưa thày siwtom, nếu thấy chủ đề hay nhà em hay down các bài viết của các thày và các bạn về để học hỏi . Nếu không text thử thì không thể biết code hay ở chỗ nào . Thực tế có nhiều trường hợp bạn viết cẩu thả , hoặc bạn sửa code của người khác , rồi không text thử nên code không chạy . Vì vậy nhà em cứ text thử, khi code cho kết quả thì kiểm tra kết quả, sau đó mới mở xem code và học cách viết của các thầy . Nếu cùng chủ đề thì xem bài viết nào ngắn gọn, dễ hiểu hơn, code nào cho kết quả nhanh hơn , chạy có vẻ "êm" hơn . Về chủ đề này , nhà em không hiểu về thuật toán và code thì chỗ hiểu , chỗ không vì kiến thức có hạn . Nhà em đã text thử ở tập tin đính kèm .

Đúng là chưa tối ưu. Với dữ liệu như thế thì phải dùng tới 10 thanh (từ thanh cuối 9000 cắt 1 thanh nhỏ 852).
Cách của huuthang_bd và cách bạn liệt kê chỉ cần dùng 9 thanh.

Nói thực là việc cắt thanh là việc khó. Có thể với dữ liệu thế này thì tối ưu nhưng với dữ liệu khác thì chưa chắc. Trừ phi dùng cách xét tất cả mọi trường hợp - có thể là con số rất lớn nhưng hữu hạn - còn không khó chứng minh chặt chẽ về mặt toán học là thuật toán chắc chắn là tối ưu.

Tôi thử thay đổ kích thước thanh con cuối từ 215 thành 515 thì cách của tôi và của huuthang_bd đều dùng 10 thanh 9000.

View attachment 105982

View attachment 105983


Kất quả các đoạn thừa:

Cách của tôi: 22, 56, 256, 241, 241, 241, 480, 137, 450, 7633
Cách của huuthang_bd: 0, 1, 18, 166, 237, 756, 756, 1847, 2988, 2988

Trong cách của tôi có thừa một đoạn rất có giá trị vì dài tận 7633

Đùa chút thôi nhưng thực ra bài toán cắt thanh là bài toán khó, phải bỏ thời gian ra nghiên cứu sâu chứ làm chơi là không được.
 
Tôi thử thay đổi kích thước thanh con cuối từ 215 thành 515 thì cách của tôi và của huuthang_bd đều dùng 10 thanh 9000.

View attachment 105982

View attachment 105983


Kất quả các đoạn thừa:

Cách của tôi: 22, 56, 256, 241, 241, 241, 480, 137, 450, 7633
Cách của huuthang_bd: 0, 1, 18, 166, 237, 756, 756, 1847, 2988, 2988

Trong cách của tôi có thừa một đoạn rất có giá trị vì dài tận 7633

Đùa chút thôi nhưng thực ra bài toán cắt thanh là bài toán khó, phải bỏ thời gian ra nghiên cứu sâu chứ làm chơi là không được.[/QUOTE]

Thưa thày, bài toán cắt thép thực ra còn một bước nữa mà thực tế người ta đang làm , đó là nối các đầu thừa để cắt thanh nào đó nếu phù hợp kích thước ( điều này trong kỹ thuật nhiều trường hợp được phép nối ). chính vì vậy nhiều bài toán rất hay, nhưng ứng dụng vào thực tế lại hạn chế . Với đề tài này các thày giải quyết phương án chắc là tối ưu rồi (tất nhiên ta không thể text mãi để kiểm chứng được; Xin cám ơn thày và các bạn .
 
Lần chỉnh sửa cuối:
Tôi test thấy có vài trường hợp như trong file.

Như tôi đã nói ở bài #11: cắt thanh là bài toán khó. Và nếu không chứng minh chặt chẽ được về mặt toán học là thuật toán chắc chắn tối ưu thì mãi mãi nó chỉ là "ứng viên" mà thôi.
Có thể với tập dữ liệu này thì thuật toán "này" tối ưu hơn thuật toán "kia" nhưng rất có thể với tập dữ liệu khác thì thuật toán "kia" lại tối ưu hơn.

Để chứng tỏ là có thể sẩy ra thế thì tôi đưa ra ví dụ.

1. Với dữ liệu ở bài #10 thì code của bạn dùng 9 thanh trong khi code của tôi dùng 10 thanh.

2. Với dữ liệu trong tập tin đính kèm thì code của bạn dùng 10 thanh trong khi code của tôi dùng 9 thanh.

Ở hình dưới đây thì kết quả mầu đỏ do code cat_cat_cat trả về. Kết quà ở phía trên do code CThanh trả về.

View attachment 105997
 

File đính kèm

  • Toi uu hoa v1.1.xls
    79.5 KB · Đọc: 163
Như tôi đã nói ở bài #11: cắt thanh là bài toán khó. Và nếu không chứng minh chặt chẽ được về mặt toán học là thuật toán chắc chắn tối ưu thì mãi mãi nó chỉ là "ứng viên" mà thôi.
Có thể với tập dữ liệu này thì thuật toán "này" tối ưu hơn thuật toán "kia" nhưng rất có thể với tập dữ liệu khác thì thuật toán "kia" lại tối ưu hơn.

Để chứng tỏ là có thể sẩy ra thế thì tôi đưa ra ví dụ.

1. Với dữ liệu ở bài #10 thì code của bạn dùng 9 thanh trong khi code của tôi dùng 10 thanh.

2. Với dữ liệu trong tập tin đính kèm thì code của bạn dùng 10 thanh trong khi code của tôi dùng 9 thanh.

Ở hình dưới đây thì kết quả mầu đỏ do code cat_cat_cat trả về. Kết quà ở phía trên do code CThanh trả về.

View attachment 105997
Chào thày, như vậy muốn chắc ăn, ta dùng luôn cả mấy chương trình để khảo sát , cái nào tối ưu hơn thì ta thực hiện . Nhưng theo nhà em cái được lớn hơn của bài toán này là : Với tiên lượng nào đó ta nên mua loại thép có kích thước chiều dài nào là hợp lý nhất . Bởi khi thay đổi loại chiều dài của cây thép ta có thể giảm hao hụt ( nhiều khi từ mấy chục phần trăm xuống còn vài phần trăm ). Xin chào và cám ơn thày !
 
Bạn kiểm tra giúp file này tại sao bị lỗi run-time. Cám ơn!
 

File đính kèm

  • Toi uu hoa v1.1 loi run-time error'1004'.xls
    76 KB · Đọc: 19
Bạn kiểm tra giúp file này tại sao bị lỗi run-time. Cám ơn!

Bởi kết quả trả về có tới 502 cột trong khi tập tin XLS chỉ "phục vụ" tới 256 cột.

Bạn hãy ghi lại dưới dạng XLSM (Excel 2007 trở lên) --> đóng Excel --> mở lại.

Với dữ liệu như thế thì code của tôi dùng hơn code của huuthang_bd tới 2 thanh nguyên.

Nhưng nếu số lượng cắt thanh dài 2200 không phải là 1056 mà là 10, 20 hay 30 thì code của tôi dùng ít hơn code của huuthang_bd tới 2 thanh nguyên. Với số lượng 40 thì code của tôi dùng ít hơn 1 thanh nguyên. Với số lượng 50 thì 2 code dùng số thanh nguyên như nhau. Nhưng với số thanh vd. 60 thì code của tôi lại dùng nhiều thanh hơn.
 

File đính kèm

  • Toi uu hoa v1.1.xlsm
    47.1 KB · Đọc: 93
Sau khi nghiên cứu code của siwtom tôi thấy thuật toán là tại mọi thời điểm cố gắng cắt thanh dài nhất có thể. Và với thuật toán như thế có những trường hợp mà tỷ lệ hao hụt rất cao. Như trong file tôi đính kèm. Số lượng chênh lệch giữa 2 kết quả lên đến 75 thanh. Nếu tăng số thanh cần cắt lên nữa thì chênh lệch càng tăng cao.
 

File đính kèm

  • Toi uu hoa v1.1.rar
    92.8 KB · Đọc: 174
Cảm ơn anh Siwtom và bạn Huuthang-BD
Em làm xây dựng có quan tâm nhiều đến việc cắt thanh tối ưu cho thanh có độ dài 11700 mm
Trước thì làm thủ công cứ cắt thanh dài trước ngắn sau sao cho đầu thừa là ngắn nhất
kết luận là đầu thừa khi đoạn đó có chiều dài nhỏ hơn chiều dài của thanh nhỏ nhất cần cắt
để tiết kiệm hơn thì em có tính đến một sai số cho phép
Ví dụ thanh 6450 là em cho vào loại thanh 6500 được
Việc sai số này Giám sát bỏ qua luôn
Em có phền mềm dùng thử nhưng xem giao diện không thân thiện lắm các anh có thể tham khảo
Em thấy đề tài này không hề nhỏ
ngoài tổ hợp được thanh cần cắt ra còn phải xuất thành hình minh họa để công nhân có thể đọc và hiểu được
Trên hình vẽ thể hiện được chiều dài thanh nguyên 11700mm cần cắt ở vị trí nào được thanh số mấy và chiều dài thanh,
 

File đính kèm

  • Cut thep.rar
    1.9 MB · Đọc: 553
Lần chỉnh sửa cuối:
Đây là bài toán tối ưu, đối với việc cắt thanh thép, do đó tôi nghĩ ngay đến việc dùng Solver trong excel. Mọi người tham khảo theo file đính kèm. Tôi nghĩ dùng Solver khá đơn giản, gọn nhẹ và có nhiều tùy chọn (về sai số, thêm bớt điều kiện) mà bài toán được giải khá tốt.
 

File đính kèm

  • Solver_Toi uu cat thanh.zip
    39.4 KB · Đọc: 331
Lần chỉnh sửa cuối:
Sau khi nghiên cứu code của siwtom tôi thấy thuật toán là tại mọi thời điểm cố gắng cắt thanh dài nhất có thể. Và với thuật toán như thế có những trường hợp mà tỷ lệ hao hụt rất cao. Như trong file tôi đính kèm. Số lượng chênh lệch giữa 2 kết quả lên đến 75 thanh. Nếu tăng số thanh cần cắt lên nữa thì chênh lệch càng tăng cao.

Tôi cũng biết điều này vì thế ngay bài #1 tôi cũng nói là chỉ là 1 cách cắt.
Tôi cũng nói là bài toán rất khó.
Mục đích tôi muốn nói chỉ là nếu không thể chứng minh được về mặt toán học là tối ưu thì mãi mãi cách cắt chỉ là "ứng cử viên" cách cách tối ưu thôi.
Code của tôi dùng chỉ để có cái mà so sánh, để thấy là có cách cắt kém hơn và có cách cắt tốt hơn code của bạn, với mục đích chỉ ra là code không tối ưu trong mọi trường hợp. Chỉ thế thôi chứ tôi không có ý định tranh đua về code. Chỉ có điều là nếu tôi ý thức được là không có code nào luôn tối ưu thì mỗi khi có trường hợp cụ thể thì tôi sẽ chạy tất cả - của bạn, của tôi, và của những người khác - rồi chọn kết quả tốt nhất trong chúng. Chuyện code nào được dùng "thường xuyên" hơn thì là chuyện không có ý nghĩa gì đối với người cắt thép. Anh ta chỉ cần cắt tốt nhất có thể mà thôi.
 
Web KT
Back
Top Bottom