Tiện ích tính toán để tiết kiệm khi cắt tấm, cắt thanh. (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

huuthang_bd

Chuyên gia GPE
Tham gia
10/9/08
Bài viết
8,933
Được thích
11,357
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

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

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

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

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

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

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

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!

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

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

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

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

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.
 
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.

Thật thú vị khi em test cách của em tại bài #4 (một bạn nào đó đưa lên lại) cho kết quả giống của anh tại bài 11, cách của bạn huuthang_bd mình chưa test được vì không hiểu sao lại báo lỗi.
Trước đây mình chỉ cắt tuần tự nên hao hụt có thể xảy ra lớn.

Đúng là rất khó, em đã đầu tư thời gian để tạo ra cách sau đây, mà em nghĩ là đã tối ưu.
Chứng minh:
- Liệt kê tất cả các "tổ hợp" có thể xảy ra và kích thước của chúng căn cứ vào chiều dài thanh nguyên liệu và thanh nhỏ nhất cần cắt. Ví dụ từ thanh nguyên 3000, ta phải cắt hai loại a và b, kích thước loại nhỏ là 950, vậy một thanh nguyên có thể cắt tối đa 3 SP. Các trường hợp cắt có thể xảy ra trên một thanh nguyên là: a,b, a+b, a+a+b, a+b+b, a+a+a,b+b+b.
- Tính kích thước trong từng trường hợp và loại bỏ những trường hợp vượt quá chiều dài thanh nguyên.
- Sắp xếp tổ hợp theo kích thước của chúng.
- Xét lần lượt từ trường hợp dài nhất (tổn hao ít nhất) đến trường hợp ngắn nhất, nếu yêu cầu cắt còn thỏa mãn các loại thanh của trường hợp đó thì tiến hành cắt.

Muốn giảm hao hụt cần phải: Các thanh cần cắt và các thanh nguyên liệu phải phù hợp. Ví dụ thanh nguyên liệu là 6000 mà cắt toàn loại khỏng 3500 thì không có cách nào giảm tổn hao được.

--------------------------------------------------

Tuy nhiên cái gì cũng có giá của nó, để tính cắt tối ưu thì thời gian tính toán rất lâu, tùy thuộc vào: Cấu hình máy tính, số laoị cần cắt và tỉ lệ giữa thanh nguyên và thanh nhỏ nhất.
Với máy mình + cắt 10 loại thanh + tỉ lệ thanh nguyên/thanh cắt min = 6000/480 thì thời gian tình toán xấp xỉ 1 phút (phải xét gần 100.000 trường hợp).
Thới gian tính có lẽ tăng theo lũy thừa của 2, ví dụ: 10 loại 2 phút thì 11 loại là 4 phút, 12 loại 8 phút.

Mình gởi file để các bạn tham khảo, vì là bản "dùng thử" nên số loại cắt tối đa cho phép là 260 loại. Hi hi, như phân tích ở trên thì nếu cắt đủ 260 loại thì hãy bật náy lên, đi chơi một tuần về coi thử tính xong chưa, mà có lẽ cũng không được vì lỗi tràn bộ nhớ. Bản thân mình test có 10 loại mà test đi test lại quá mất thời gian. Code trong file chưa được khai báo đầy đủ kiểu biến và giải phóng biến.
 

File đính kèm

Thật thú vị khi em test cách của em tại bài #4 (một bạn nào đó đưa lên lại) cho kết quả giống của anh tại bài 11, cách của bạn huuthang_bd mình chưa test được vì không hiểu sao lại báo lỗi.
Trước đây mình chỉ cắt tuần tự nên hao hụt có thể xảy ra lớn.

Đúng là rất khó, em đã đầu tư thời gian để tạo ra cách sau đây, mà em nghĩ là đã tối ưu.
Chứng minh:
- Liệt kê tất cả các "tổ hợp" có thể xảy ra và kích thước của chúng căn cứ vào chiều dài thanh nguyên liệu và thanh nhỏ nhất cần cắt. Ví dụ từ thanh nguyên 3000, ta phải cắt hai loại a và b, kích thước loại nhỏ là 950, vậy một thanh nguyên có thể cắt tối đa 3 SP. Các trường hợp cắt có thể xảy ra trên một thanh nguyên là: a,b, a+b, a+a+b, a+b+b, a+a+a,b+b+b.
- Tính kích thước trong từng trường hợp và loại bỏ những trường hợp vượt quá chiều dài thanh nguyên.
- Sắp xếp tổ hợp theo kích thước của chúng.
- Xét lần lượt từ trường hợp dài nhất (tổn hao ít nhất) đến trường hợp ngắn nhất, nếu yêu cầu cắt còn thỏa mãn các loại thanh của trường hợp đó thì tiến hành cắt.

Muốn giảm hao hụt cần phải: Các thanh cần cắt và các thanh nguyên liệu phải phù hợp. Ví dụ thanh nguyên liệu là 6000 mà cắt toàn loại khỏng 3500 thì không có cách nào giảm tổn hao được.

--------------------------------------------------

Tuy nhiên cái gì cũng có giá của nó, để tính cắt tối ưu thì thời gian tính toán rất lâu, tùy thuộc vào: Cấu hình máy tính, số laoị cần cắt và tỉ lệ giữa thanh nguyên và thanh nhỏ nhất.
Với máy mình + cắt 10 loại thanh + tỉ lệ thanh nguyên/thanh cắt min = 6000/480 thì thời gian tình toán xấp xỉ 1 phút (phải xét gần 100.000 trường hợp).
Thới gian tính có lẽ tăng theo lũy thừa của 2, ví dụ: 10 loại 2 phút thì 11 loại là 4 phút, 12 loại 8 phút.

Mình gởi file để các bạn tham khảo, vì là bản "dùng thử" nên số loại cắt tối đa cho phép là 260 loại. Hi hi, như phân tích ở trên thì nếu cắt đủ 260 loại thì hãy bật náy lên, đi chơi một tuần về coi thử tính xong chưa, mà có lẽ cũng không được vì lỗi tràn bộ nhớ. Bản thân mình test có 10 loại mà test đi test lại quá mất thời gian. Code trong file chưa được khai báo đầy đủ kiểu biến và giải phóng biến.

Bạn thử cắt 30 thanh kích thước 3999 (a) và 30 thanh kích thước 2000 (b) với kích thước nguyên liệu là 6000 xem.

Kết quả hợp lý nhất là kết hợp 1 thanh (a) với 1 thanh (b) tổng cộng sử dụng 30 thanh nguyên liệu.

Code của bạn cho kết quả là
- Kiểu 1: 1 thanh nguyên liệu cắt 3 thanh (b) => 10 thanh nguyên liệu cắt 30 thanh (b)
- Kiểu 2: 1 thanh nguyên liệu cắt 1 thanh (a) => 30 thanh nguyên liệu cắt 30 thanh (a)
Tổng cộng sử dụng 40 thanh nguyên liệu.
 
Bạn thử cắt 30 thanh kích thước 3999 (a) và 30 thanh kích thước 2000 (b) với kích thước nguyên liệu là 6000 xem.

Kết quả hợp lý nhất là kết hợp 1 thanh (a) với 1 thanh (b) tổng cộng sử dụng 30 thanh nguyên liệu.

Code của bạn cho kết quả là
- Kiểu 1: 1 thanh nguyên liệu cắt 3 thanh (b) => 10 thanh nguyên liệu cắt 30 thanh (b)
- Kiểu 2: 1 thanh nguyên liệu cắt 1 thanh (a) => 30 thanh nguyên liệu cắt 30 thanh (a)
Tổng cộng sử dụng 40 thanh nguyên liệu.
Ok, cảm ơn bạn, mình sẽ kiểm tra lại điều kiện chọn cây mới.
 
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.
Gửi bạn huuthang_bd,

Bài này thiếu mất code CTam (Cắt tấm), tui tải mấy file đính kèm mà không thấy, bạn cập nhật dùm nhé.

Cảm ơn.
 
Đọc sách đừng đọc mỗi trang cuối.
 
Đọc sách đừng đọc mỗi trang cuối.
Gửi huuthang_bd,
Thành thật xin lỗi vì file đầu tiên tải xuống, tui sử dụng chưa đúng nên bị lỗi (Khuôn 1220x2440, Mẫu 250x350) mà không kiểm tra code CTam. Các file từ bài 13, 16, 17 không có code này. Vì bài 17 cập nhật ngày 22/07, muộn hơn bài 1 cập nhật 17/07 nên tui không kiểm tra lại code trong bài 1. Tui đọc và tải ít nhất 6 file các bài trong topic này trước khi gửi bài 27.
Cảm ơn huuthang_bd đã nhắc nhở và cảm ơn vì bài viết hữu ích này.
 
Chào bạn , tôi có 1 bài toán cắt thép tối ưu, muốn nhờ bạn giải giúp như sau
Hiện trong kho có các loại thép thanh 6000,6500,7000,7500,8000,8500,9000,9500,10000,10500,11000,11500,12000
với số lượng và các kích thước cần cắt có sẵn (file đính kèm). tìm số lượng thanh thép cần dùng (có thể phối hợp 3-4 loại thép ở trên). THANKS
 

File đính kèm

Chào các bạn , tôi có 1 bài toán cắt thép tối ưu, muốn nhờ bạn giải giúp như sau
Hiện trong kho có các loại thép thanh 6000,6500,7000,7500,8000,8500,9000,9500,10000,1050 0,11000,11500,12000
với số lượng và các kích thước cần cắt có sẵn (file đính kèm). tìm số lượng thanh thép cần dùng (có thể phối hợp 3-4 loại thép ở trên). THANKS
 

File đính kèm

cho mình hỏi vì sao khi bấm "run" thì nó bị lỗi này@#!^%
 

File đính kèm

  • Untitled.jpg
    Untitled.jpg
    29 KB · Đọc: 87
Với SHEET tấm mình nhập thông số đầu vào là: Tấm có kuch thước (tính theo mm) 6.000, 12.000 và tấm muốn chia có kích thước là 200, 350 thì bị lỗi. Bạn check lại xem
 
Sao lại chia cho 50 làm gì mà mình chưa hiểu con số nàt lắm?
 
Sao lại chia cho 50 làm gì mà mình chưa hiểu con số nàt lắm?
Code vẽ kết quả trên sheet với mỗi đơn vị là 1 ô nên nếu chiều rộng lớn hơn số cột của Excel sẽ không đủ chỗ vẽ và bị lỗi. 50 là ước số chung lớn nhất của các số, chia ra để giảm kích thước, lúc này 1 ô tương đương với 50 đơn vị.
 
huuthang_bd đã viết:
Sao tôi thử một vài trường hợp mà không nhận được trường hợp theo CÁCH XẾP UT DÀI?
Liệu cách xếp UT Rong và UT Dai có bản chất thuật toán giống nhau?
 
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.
cái này muốn thêm phần nhôm bị cắt đi do lưỡi cắt từ 10-20mm thì thêm vào chỗ nào trong đoạn mã vậy b
 
Bạn cộng các kích thước cho độ rộng vết cắt là xong.test.png
ý b là cộng kích thước mạch cắt vào luôn chỗ kích thước này à, e muốn nó cộng trong đoạn code để cái số ko đổi hoặc b có thể làm thêm 1 ô " trừ mạch cắt" vì thực tế cây 5m ko thể cắt đc thành 2 đoạn 3500 và 1500 được
b xem giúp e, cám ơn b
 
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.
thêm một điều kiện nữa không thầy số loại trên một cột chạy ra ít nhất không thầy?
 
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.
Bác ạ, món này có cải tiến gì so với ngày xưa không ạ?

Hiện có điều chỉnh tí tẹo là em phải lưu lại xlsm vì yêu cầu kết quả nhiều hơn số lượng cột hạn hẹp của dạng .xls.
 
món này khó đấy bác, mình ngâm cứu 4 năm nay mà chưa ra
nhưng theo đuổi cũng ngộ đc nhiều điều !
xứng đang là mục tiêu dài hạn !

Trên youtube cũng có 1 vài thuật giải về quy hoạch rời rạc của bác Bùi Thế Tâm có thể tham khảo !
1 số đề tài TS trong nước cũng có đề cập như kỹ thuật tạo sinh cột !
nói chung thế giới vẫn nghiên cứu , chưa có cách nào tối ưu nhất bác ạ

về công cụ thì có thể liệt kê các lát cắt, dùng solver của Excel tính cũng ra, nhưng giới hạn vài chục mẫu thôi !

nếu bác có cùng đam mê thì follow thớt này để update thông tin ^^

https://en.wikipedia.org/wiki/Cutting_stock_problem#:~:text=In operations research, the cutting,arises from applications in industry.

1698409453839.png
 
Lần chỉnh sửa cuối:
Ồ, nếu theo mẫu thử trong link này thì cắt 73 đoạn thì tối ưu nhất, nhưng lại không có thuật toán.
1698418839777.png
Code bác Thắng suýt soát 74, của bác siwtom, thanhlanh thì 82, của phần mềm khác là 75.

Như thế thì có con đường tắt để tối ưu, nhưng chắc khó. :wallbash: :wallbash: :wallbash:
 
Link trên tổng cộng 219 thanh con, mình cố lắm được 45 thanh con ah`
1699077449757.png

40
1699081723586.png

cũng có trường hợp nhiều hơn nhưng vẫn hội tụ khá nhanh !
1699024976805.png

nói chung mình vẫn trong quá trình nghiên cứu ^^
mục tiêu 219 thanh con vẫn quá xa @@
 
Lần chỉnh sửa cuối:
tổng cộng 219 thanh con, mình cố lắm được 45 thanh con
Tớ không hiểu lắm. 45 thanh kia nghĩa là tương ứng sẽ có 15 kiểu cắt ấy hả?
Chỉ cần 2x, 3x, 4x, ... hoặc nx với lần lượt 15 thanh là ra? Và đảm bảo cộng 2x, 3x, 4x, ... hoặc nx = 73 hả?

Còn bảng số liệu với 4520 là số lượng từng thanh bao nhiêu nhỉ?
Để tớ test với code của các bác xem tối ưu là bao nhiêu thanh?
 
Tớ không hiểu lắm. 45 thanh kia nghĩa là tương ứng sẽ có 15 kiểu cắt ấy hả?
Chỉ cần 2x, 3x, 4x, ... hoặc nx với lần lượt 15 thanh là ra? Và đảm bảo cộng 2x, 3x, 4x, ... hoặc nx = 73 hả?
ví dụ trong Link vì kết quả quá dài , 73 thanh, nên họ gộp những thanh giống nhau lại , mất 73 thanh để cắt 219 thanh con
trong hình mình liệt kê từng thanh cho nó ấn tượng thôi , 45 thanh con sẽ dùng hết 15 thanh dài

Còn bảng số liệu với 4520 là số lượng từng thanh bao nhiêu nhỉ?

bác thử !
463​
16​
467​
8​
473​
4​
475​
8​
479​
4​
555​
4​
713​
4​
1183​
8​
1276​
16​


Để tớ test với code của các bác xem tối ưu là bao nhiêu thanh?
hiện tại khả năng của code chỉ hiệu quả trong vòng 50 thanh con đổ lại cho mọi trường hợp (mình đoán thế ) !
50 -> 70 tính toán hơi chậm !
70 -> 100 cho vài trường hợp đặc biệt !
chắc 1 2 năm nữa mới có thêm chút tiến bộ @@

1699201710669.png

13805
15205
15605
17105
18205
18805
19305
20005
20505
21005
21405
21505
22004
Sum64
Số thanh cần22

ví dụ mở rộng thêm mẫu cắt !
1699202873247.png
13802
15202
15602
17102
18202
18802
19302
20002
20502
21002
21402
21502
22002
13502
15502
15502
17502
18502
18502
19502
23501
20701
23501
21901
21801
22501
Sum46
Số thanh cần16

phần phế phẩm nhiều , nhưng hok thể tối ưu hơn !
1699204133085.png

13802
15202
15603
17104
18205
18806
19307
20001
20502
21003
21404
21505
22006
Sum50
Số thanh cấn19
 
Lần chỉnh sửa cuối:
Đáp số 4520 nè:

SLL1L2L3L4L5L6L7L8
4​
1276​
1276​
555​
479​
467​
467​
2​
1276​
463​
463​
463​
463​
463​
463​
463​
1​
713​
713​
713​
475​
475​
475​
475​
475​
1​
1183​
1183​
713​
475​
475​
475​
2​
1183​
1183​
1183​
473​
473​
2​
1276​
1276​
1276​
463​
 
Lần chỉnh sửa cuối:
dùng 12 thanh là đáp án đúng rùi ák, phần mềm Cutting Optimization cũng nhiêu đó thui !
bác test thử mẫu này !
độ khó cũng trung bình,
kết quả dài quá mình đính kèm Excel ^^

1699251728102.png
 

File đính kèm

dùng 12 thanh là đáp án đúng rùi ák, phần mềm Cutting Optimization cũng nhiêu đó thui !
bác test thử mẫu này !
độ khó cũng trung bình,
kết quả dài quá mình đính kèm Excel ^^

View attachment 296462
Code trong chủ đề này vẫn ra được 39 thanh đấy.
Mà ứng dụng của bạn đẹp đấy, rất dễ nhìn. Nếu thêm tùy biến các thanh giống nhau ghép lại thì đẹp.
Solver excel nó cũng kém, đổi vị trí kiểu cắt ra trước hoặc sau là kết quả nó nhảy lung tung luôn.
Và để tối ưu nhất chắc là chấp nhận hụt vài thanh trong ngân sách cho phép.
 
thanks bác đã hỗ trợ test
bác test dùm e thêm mẫu bên dưới giúp nha (có file đính kèm) !
View attachment 296524
Các code đều cho ra 13 hết. Thường thì có nhiều đoạn nhỏ sẽ tương đối tiết kiệm.

Còn code lượm trên mạng nhưng tính từ bảng thống kê thép rồi chạy ra luôn mà tớ chưa mò sửa được. Hehe.
Bài toán tối ưu thép biến thành bài toán sưu tầm code. Khi nào ổn nhớ share lên nghen. --=0 --=0 --=0
1:
1​
2x1276 + 1x555 + 1x479 + 2x467
2​
2x1276 + 1x555 + 1x479 + 2x467
3​
2x1276 + 1x555 + 1x479 + 2x467
4​
2x1276 + 1x555 + 1x479 + 2x467
5​
1x1276 + 7x463
6​
1x1276 + 1x463 + 6x463
7​
3x713 + 5x475
8​
2x1183 + 1x713 + 3x475
9​
2x1183 + 1x1183 + 2x473
10​
3x1183 + 2x473
11​
3x1276 + 1x473
12​
3x1276 + 1x463
13​
1x463

2:
1​
3x1276 + 1x555
2​
3x1276 + 1x555
3​
2x1276 + 1x1276 + 1x555
4​
3x1276 + 1x555
5​
3x1276 + 1x479
6​
1x1276 + 2x1183 + 1x713
7​
2x1183 + 1x1183 + 1x713
8​
3x1183 + 1x713
9​
1x713 + 3x479 + 4x475 + 1x467
10​
4x475 + 5x473
11​
7x467 + 2x463
12​
6x463 + 3x463
13​
5x463
 
Các code đều cho ra 13 hết
Test như vậy thì sao mà ra được vấn đề. Ngoài số lượng thanh nguyên sử dụng còn xét đến các thanh thừa nữa. Ví dụ ở phương án 1 thanh thứ 13 chỉ mới cắt 1 thanh 463, còn dư 4057. Vậy nếu bớt 1 thanh 463 ở số lượng thanh còn cắt thì phương án 1 chỉ còn dùng 12 thanh nguyên, các phương án khác có bớt được 1 thanh nguyên như vậy không. Hoặc cần cắt thêm 3 thanh 1276 thì phương án 1 vẫn chỉ dùng 13 thanh, các phương án khác có thể cắt với 13 thanh như vậy không.
 
Test như vậy thì sao mà ra được vấn đề. Ngoài số lượng thanh nguyên sử dụng còn xét đến các thanh thừa nữa. Ví dụ ở phương án 1 thanh thứ 13 chỉ mới cắt 1 thanh 463, còn dư 4057. Vậy nếu bớt 1 thanh 463 ở số lượng thanh còn cắt thì phương án 1 chỉ còn dùng 12 thanh nguyên, các phương án khác có bớt được 1 thanh nguyên như vậy không. Hoặc cần cắt thêm 3 thanh 1276 thì phương án 1 vẫn chỉ dùng 13 thanh, các phương án khác có thể cắt với 13 thanh như vậy không.
Khó lắm bác ạ, cái này chắc không tối ưu được mà sẽ có code tối ưu được hệ này nhưng lại không với hệ khác.
Em thử solver với chỉ 3 loại thanh thôi mà đổi vị trí các trường hợp là nó ra kết quả khác ngay.
Nên em nghĩ, phải chấp nhận lãng phí nếu trong giới hạn cho phép.
 
test thử bớt 1 thanh 463
thêm 3 thanh 1276
 

File đính kèm

Bài viết mới nhất

Back
Top Bottom