Author Topic: The Cutting Stock Problem (Optimizing Cutting of Rebar or Other Material)  (Read 17578 times)

0 Members and 1 Guest are viewing this topic.

pBe

  • Bull Frog
  • Posts: 402
Good stuff YMG , i recently was introduced to the cutting stock problem. i ended up using First Fit Decreasing approach

I will look into this like now-now  ;D

;; Cutting Stock Problem as per approach described in:                       
;;                                                                           
;;               A GENERALIZED APPROACH TO THE SOLUTION                     
;;                  OF ONE-DIMENSIONAL STOCK-CUTTING                         
;;                    PROBLEM FOR SMALL SHIPYARDS.                           
;;              by Ahmet Cemil Dikili and Baris Barlas                       
;;                                                                           
;; Link:  http://jmst.ntou.edu.tw/marine/19-4/368-376.pdf                   

Thank you for the linky.  ;D

andy_lee

  • Newt
  • Posts: 147
emk2012,

You supply  list L, Length of bars needed.
You also supply list D, How many of each length are required.
You also give LS which is the length of the long bar from which
the smaller lengths are going to be cut.

The program then cut all the pieces, using two different methods
in order to minimize the waste.

Output is a set of cut patterns:

Thanks ymg, you did a good job.
andy.
Best regards.

ymg

  • Guest
pBe,

As I told before, you have to be careful with Dikili & Barlas
and compared with FFD-binpack.

I now have an Evolutionnary Programming solution, which shows
great promises.

Will publish once I figure the best way to stop generating solutions.
This is highly problem dependant but I seem to converge to good
solution within 500 generations.

Could also stop if solution fitness does not improve during, say, 50 generations.

Stay tuned!

ymg

pBe

  • Bull Frog
  • Posts: 402
.... I now have an Evolutionnary Programming solution, which shows
great promises......

Stay tuned!

ymg

That i will.  :)

ymg

  • Guest
Here is an implementation of the Evolutionnary Programming solution
to the Cutting Stock Problem as described in the following paper:

   A New Evolutionary Approach to Cutting Stock Problems With and Without Contiguity
   By: Ko-Hsin Liang, Xin Yao, Charles Newton, David Hoffman

This is again a text screen application.
I run it in the VLIDE editor.

Here is the code:
Code - Auto/Visual Lisp: [Select]
  1. ;;                       Example Problems                                     ;
  2. ;; From:                                                                      ;
  3. ;; Genetic algorithms for cutting stock problems: with and without contiguity ;
  4. ;;      by Hinterding R, Khan L.                                              ;
  5. ;;                                                                            ;
  6. ;;   http://vuir.vu.edu.au/25789/1/TECHNICALREPORT40_compressed.pdf           ;
  7. ;;                                                                            ;
  8.  
  9. (setq prob1ato5a
  10. '(("Problem 1a. Stock length 14 (20 items)                                  \n"
  11.   (3 4 5 6 7 8 9 10)
  12.   (5 2 1 2 4 2 1 3)
  13.   14)
  14.   ("Problem 2a  (50 items)                                                  \n"
  15.   (3 4 5 6 7 8 9 10)
  16.   (4 8 5 7 8 5 5 8)
  17.   15)
  18.   ("Problem 3a. Stock length 25 (60 items)                                  \n"
  19.   (3 4 5 6 7 8 9 10)
  20.   (6 12 6 5 15 6 4 6)
  21.   25)
  22.   ("Problem 4a. Stock length 25 (60 items)                                  \n"
  23.   (5 6 7 8 9 10 11 12)
  24.   (7 12 15 7 4 6 8 1)
  25.   25)
  26.   ("Problem 5a. Stock length 4300 (126 items)                               \n"
  27.   (2350 2250 2200 2100 2050 2000 1950 1900 1850 1700 1650 1350 1300 1250 1200 1150 1100 1050)
  28.   (2 4 4 15 6 11 6 15 13 5 2 9 3 6 10 4 8 3)
  29.   4300))
  30.   prob6a    
  31.   '(("Problem 6a. Stock length 86 (200 items)                                 \n"
  32.   (21 23 24 25 26 27 28 29 31 33 34 35 37 38 41 42 44 47)
  33.   (10 14 10 7 14 4 13 9 5 10 13 10 11 15 12 15 15 13)
  34.   86))
  35.   prob7a    
  36.   '(("Problem 7a. Stock length 120 (200 items)                                \n"
  37.   (22 26 27 28 29 30 31 32 34 36 37 38 39 46 47 48 52 53 54 56 58 60 63 64)
  38.   (6 3 14 12 9 15 11 10 11 13 4 3 6 14 7 3 14 9 7 3 5 14 4 3)
  39.   120))
  40.   prob8a    
  41.   '(("Problem 8a. Stock length 120 (400 items)                                \n"
  42.   (22 23 24 26 27 28 29 30 31 36 39 41 42 48 49 50 51 54 55 56 59 60 66 67)
  43.   (12 8 27 15 25 7 10 22 5 16 19 21 26 16 12 26 20 25 9 17 22 14 17 9)
  44.   120))
  45.   prob9a    
  46.   '(("Problem 9a. Stock length 120 (400 items)                                \n"
  47.   (21 22 24 25 27 29 30 31 32 33 34 35 38 39 42 44 45 46 47 48 49 50 51 52 53 54 55 56 57 59 60 61 63 65 66 67)
  48.   (13 15 7 5 9 9 3 15 18 17 4 17 20 9 4 19 9 12 15 3 20 14 15 6 4 7 5 19 19 6 3 7 20 5 10 17)
  49.   120))
  50.   prob10a    
  51.   '(("Problem 10a. Stock length 120 (600 items)                               \n"
  52.   (21 22 23 24 25 27 28 29 30 31 33 35 36 39 40 41 42 43 44 45 46 47 48 50 51 54 56 57 58 61 62 63 64 65 66 67)
  53.   (13 19 24 20 23 24 15 5 24 16 12 24 16 4 20 24 6 14 21 20 24 2 11 26 23 25 8 16 10 14 6 19 18 11 27 16)
  54.   120))
  55. )
  56.  
  57.  
  58. ;; EP-Cut              by ymg                                                 ;
  59. ;;                                                                            ;
  60. ;;        A New Evolutionary Approach to Cutting Stock Problems               ;
  61. ;;                  With and Without Contiguity                               ;
  62. ;;       By: Ko-Hsin Liang, Xin Yao, Charles Newton, David Hoffman          ;
  63. ;;  https://www.cs.bham.ac.uk/~xin/papers/COR_LiangYaoNewtonHoffman.pdf       ;
  64. ;;                                                                            ;
  65. ;; Contiguity is not implemented yet in the following                         ;
  66. ;;                                                                            ;
  67.  
  68. (defun c:EP-Cut (/ a b bc c cost d gmul graf i k l ls mn mu mx n n3ps ngen opp
  69.                    popu popuc prob  probc s st stid stidc stoc sz ti tit tsiz vexg w win)
  70.  
  71.             ; Notes that variables bsol, bcost, bstoc, sol, costc and stocc   ;
  72.             ; are not declared so that we can inspect other solutions.        ;
  73.             ; Sample problems also will need to bet to nil manually           ;
  74.  
  75.                  
  76.    (setq   mu 75             ; Size of Population                             ;
  77.          tsiz 10             ; Tournament Size (Number of Opponents)          ;
  78.          gmul 20             ; Multiplier for Nunber of Generation to Run     ;
  79.          n3ps  2             ; Number of 3PS Repetitions to Creates Offspring ;
  80.    )                        
  81.    (foreach pr prob1ato5a
  82.       (setq popu nil)
  83.       (setq ti (car (_vl-times)))
  84.       (setq tit (car   pr)
  85.               l (cadr  pr)
  86.               d (caddr pr)
  87.              ls (last  pr)
  88.       )
  89.       (setq popu (list (longlst l d)); Adding Ordered List eq. to FFD-binpack ;
  90.                n (length (car popu)) ; Nomber of Items to Cut                 ;
  91.             ngen (* gmul n)          ; Number of Generations to Run           ;
  92.             vexg (/ ngen 1.6)        ; Vertical Exageration for Graph         ;
  93.       )
  94.       (repeat (1- mu)
  95.          (setq popu (cons  (shuffle (car popu)) popu))
  96.       )
  97.       ; popu, Population                                                      ;
  98.       ; stoc, Population Decoded by First Fit Binpack                         ;
  99.       ; stid, Indices to popu to End of a Cut Stock                           ;
  100.       ; cost, Relative Cost of Each Individual                                ;
  101.       ; prob, Probability of Selecting a Given Stock for Mutations            ;
  102.      
  103.       (setq popu (reverse popu)
  104.             stoc (mapcar '(lambda (a) (ff-binpack a ls)) popu)
  105.             stid (mapcar '(lambda (a) (setq st -1) (mapcar '(lambda (a) (setq st (+ st (length (car a))))) a)) stoc)
  106.             cost (mapcar 'relcost  stoc)
  107.             prob (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stoc)
  108.                k 0
  109.       )
  110.       (setq    bc (apply 'min cost)
  111.             bstoc stoc
  112.             bcost cost
  113.              graf (list (list 0 (* vexg bc)))
  114.       )
  115.       (princ (strcat "\nEP-Cut - " tit ))
  116.       (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos bc 2 6)))
  117.      
  118.       ; Each Idividual in Population is Mutated by 3 Point Swap (3PS)         ;
  119.       (repeat ngen
  120.          (setq i 0 popuc nil)
  121.          (foreach ind popu
  122.             (repeat n3ps
  123.                (setq a (fix (* (rand) n))
  124.                      s (roulette (nth i prob))
  125.                     mx (nth s (nth i stid))
  126.                     mn (if (zerop s) 0 (+ (nth (1- s) (nth i stid)) 1))
  127.                      b (randrng mn mx)    
  128.                      s (roulette (nth i prob))
  129.                     mx (nth s (nth i stid))
  130.                     mn (if (zerop s) 0 (+ (nth (1- s) (nth i stid)) 1))
  131.                      c (randrng mn mx)    
  132.                    ind (swapnth a b ind)
  133.                    ind (swapnth a c ind)
  134.                )
  135.             )
  136.             (setq popuc (cons ind popuc)
  137.                   i (1+ i)
  138.             )      
  139.          )
  140.          (setq popuc (reverse popuc)
  141.                stocc (mapcar '(lambda (a) (ff-binpack a ls)) popuc)
  142.                stidc (mapcar '(lambda (a) (setq st -1) (mapcar '(lambda (a) (setq st (+ st (length (car a))))) a)) stocc)
  143.                costc (mapcar 'relcost  stocc)
  144.                probc (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stocc)
  145.                popuc (append popu popuc)
  146.                stocc (append stoc stocc)
  147.                stidc (append stid stidc)
  148.                costc (append cost costc)
  149.                probc (append prob probc)
  150.          )
  151.      
  152.          ; Conduct Comparisons Over the Union of Parents and Offspring        ;
  153.          ; Tournament Size is Defined at Beginning of Proram                  ;
  154.        
  155.          (setq i 0  sz (length costc) win nil)
  156.          (foreach c costc
  157.             (setq w 0)
  158.             (repeat tsiz
  159.                (while (= i (setq opp (fix (* (rand) sz)))))
  160.                (if (<= c (nth opp costc)) (setq w (1+ w)))
  161.             )
  162.             (setq win (cons w win)
  163.                     i (1+ i)
  164.             )      
  165.          )
  166.          (setq win (reverse win))
  167.            
  168.          ; Choose the Solution With Most Win for New Generation               ;
  169.        
  170.          (setq win (vl-sort-i win '>))
  171.          (setq popu nil stoc nil stid nil cost nil prob nil)       
  172.          (repeat mu
  173.             (setq    i (car win)  win (cdr win)
  174.                   popu (cons (nth i popuc) popu)
  175.                   stoc (cons (nth i stocc) stoc)
  176.                   stid (cons (nth i stidc) stid)
  177.                   cost (cons (nth i costc) cost)
  178.                   prob (cons (nth i probc) prob)
  179.             )
  180.          )
  181.          (setq popu (reverse popu)
  182.                stoc (reverse stoc)
  183.                stid (reverse stid)       
  184.                cost (reverse cost)
  185.                prob (reverse prob)       
  186.                   k (1+ k)
  187.         )
  188.         (setq    b (apply 'min costc)
  189.               graf (cons (list k (* vexg b)) graf)
  190.         )            
  191.         (if (< b bc)
  192.            (progn
  193.              (setq bc b bstoc stocc bcost costc)
  194.              (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos (apply 'min cost) 2 6)))            
  195.            )
  196.         )  
  197.      )
  198.      ; Order of the last 150 solutions in stocc                               ;
  199.      (setq sol (vl-sort-i bcost '<))  
  200.      (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos (apply 'min cost) 2 6)))
  201.      (princ (strcat "\n    EP-Cut - Elapsed time: " (rtos (/ (- (car (_vl-times)) ti) 1000.) 2 4) " secs. \n" ))
  202.      
  203.      
  204.      ; Here I am sorting all bins of the best solutions and outputting        ;
  205.      (setq bsol (mapcar '(lambda (a) (list (mapcar '(lambda (b) (nth b (car a))) (vl-sort-i (car a) '>)) (cadr a))) (nth (car sol) bstoc)))
  206.      (printres (strcat "EP-Cut - " tit) l d ls (distinct# bsol))
  207.      
  208.      ; Output the graph of Generations vs Cost for Debugging and Finding Best ;
  209.      ; way to stop the algorithm.                                             ;
  210.      (mk_lwp (reverse graf))          
  211.    ) ; Go to Next Problem    ;
  212.    (princ)
  213. )
  214.  
  215.  
  216. ;; longlst                                                                    ;
  217. ;; Expand a list of length and quantity to a                                  ;
  218. ;; Sorted long list with repeating items                                      ;
  219. ;;                                                                            ;
  220.  
  221. (defun longlst (l d / i j ll)
  222.   (setq j 0)
  223.   (foreach i d
  224.      (repeat i (setq ll (cons (nth j l) ll)))
  225.      (setq j (1+ j))
  226.   )
  227.   (mapcar '(lambda (a) (nth a ll)) (vl-sort-i ll '>))
  228. )
  229.  
  230.  
  231. ;; FF-binpack          by ymg                                                 ;
  232. ;; First Fit                                                                  ;
  233. ;; Arguments: l  List of items to put in bins                                 ;
  234. ;;            c  Capacity of a bin                                            ;
  235. ;;                                                                            ;
  236.  
  237. (defun FF-binpack (l c / i b tb)
  238.    (setq r nil)
  239.    (while l
  240.       (setq w ls b nil)
  241.       (while (and l (>= w (setq i (car l))))
  242.          (setq b (cons i b)
  243.                w (- w i)
  244.                l (cdr l)
  245.          )
  246.       )
  247.       (setq r (cons (list (reverse b) w) r))
  248.    )
  249.    (reverse r)
  250. )
  251.  
  252.  
  253. ;; Random number generator, #s(eed) remains Global.                           ;
  254.  
  255. (defun rand (/ x)
  256.    (/ (setq x 4294967296.0 #s (rem (1+ (* 1664525.0 (cond (#s) ((getvar 'DATE))))) x)) x)
  257. )
  258.  
  259. ;; Random in range i j  (Integer Range)                                       ;
  260.  
  261. (defun randrng (i j) (+ i (fix (* (rand) (- j i -1)))))
  262.  
  263. ;; roulette      by ymg                                                       ;
  264. ;;                                                                            ;
  265. ;; Roulette-Wheel Selection Via Stochastic Acceptance                         ;
  266. ;;    by Adam Lipowski and Dorota Lipowska                                    ;
  267. ;;          http://arxiv.org/pdf/1109.3627v2.pdf                              ;
  268. ;;                                                                            ;
  269. ;; Argument: l   List of Probabilities. (No need to normalize)                ;
  270. ;; Returns : Index in List of Chosen Item According to Probabilities.         ;
  271. ;;                                                                            ;
  272.  
  273. (defun roulette (l / k m n)
  274.    (setq  m (float (apply 'max l)) n (length l))
  275.    (while (> (rand) (/ (nth (setq k (fix (* (rand) n))) l) m)))
  276.    k
  277. )
  278.  
  279. ;; For Debugging Check Frquency of Returns of Roulette's Function             ;
  280. (defun checkroulette (/ l p r c0 c1 c2 c3 c4)
  281.    (setq l '((0.4 0.0 0.3 1.2 0.1)  ; Raw Probabilities                       ;
  282.              (0.2 0 0.15 0.6 0.05)) ; Same Probailities Normalized to 1       ;
  283.          r nil
  284.    )
  285.    (foreach p l
  286.       (setq c0 0 c1 0 c2 0 c3 0 c4 0)
  287.       (repeat 10000
  288.          (setq i (roulette p))
  289.          (cond
  290.             ((= i 0)(setq c0 (1+ c0)))
  291.             ((= i 1)(setq c1 (1+ c1)))
  292.             ((= i 2)(setq c2 (1+ c2)))
  293.             ((= i 3)(setq c3 (1+ c3)))
  294.             ((= i 4)(setq c4 (1+ c4))) 
  295.          )     
  296.       )
  297.       ; Should return close to (2000 0 1500 6000 500)                         ;
  298.       (setq r (cons (list c0 c1 c2 c3 c4) r))
  299.    )
  300.    (reverse r)
  301. )
  302.  
  303.  
  304. ;; relcost     by ymg                                                         ;
  305. ;;                                                                            ;
  306. ;; Calculates Relative Cost of Solution                                       ;
  307. ;; From: Genetic Algorithms for Cutting Stock Problems:                       ;
  308. ;;       With and Without Contiguity.                                         ;
  309. ;; By Robert Hinterding & Lutfar Khan                                         ;
  310. ;;      http://vuir.vu.edu.au/25789/1/TECHNICALREPORT40_compressed.pdf        ;
  311. ;;                                                                            ;
  312. ;; ls is defined in main program                                              ;
  313.  
  314. (defun relcost (l / m)
  315.    (setq m (length l))
  316.    (/ (apply '+
  317.          (mapcar '(lambda (a) (+ (sqrt (/ (cadr a) (float ls)))
  318.                                  (/ (if (zerop (cadr a)) 0 1.0) m)
  319.                               )
  320.                   )
  321.                   l
  322.          )
  323.       )
  324.       (1+ m)
  325.    )
  326. )
  327.  
  328.  
  329.  
  330. ;; swapnth     by ymg                                                         ;
  331. ;;                                                                            ;
  332. ;; Given Two Indices, n1 and n2 and a List l.                                 ;
  333. ;; Returns the List with the Item Position Swapped                            ;
  334. ;;                                                                            ;
  335.  
  336. (defun swapnth (n1 n2 l / a d tmp)
  337.    (setq d (1- (length l))
  338.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)
  339.        tmp (vlax-safearray-get-element a n1)
  340.    )
  341.    (vlax-safearray-put-element a n1 (vlax-safearray-get-element a n2))
  342.    (vlax-safearray-put-element a n2 tmp)
  343.    (vlax-safearray->list a)
  344. )
  345.  
  346.  
  347. ; shuffle     (Original idea by highflyingbird)                               ;
  348. ;             Simplified the code   ymg                                       ;
  349.  
  350. (defun shuffle (l / a d  i  n tmp)
  351.    (setq d (1- (length l))
  352.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)                    
  353.          i -1
  354.    )
  355.    (repeat d
  356.       (setq  i (1+ i)
  357.              n (+ i (fix (* (rand) (- d i))))  
  358.            tmp (vlax-safearray-get-element a n)
  359.       )
  360.       (vlax-safearray-put-element a n (vlax-safearray-get-element a i))
  361.       (vlax-safearray-put-element a i tmp)
  362.   )
  363.   (vlax-safearray->list a)
  364. )
  365.  
  366. ; This one by Irneb, list based. Actually quite fast, and even faster once    ;
  367. ; we replace repetitive call to function length by variable i                 ;
  368. ; in the vl-sort-i lambda clauses.                                            ;
  369.  
  370. (defun shuffle2 (l / p i)
  371.   (setq p (/ (setq i (length l)) 2))
  372.   (mapcar '(lambda (n) (nth n l))
  373.               (vl-sort-i l '(lambda (a b) (<= (fix (* (rand) i)) p)))))
  374.  
  375.  
  376.  
  377.  
  378. ;; mk_lwp    by Alan J Thompson                                                 ;
  379. ;; Argument: pl, A list of points (2d or 3d)                                    ;
  380. ;; Create an LWPolyline at Elevation 0, on Current Layer.                       ;
  381. ;; Return: Polyline Object                                                      ;
  382. ;;                                                                              ;
  383.  
  384. (defun mk_lwp (pl)
  385.     (vlax-ename->vla-object
  386.       (entmakex
  387.          (append (list '(0 . "LWPOLYLINE")
  388.                        '(100 . "AcDbEntity")
  389.                        '(100 . "AcDbPolyline")
  390.                         (cons 90 (length pl))
  391.                         '(70 . 0)
  392.                  )
  393.                  (mapcar '(lambda (p) (cons 10 (trans (list (car p) (cadr p)) 1 0))) pl)
  394.         )
  395.       )
  396.     )
  397.  )
  398.  
  399. ;; distinct#    by ymg  (Derived from Distinct by Gile Chanteau               ;
  400. ;; Returns a list of distinct Item and Quantity ((item qty)......)            ;
  401. ;; Argument                                                                   ;
  402. ;; l   List                                                                   ;
  403. ;;                                                                            ;
  404.  
  405. ;(defun distinct# (l)
  406. ;   (if l
  407. ;     (cons (cons (car l) (- (length l) (length (setq l (vl-remove (car l) l))))) (distinct# l))    
  408. ;   )
  409. ;)
  410.  
  411. ; Modified to return ((qty (pattern) waste) (...) (...))
  412. (defun distinct# (l / i)
  413.    (if l
  414.       (cons (cons (- (length l) (length (setq l (vl-remove (setq i (car l)) l)))) i) (distinct# l))    
  415.    )
  416. )
  417.  
  418.  
  419. ;; printres                                                                   ;
  420. ;;                                                                            ;
  421. ;; Crude Patterns and Statistic Output to the Text Screen.                    ;
  422. ;;                                                                            ;
  423.  
  424. (defun printres (tit l d ls p / a su w)
  425.    (textscr)
  426.    (princ (strcat "\n" tit))
  427.    (princ (strcat "\n D: " (vl-princ-to-string d)))
  428.    (princ (strcat "\n L: " (vl-princ-to-string l)))
  429.    (princ (strcat "\nLs: " (if (= 'INT (type ls)) (itoa ls) (rtos ls 2 3))))
  430.    (princ "\n")
  431.    (foreach i p
  432.       (princ (strcat "\n" (vl-princ-to-string i)))
  433.    )
  434.    (princ "\n")
  435.    (princ (strcat "\nNb of Stock used    : " (itoa (setq su (apply '+ (mapcar 'car p))))))
  436.    (princ (strcat "\nNb of Parts Cut     : " (itoa (apply '+ (mapcar '(lambda (a) (* (car a) (length (cadr a)))) p)))))
  437.    (princ (strcat "\nTotal Length Wasted : " (if (= 'INT (type (setq w (apply '+ (mapcar '(lambda (a) (* (car a) (caddr a))) p))))) (itoa w) (rtos w 2 2))))
  438.    (princ (strcat "\nNb Patterns used    : " (itoa (length p))))
  439.    (princ (strcat "\nPercent Efficiency  : " (rtos (* 100 ( / (- (* su (float ls)) w) (* su ls))) 2 4) " %"))
  440.    (princ "\n\n")
  441. )
  442.  

See continuation in next post.....
« Last Edit: April 10, 2015, 04:34:53 PM by ymg »

ymg

  • Guest
.......Continued from above.

The basic approach is to create a population of 75 permutations
of the items to be cut.

Each individuals in the Parent population is evaluated against a cost function.  It
then creates a single offspring by mutation (3 Points Swap) thus giving us a
CHILDREN population.

Each individuals in the Children population is also evaluated by the same cost function.

For each individual in the union of (Parent U Children) we select at random 10 opponents.
Each individual is compared  against all opponents.  For each comparison,
if the individual's cost is no greater than the opponent's, it receives a "WIN".

The 75 individuals with the most wins are elected to become the Parents for the Next generation.

Now still haven't figured a smart way to stop the generating.

Seems to be highly problem dependant.  For the moment I run (* 20 Nb itms to cut)
generations.

For Problem 1a to 4a it is more than sufficient.  At problem 5a it reaches the solution
however it is a tight fit.

Now I am open to suggestion If you play with it.

Next thing, I will implement the contiguous solution as it can be
an important factor in rebar cutting.

In parrallel I'm also working on an Ant Colony Optimization,
this one, Pattern based, could be faster than the above.

ymg
« Last Edit: April 10, 2015, 04:49:34 PM by ymg »

ymg

  • Guest
Here is revised code, faster mainly due
to the replacement of my swapnth routine
by CAB's excellent version of it.

CAB's version is nearly 3x faster  :embarrassed:

I've also done a bit of cleanup, but more
need to be done.

Code - Auto/Visual Lisp: [Select]
  1. ;; EP-Cut              by ymg                                                 ;
  2. ;;                                                                            ;
  3. ;;        A New Evolutionary Approach to Cutting Stock Problems               ;
  4. ;;                  With and Without Contiguity                               ;
  5. ;;       By: Ko-Hsin Liang, Xin Yao, Charles Newton, David Hoffman          ;
  6. ;;  https://www.cs.bham.ac.uk/~xin/papers/COR_LiangYaoNewtonHoffman.pdf       ;
  7. ;;                                                                            ;
  8. ;; Contiguity is not implemented yet in the following                         ;
  9. ;;                                                                            ;
  10.  
  11. (defun c:EP-Cut (/ a b bc c cost d gmul graf i k l ls mn mu mx n n3ps ngen opp
  12.                    popu popuc prob  probc s st stid stidc stoc sz ti tit tsiz vexg w win)
  13.  
  14.             ; Notes that variables bsol, bcost, bstoc, sol, costc and stocc   ;
  15.             ; are not declared so that we can inspect other solutions.        ;
  16.             ; Sample problems also will need to bet to nil manually           ;
  17.  
  18.                  
  19.    (setq   mu 75             ; Size of Population                             ;
  20.          tsiz 10             ; Tournament Size (Number of Opponents)          ;
  21.          gmul 20             ; Multiplier for Nunber of Generation to Run     ;
  22.          n3ps  2             ; Number of 3PS Repetitions to Creates Offspring ;
  23.    )                        
  24.    (foreach pr prob1ato5a
  25.       (setq popu nil)
  26.       (setq ti (car (_vl-times)))
  27.       (setq tit (car   pr)
  28.               l (cadr  pr)
  29.               d (caddr pr)
  30.              ls (last  pr)
  31.       )
  32.       (setq popu (list (longlst l d)); Adding Ordered List eq. to FFD-binpack ;
  33.                n (length (car popu)) ; Nomber of Items to Cut                 ;
  34.             ngen (* gmul n)          ; Number of Generations to Run           ;
  35.             vexg (/ ngen 1.6)        ; Vertical Exageration for Graph         ;
  36.       )
  37.       (repeat (1- mu)
  38.          (setq popu (cons  (shuffle (car popu)) popu))
  39.       )
  40.      
  41.       ; popu, Population                                                      ;
  42.       ; stoc, Population Decoded by First Fit Binpack                         ;
  43.       ; stid, Indices to popu to End of a Cut Stock                           ;
  44.       ; prob, Probability of Selecting a Given Stock for Mutations            ;
  45.       ; cost, Relative Cost of Each Individual                                ;
  46.      
  47.       (setq popu (reverse popu)
  48.             stoc (mapcar '(lambda (a) (ff-binpack a ls)) popu)
  49.             stid (mapcar '(lambda (a) (setq st -1) (mapcar '(lambda (a) (setq st (+ st (length (car a))))) a)) stoc)
  50.             prob (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stoc)
  51.             cost (mapcar 'relcost  stoc)
  52.             k 0
  53.       )
  54.       (setq    bc (apply 'min cost)
  55.             bstoc stoc
  56.             bcost cost
  57.              graf (list (list 0 (* vexg bc)))
  58.       )
  59.       (princ (strcat "\nEP-Cut - " tit ))
  60.       (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos bc 2 9)))
  61.      
  62.       ; Each Idividual in Population is Mutated by 3 Point Swap (3PS)         ;
  63.       (repeat ngen
  64.          (setq i 0 popuc nil)
  65.          (foreach ind popu
  66.             (repeat n3ps
  67.                (setq a (fix (* (rand) n))
  68.                      s (roulette (nth i prob))
  69.                     mx (nth s (nth i stid))
  70.                     mn (if (zerop s) 0 (+ (nth (1- s) (nth i stid)) 1))
  71.                      b (randrng mn mx)    
  72.                      s (roulette (nth i prob))
  73.                     mx (nth s (nth i stid))
  74.                     mn (if (zerop s) 0 (+ (nth (1- s) (nth i stid)) 1))
  75.                      c (randrng mn mx)    
  76.                    ind (swapnth a b ind)
  77.                    ind (swapnth a c ind)
  78.                )
  79.             )
  80.             (setq popuc (cons ind popuc)
  81.                   i (1+ i)
  82.             )      
  83.          )
  84.        
  85.          (setq popuc (reverse popuc)
  86.                stocc (mapcar '(lambda (a) (ff-binpack a ls)) popuc)
  87.                stidc (mapcar '(lambda (a) (setq st -1) (mapcar '(lambda (a) (setq st (+ st (length (car a))))) a)) stocc)
  88.                probc (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stocc)
  89.                costc (mapcar 'relcost  stocc)
  90.                
  91.                popuc (append popu popuc)
  92.                stocc (append stoc stocc)
  93.                stidc (append stid stidc)
  94.                probc (append prob probc)
  95.                costc (append cost costc)
  96.          )
  97.      
  98.          ; Conduct Comparisons Over the Union of Parents and Offspring        ;
  99.          ; Tournament Size is Defined at Beginning of Proram                  ;
  100.        
  101.          (setq i 0  sz (+ mu mu) win nil)
  102.          (foreach c costc
  103.             (setq w 0)
  104.             (repeat tsiz
  105.                (while (= i (setq opp (fix (* (rand) sz)))))
  106.                (if (<= c (nth opp costc)) (setq w (1+ w)))
  107.             )
  108.             (setq win (cons w win)
  109.                     i (1+ i)
  110.             )      
  111.          )
  112.          
  113.            
  114.          ; Choose the Solution With Most Win for New Generation               ;
  115.        
  116.          (setq  win (take mu (vl-sort-i (reverse win) '>))
  117.                popu (mapcar '(lambda (a) (nth a popuc)) win)
  118.                stoc (mapcar '(lambda (a) (nth a stocc)) win)
  119.                stid (mapcar '(lambda (a) (nth a stidc)) win)
  120.                prob (mapcar '(lambda (a) (nth a probc)) win)
  121.                cost (mapcar '(lambda (a) (nth a costc)) win)
  122.                   k (1+ k)
  123.          )
  124.                   (vl-sort-i win '>)
  125.         (setq    b (apply 'min costc)
  126.               graf (cons (list k (* vexg b)) graf)
  127.         )            
  128.         (if (< b bc)
  129.            (progn
  130.              (setq bc b bstoc stocc bcost costc)
  131.              (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos (apply 'min cost) 2 9)))            
  132.            )
  133.         )  
  134.      )
  135.      ; Order of the last 150 solutions in stocc                               ;
  136.      (setq sol (vl-sort-i bcost '<))  
  137.      (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos (apply 'min cost) 2 9)))
  138.      (princ (strcat "\n    EP-Cut - Elapsed time: " (rtos (/ (- (car (_vl-times)) ti) 1000.) 2 4) " secs. \n" ))
  139.      
  140.      
  141.      ; Here I am sorting all bins of the best solutions and outputting        ;
  142.      (setq bsol (mapcar '(lambda (a) (list (mapcar '(lambda (b) (nth b (car a))) (vl-sort-i (car a) '>)) (cadr a))) (nth (car sol) bstoc)))
  143.      (printres (strcat "EP-Cut - " tit) l d ls (distinct# bsol))
  144.      
  145.      ; Output the graph of Generations vs Cost for Debugging and Finding Best ;
  146.      ; way to stop the algorithm.                                             ;
  147.      (mk_lwp (reverse graf))          
  148.    ) ; Go to Next Problem    ;
  149.    (princ)
  150. )
  151.  
  152.  
  153. ;; longlst                                                                    ;
  154. ;; Expand a list of length and quantity to a                                  ;
  155. ;; Sorted long list with repeating items                                      ;
  156. ;;                                                                            ;
  157.  
  158. (defun longlst (l d / i j ll)
  159.   (setq j 0)
  160.   (foreach i d
  161.      (repeat i (setq ll (cons (nth j l) ll)))
  162.      (setq j (1+ j))
  163.   )
  164.   (mapcar '(lambda (a) (nth a ll)) (vl-sort-i ll '>))
  165. )
  166.  
  167.  
  168. ;; FF-binpack          by ymg                                                 ;
  169. ;; First Fit                                                                  ;
  170. ;; Arguments: l  List of items to put in bins                                 ;
  171. ;;            c  Capacity of a bin                                            ;
  172. ;;                                                                            ;
  173.  
  174. (defun FF-binpack (l c / i b tb)
  175.    (setq r nil)
  176.    (while l
  177.       (setq w ls b nil)
  178.       (while (and l (>= w (setq i (car l))))
  179.          (setq b (cons i b)
  180.                w (- w i)
  181.                l (cdr l)
  182.          )
  183.       )
  184.       (setq r (cons (list (reverse b) w) r))
  185.    )
  186.    (reverse r)
  187. )
  188.  
  189.  
  190. ;; Random number generator, #s(eed) remains Global.                           ;
  191.  
  192. (defun rand (/ x)
  193.    (/ (setq x 4294967296.0 #s (rem (1+ (* 1664525.0 (cond (#s) ((getvar 'DATE))))) x)) x)
  194. )
  195.  
  196. ;; Random in range i j  (Integer Range)                                       ;
  197.  
  198. (defun randrng (i j) (+ i (fix (* (rand) (- j i -1)))))
  199.  
  200. ;; roulette      by ymg                                                       ;
  201. ;;                                                                            ;
  202. ;; Roulette-Wheel Selection Via Stochastic Acceptance                         ;
  203. ;;    by Adam Lipowski and Dorota Lipowska                                    ;
  204. ;;          http://arxiv.org/pdf/1109.3627v2.pdf                              ;
  205. ;;                                                                            ;
  206. ;; Argument: l   List of Probabilities. (No need to normalize)                ;
  207. ;; Returns : Index in List of Chosen Item According to Probabilities.         ;
  208. ;;                                                                            ;
  209.  
  210. (defun roulette (l / k m n)
  211.    (setq  m (float (apply 'max l)) n (length l))
  212.    (while (> (rand) (/ (nth (setq k (fix (* (rand) n))) l) m)))
  213.    k
  214. )
  215.  
  216. ;; For Debugging Check Frquency of Returns of Roulette's Function             ;
  217. (defun checkroulette (/ l p r c0 c1 c2 c3 c4)
  218.    (setq l '((0.4 0.0 0.3 1.2 0.1)  ; Raw Probabilities                       ;
  219.              (0.2 0 0.15 0.6 0.05)) ; Same Probailities Normalized to 1       ;
  220.          r nil
  221.    )
  222.    (foreach p l
  223.       (setq c0 0 c1 0 c2 0 c3 0 c4 0)
  224.       (repeat 10000
  225.          (setq i (roulette p))
  226.          (cond
  227.             ((= i 0)(setq c0 (1+ c0)))
  228.             ((= i 1)(setq c1 (1+ c1)))
  229.             ((= i 2)(setq c2 (1+ c2)))
  230.             ((= i 3)(setq c3 (1+ c3)))
  231.             ((= i 4)(setq c4 (1+ c4))) 
  232.          )     
  233.       )
  234.       ; Should return close to (2000 0 1500 6000 500)                         ;
  235.       (setq r (cons (list c0 c1 c2 c3 c4) r))
  236.    )
  237.    (reverse r)
  238. )
  239.  
  240.  
  241. ;; relcost     by ymg                                                         ;
  242. ;;                                                                            ;
  243. ;; Calculates Relative Cost of Solution                                       ;
  244. ;; From: Genetic Algorithms for Cutting Stock Problems:                       ;
  245. ;;       With and Without Contiguity.                                         ;
  246. ;; By Robert Hinterding & Lutfar Khan                                         ;
  247. ;;      http://vuir.vu.edu.au/25789/1/TECHNICALREPORT40_compressed.pdf        ;
  248. ;;                                                                            ;
  249. ;; ls is defined in main program                                              ;
  250.  
  251. (defun relcost (l / m)
  252.    (setq m (length l))
  253.    (/ (apply '+
  254.          (mapcar '(lambda (a) (+ (sqrt (/ (cadr a) (float ls)))
  255.                                  (/ (if (zerop (cadr a)) 0 1.0) m)
  256.                               )
  257.                   )
  258.                   l
  259.          )
  260.       )
  261.       (1+ m)
  262.    )
  263. )
  264.  
  265.  
  266.  
  267. ;; swapnth     by ymg                                                         ;
  268. ;;                                                                            ;
  269. ;; Given Two Indices, n1 and n2 and a List l.                                 ;
  270. ;; Returns the List with the Item Position Swapped                            ;
  271. ;;                                                                            ;
  272.  
  273. (defun swapnth (n1 n2 l / a d tmp)
  274.    (setq d (1- (length l))
  275.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)
  276.        tmp (vlax-safearray-get-element a n1)
  277.    )
  278.    (vlax-safearray-put-element a n1 (vlax-safearray-get-element a n2))
  279.    (vlax-safearray-put-element a n2 tmp)
  280.    (vlax-safearray->list a)
  281. )
  282.  
  283. ;; swapnth     by CAB    (3 times faster than above)                          ;
  284. ;;                                                                            ;
  285. ;; Given Two Indices, n1 and n2 and a List l.                                 ;
  286. ;; Returns the List with the Item Position Swapped                            ;
  287. ;; Notes: I've removed the arguments testing.                                 ;
  288. ;; (if (and (< -1 i1 (length lst)) (< -1 i2 (length lst)))                    ;
  289.  
  290. (defun swapnth (n1 n2 l / i)
  291.   (setq i -1)
  292.     (mapcar '(lambda (a)
  293.                (setq i (1+ i))
  294.                (cond
  295.                  ((= i n2) (nth n1 l))
  296.                  ((= i n1) (nth n2 l))
  297.                  (a)
  298.                )
  299.              )
  300.         l
  301.     )
  302. )
  303.  
  304.  
  305. ; shuffle     (Original idea by highflyingbird)                               ;
  306. ;             Simplified the code   ymg                                       ;
  307.  
  308. (defun shuffle (l / a d  i  n tmp)
  309.    (setq d (1- (length l))
  310.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)                    
  311.          i -1
  312.    )
  313.    (repeat d
  314.       (setq  i (1+ i)
  315.              n (+ i (fix (* (rand) (- d i))))  
  316.            tmp (vlax-safearray-get-element a n)
  317.       )
  318.       (vlax-safearray-put-element a n (vlax-safearray-get-element a i))
  319.       (vlax-safearray-put-element a i tmp)
  320.   )
  321.   (vlax-safearray->list a)
  322. )
  323.  
  324. ; This one by Irneb, list based. Actually quite fast, and even faster once    ;
  325. ; we replace repetitive call to function length by variable i                 ;
  326. ; in the vl-sort-i lambda clauses.                                            ;
  327.  
  328. (defun shuffle2 (l / p i)
  329.   (setq p (/ (setq i (length l)) 2))
  330.   (mapcar '(lambda (n) (nth n l))
  331.               (vl-sort-i l '(lambda (a b) (<= (fix (* (rand) i)) p)))))
  332.  
  333.  
  334.  
  335.  
  336. ;; mk_lwp    by Alan J Thompson                                                 ;
  337. ;; Argument: pl, A list of points (2d or 3d)                                    ;
  338. ;; Create an LWPolyline at Elevation 0, on Current Layer.                       ;
  339. ;; Return: Polyline Object                                                      ;
  340. ;;                                                                              ;
  341.  
  342. (defun mk_lwp (pl)
  343.     (vlax-ename->vla-object
  344.       (entmakex
  345.          (append (list '(0 . "LWPOLYLINE")
  346.                        '(100 . "AcDbEntity")
  347.                        '(100 . "AcDbPolyline")
  348.                         (cons 90 (length pl))
  349.                         '(70 . 0)
  350.                  )
  351.                  (mapcar '(lambda (p) (cons 10 (trans (list (car p) (cadr p)) 1 0))) pl)
  352.         )
  353.       )
  354.     )
  355.  )
  356.  
  357. ;; distinct#    by ymg  (Derived from Distinct by Gile Chanteau               ;
  358. ;; Returns a list of distinct Item and Quantity ((item qty)......)            ;
  359. ;; Argument                                                                   ;
  360. ;; l   List                                                                   ;
  361. ;;                                                                            ;
  362.  
  363. ;(defun distinct# (l)
  364. ;   (if l
  365. ;     (cons (cons (car l) (- (length l) (length (setq l (vl-remove (car l) l))))) (distinct# l))    
  366. ;   )
  367. ;)
  368.  
  369. ; Modified to return ((qty (pattern) waste) (...) (...))
  370. (defun distinct# (l / i)
  371.    (if l
  372.       (cons (cons (- (length l) (length (setq l (vl-remove (setq i (car l)) l)))) i) (distinct# l))    
  373.    )
  374. )
  375.  
  376. ; take   by ymg                                                               ;
  377. ;                                                                             ;
  378. ; Returns the first n items from a list as a list                             ;
  379. ;                                                                             ;
  380. ; Iterative version of Gile Chanteau's take                                   ;
  381.  
  382. (defun take (n l / r)
  383.    (repeat n
  384.       (setq r (cons (car l) r) l (cdr l))
  385.    )
  386.    (reverse r)
  387. )
  388.  
  389.  
  390. ;; printres                                                                   ;
  391. ;;                                                                            ;
  392. ;; Crude Patterns and Statistic Output to the Text Screen.                    ;
  393. ;;                                                                            ;
  394.  
  395. (defun printres (tit l d ls p / a su w)
  396.    ;(textscr)
  397.    (princ (strcat "\n" tit))
  398.    (princ (strcat "\n D: " (vl-princ-to-string d)))
  399.    (princ (strcat "\n L: " (vl-princ-to-string l)))
  400.    (princ (strcat "\nLs: " (if (= 'INT (type ls)) (itoa ls) (rtos ls 2 3))))
  401.    (princ "\n")
  402.    (foreach i p
  403.       (princ (strcat "\n" (vl-princ-to-string i)))
  404.    )
  405.    (princ "\n")
  406.    (princ (strcat "\nNb of Stock used    : " (itoa (setq su (apply '+ (mapcar 'car p))))))
  407.    (princ (strcat "\nNb of Parts Cut     : " (itoa (apply '+ (mapcar '(lambda (a) (* (car a) (length (cadr a)))) p)))))
  408.    (princ (strcat "\nTotal Length Wasted : " (if (= 'INT (type (setq w (apply '+ (mapcar '(lambda (a) (* (car a) (caddr a))) p))))) (itoa w) (rtos w 2 2))))
  409.    (princ (strcat "\nNb Patterns used    : " (itoa (length p))))
  410.    (princ (strcat "\nPercent Efficiency  : " (rtos (* 100 ( / (- (* su (float ls)) w) (* su ls))) 2 4) " %"))
  411.    (princ "\n\n")
  412. )
  413.  

ymg

  • Guest
Here again, revised code with some
more speed improvements.

I've settled the issue of stopping the generation
loop.  As of now the loop executes for at least
400 generations past the last generation, where
there was an improvement in cost, unless we reach
a cost of 0.0 in which case we Exit.

(Note: this much more than my initial guess of 50)

I will now concentrate on implementing the
"Contiguity" constraint, before trying to do
any more speed improvements.


Code - Auto/Visual Lisp: [Select]
  1. ;; EP-Cut              by ymg                                                 ;
  2. ;;                                                                            ;
  3. ;;        A New Evolutionary Approach to Cutting Stock Problems               ;
  4. ;;                  With and Without Contiguity                               ;
  5. ;;       By: Ko-Hsin Liang, Xin Yao, Charles Newton, David Hoffman          ;
  6. ;;  https://www.cs.bham.ac.uk/~xin/papers/COR_LiangYaoNewtonHoffman.pdf       ;
  7. ;;                                                                            ;
  8. ;; Contiguity is not implemented yet in the following                         ;
  9. ;;                                                                            ;
  10.  
  11. (defun c:EP-Cut (/ a b bc c cost d gmul graf i k l ls mn mu mx n n3ps ngen opp
  12.                    popu popuc prob  probc s st stid stidc stoc sz ti tit tsiz vexg w win)
  13.  
  14.             ; Notes that variables bsol, bcost, bstoc, sol, costc and stocc   ;
  15.             ; are not declared so that we can inspect other solutions.        ;
  16.             ; Sample problems also will need to bet to nil manually           ;
  17.  
  18.                  
  19.    (setq   mu 75             ; Size of Population                             ;
  20.          tsiz 10             ; Tournament Size (Number of Opponents)          ;
  21.          gmul 20             ; Multiplier for Max # of Generation to Run      ;
  22.          n3ps  2             ; Number of 3PS Repetitions to Creates Offspring ;
  23.          stop 400            ; Exit Loop if Best Cost Show no Improvement     ;
  24.    )                        
  25.    (foreach pr prob1ato5a
  26.       (setq popu nil)
  27.       (setq ti (car (_vl-times)))
  28.       (setq tit (car   pr)
  29.               l (cadr  pr)
  30.               d (caddr pr)
  31.              ls (last  pr)
  32.       )
  33.       (setq popu (list (longlst l d)); Adding Ordered List eq. to FFD-binpack ;
  34.                n (length (car popu)) ; Nomber of Items to Cut                 ;
  35.       )
  36.       (repeat (1- mu)
  37.          (setq popu (cons  (shuffle (car popu)) popu))
  38.       )
  39.      
  40.       ; popu, Population                                                      ;
  41.       ; stoc, Population Decoded by First Fit Binpack                         ;
  42.       ; stid, Indices to popu to Start of a Cut Stock                         ;
  43.       ; prob, Probability of Selecting a Given Stock for Mutations            ;
  44.       ; cost, Relative Cost of Each Individual                                ;
  45.      
  46.       (setq popu (reverse popu)
  47.             stoc (mapcar '(lambda (a) (ff-binpack a ls)) popu)
  48.             stid (mapcar '(lambda (a) (setq i 0) (cons 0 (mapcar '(lambda (a) (setq i (+ i (length (car a))))) a))) stoc)
  49.             prob (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stoc)
  50.             cost (mapcar 'relcost  stoc)
  51.             k 0
  52.       )
  53.       (setq    bc (apply 'min cost)         ; Best Cost So Far                ;
  54.             bstoc stoc                      ; Copy of stoc List               ;
  55.             bcost cost                      ; Copy of cost List               ;
  56.                bk 0                         ; Generation# of Best Cost        ;
  57.              ngen (+ bk stop)              
  58.       )
  59.       (princ (strcat "\nEP-Cut - " tit ))
  60.       (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos bc 2 9)))
  61.      
  62.       ; Each Idividual in Population is Mutated by 3 Point Swap (3PS)         ;
  63.       (while (and (< (- k bk) stop) (> bc 0))
  64.          (setq i 0 popuc nil)
  65.          (foreach ind popu
  66.             (setq pro (nth i prob) sti (nth i stid))
  67.             (setq a (fix (* (rand) n))
  68.                      s (roulette pro)
  69.                     mn (nth s sti)
  70.                     mx (1- (nth (1+ s) sti))
  71.                      b (randrng mn mx)    
  72.                      s (roulette pro)
  73.                     mn (nth s sti)
  74.                     mx (1- (nth (1+ s) sti))               
  75.                      c (randrng mn mx)    
  76.                    ind (swapnth a b ind)
  77.                    ind (swapnth a c ind)
  78.             )
  79.             (setq popuc (cons ind popuc)
  80.                   i (1+ i)
  81.             )      
  82.          )
  83.          
  84.          (setq popuc (reverse popuc)
  85.                stocc (mapcar '(lambda (a) (ff-binpack a ls)) popuc)
  86.                stidc (mapcar '(lambda (a) (setq i 0) (cons 0 (mapcar '(lambda (a) (setq i (+ i (length (car a))))) a))) stocc)
  87.                probc (mapcar '(lambda (a) (mapcar '(lambda (a) (if (> (cadr a) 0) (/ 1.0 (sqrt (cadr a))) 0.01)) a)) stocc)
  88.                costc (mapcar 'relcost  stocc)
  89.                
  90.                popuc (append popu popuc)
  91.                stocc (append stoc stocc)
  92.                stidc (append stid stidc)
  93.                probc (append prob probc)
  94.                costc (append cost costc)
  95.          )
  96.      
  97.          ; Conduct Comparisons Over the Union of Parents and Offspring        ;
  98.          ; Tournament Size is Defined at Beginning of Proram                  ;
  99.        
  100.          (setq i 0  u (+ mu mu) win nil b 1.0)
  101.          (foreach c costc
  102.             (setq w 0)
  103.             (repeat tsiz
  104.                (while (= i (setq opp (fix (* (rand) u)))))
  105.                (if (<= c (nth opp costc)) (setq w (1+ w)))
  106.             )
  107.             (setq win (cons w win)
  108.                     i (1+ i)
  109.             )      
  110.          )
  111.          
  112.            
  113.          ; Choose the Solution With Most Win for New Generation               ;
  114.        
  115.          (setq  win (take mu (vl-sort-i (reverse win) '>))
  116.                popu (mapcar '(lambda (a) (nth a popuc)) win)
  117.                stoc (mapcar '(lambda (a) (nth a stocc)) win)
  118.                stid (mapcar '(lambda (a) (nth a stidc)) win)
  119.                prob (mapcar '(lambda (a) (nth a probc)) win)
  120.                cost (mapcar '(lambda (a) (setq b (min b (setq a (nth a costc)))) a) win)
  121.                   k (1+ k)
  122.          )
  123.                  
  124.          (if (< b bc)
  125.             (setq    bc b
  126.                      bk k
  127.                   bstoc stocc
  128.                   bcost costc
  129.                   ngen (+ bk stop)  
  130.                     ** (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos b 2 9)))            
  131.            )
  132.         )  
  133.      ) ; Goto next generation ;
  134.      
  135.      ; Order of the last 150 solutions in stocc                               ;
  136.      (setq sol (vl-sort-i bcost '<))  
  137.      (princ (strcat "\nGeneration: " (itoa k) " \\ " (itoa ngen) "   -  Min. Cost: " (rtos b 2 9)))
  138.      (princ (strcat "\n    EP-Cut - Elapsed time: " (rtos (/ (- (car (_vl-times)) ti) 1000.) 2 4) " secs. \n" ))
  139.      
  140.      
  141.      ; Here Sorting the Cuts in Best Solutions and Outputting                 ;
  142.      (setq bsol (mapcar '(lambda (a) (list (mapcar '(lambda (b) (nth b (car a))) (vl-sort-i (car a) '>)) (cadr a))) (nth (car sol) bstoc)))
  143.      (printres (strcat "EP-Cut - " tit) l d ls (distinct# bsol))
  144.      
  145.              
  146.    ) ; Go to Next Problem    ;
  147.    (princ)
  148. )
  149.  
  150.  
  151. ;; longlst                                                                    ;
  152. ;; Expand a list of length and quantity to a                                  ;
  153. ;; Sorted long list with repeating items                                      ;
  154. ;;                                                                            ;
  155.  
  156. (defun longlst (l d / i j ll)
  157.   (setq j 0)
  158.   (foreach i d
  159.      (repeat i (setq ll (cons (nth j l) ll)))
  160.      (setq j (1+ j))
  161.   )
  162.   (mapcar '(lambda (a) (nth a ll)) (vl-sort-i ll '>))
  163. )
  164.  
  165.  
  166. ;; FF-binpack          by ymg                                                 ;
  167. ;; First Fit                                                                  ;
  168. ;; Arguments: l  List of items to put in bins                                 ;
  169. ;;            c  Capacity of a bin                                            ;
  170. ;;                                                                            ;
  171.  
  172. (defun FF-binpack (l c / i b tb)
  173.    (setq r nil)
  174.    (while l
  175.       (setq w ls b nil)
  176.       (while (and l (>= w (setq i (car l))))
  177.          (setq b (cons i b)
  178.                w (- w i)
  179.                l (cdr l)
  180.          )
  181.       )
  182.       (setq r (cons (list (reverse b) w) r))
  183.    )
  184.    (reverse r)
  185. )
  186.  
  187.  
  188. ;; Random number generator, #s(eed) remains Global.                           ;
  189.  
  190. (defun rand (/ x)
  191.    (/ (setq x 4294967296.0 #s (rem (1+ (* 1664525.0 (cond (#s) ((getvar 'DATE))))) x)) x)
  192. )
  193.  
  194. ;; Random in range i j  (Integer Range)                                       ;
  195.  
  196. (defun randrng (i j) (+ i (fix (* (rand) (- j i -1)))))
  197.  
  198. ;; roulette      by ymg                                                       ;
  199. ;;                                                                            ;
  200. ;; Roulette-Wheel Selection Via Stochastic Acceptance                         ;
  201. ;;    by Adam Lipowski and Dorota Lipowska                                    ;
  202. ;;          http://arxiv.org/pdf/1109.3627v2.pdf                              ;
  203. ;;                                                                            ;
  204. ;; Argument: l   List of Probabilities. (No need to normalize)                ;
  205. ;; Returns : Index in List of Chosen Item According to Probabilities.         ;
  206. ;;                                                                            ;
  207.  
  208. (defun roulette (l / k m n)
  209.    (setq  m (float (apply 'max l)) n (length l))
  210.    (while (> (rand) (/ (nth (setq k (fix (* (rand) n))) l) m)))
  211.    k
  212. )
  213.  
  214. ;; For Debugging Check Frquency of Returns of Roulette's Function             ;
  215. (defun checkroulette (/ l p r c0 c1 c2 c3 c4)
  216.    (setq l '((0.4 0.0 0.3 1.2 0.1)  ; Raw Probabilities                       ;
  217.              (0.2 0 0.15 0.6 0.05)) ; Same Probailities Normalized to 1       ;
  218.          r nil
  219.    )
  220.    (foreach p l
  221.       (setq c0 0 c1 0 c2 0 c3 0 c4 0)
  222.       (repeat 10000
  223.          (setq i (roulette p))
  224.          (cond
  225.             ((= i 0)(setq c0 (1+ c0)))
  226.             ((= i 1)(setq c1 (1+ c1)))
  227.             ((= i 2)(setq c2 (1+ c2)))
  228.             ((= i 3)(setq c3 (1+ c3)))
  229.             ((= i 4)(setq c4 (1+ c4))) 
  230.          )     
  231.       )
  232.       ; Should return close to (2000 0 1500 6000 500)                         ;
  233.       (setq r (cons (list c0 c1 c2 c3 c4) r))
  234.    )
  235.    (reverse r)
  236. )
  237.  
  238.  
  239. ;; relcost     by ymg                                                         ;
  240. ;;                                                                            ;
  241. ;; Calculates Relative Cost of Solution                                       ;
  242. ;; From: Genetic Algorithms for Cutting Stock Problems:                       ;
  243. ;;       With and Without Contiguity.                                         ;
  244. ;; By Robert Hinterding & Lutfar Khan                                         ;
  245. ;;      http://vuir.vu.edu.au/25789/1/TECHNICALREPORT40_compressed.pdf        ;
  246. ;;                                                                            ;
  247. ;; ls is defined in main program                                              ;
  248.  
  249. (defun relcost (l / m)
  250.    (setq m (length l))
  251.    (/ (apply '+
  252.          (mapcar '(lambda (a) (+ (sqrt (/ (cadr a) (float ls)))
  253.                                  (/ (if (zerop (cadr a)) 0 1.0) m)
  254.                               )
  255.                   )
  256.                   l
  257.          )
  258.       )
  259.       (1+ m)
  260.    )
  261. )
  262.  
  263.  
  264.  
  265. ;; swapnth     by ymg                                                         ;
  266. ;;                                                                            ;
  267. ;; Given Two Indices, n1 and n2 and a List l.                                 ;
  268. ;; Returns the List with the Item Position Swapped                            ;
  269. ;;                                                                            ;
  270.  
  271. (defun swapnth (n1 n2 l / a d tmp)
  272.    (setq d (1- (length l))
  273.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)
  274.        tmp (vlax-safearray-get-element a n1)
  275.    )
  276.    (vlax-safearray-put-element a n1 (vlax-safearray-get-element a n2))
  277.    (vlax-safearray-put-element a n2 tmp)
  278.    (vlax-safearray->list a)
  279. )
  280.  
  281. ;; swapnth     by CAB    (3 times faster than above)                          ;
  282. ;;                                                                            ;
  283. ;; Given Two Indices, n1 and n2 and a List l.                                 ;
  284. ;; Returns the List with the Item Position Swapped                            ;
  285. ;; Notes: I've removed the arguments testing.                                 ;
  286. ;; (if (and (< -1 i1 (length lst)) (< -1 i2 (length lst)))                    ;
  287.  
  288. (defun swapnth (n1 n2 l / i)
  289.    (setq i -1)
  290.    (mapcar '(lambda (a) (setq i (1+ i))
  291.                         (cond
  292.                            ((= i n2) (nth n1 l))
  293.                            ((= i n1) (nth n2 l))
  294.                            (a)
  295.                         )
  296.             )
  297.             l
  298.    )
  299. )
  300.  
  301.    
  302.  
  303. ; shuffle     (Original idea by highflyingbird)                               ;
  304. ;             Simplified the code   ymg                                       ;
  305.  
  306. (defun shuffle (l / a d  i  n tmp)
  307.    (setq d (1- (length l))
  308.          a (vlax-safearray-fill (vlax-make-safearray vlax-vbinteger (cons 0 d)) l)                    
  309.          i -1
  310.    )
  311.    (repeat d
  312.       (setq  i (1+ i)
  313.              n (+ i (fix (* (rand) (- d i))))  
  314.            tmp (vlax-safearray-get-element a n)
  315.       )
  316.       (vlax-safearray-put-element a n (vlax-safearray-get-element a i))
  317.       (vlax-safearray-put-element a i tmp)
  318.   )
  319.   (vlax-safearray->list a)
  320. )
  321.  
  322. ; This one by Irneb, list based. Actually quite fast, and even faster once    ;
  323. ; we replace repetitive call to function length by variable i                 ;
  324. ; in the vl-sort-i lambda clauses.                                            ;
  325.  
  326. (defun shuffle2 (l / p i)
  327.   (setq p (/ (setq i (length l)) 2))
  328.   (mapcar '(lambda (n) (nth n l))
  329.               (vl-sort-i l '(lambda (a b) (<= (fix (* (rand) i)) p)))))
  330.  
  331.  
  332.  
  333.  
  334. ;; mk_lwp    by Alan J Thompson                                                 ;
  335. ;; Argument: pl, A list of points (2d or 3d)                                    ;
  336. ;; Create an LWPolyline at Elevation 0, on Current Layer.                       ;
  337. ;; Return: Polyline Object                                                      ;
  338. ;;                                                                              ;
  339.  
  340. (defun mk_lwp (pl)
  341.     (vlax-ename->vla-object
  342.       (entmakex
  343.          (append (list '(0 . "LWPOLYLINE")
  344.                        '(100 . "AcDbEntity")
  345.                        '(100 . "AcDbPolyline")
  346.                         (cons 90 (length pl))
  347.                         '(70 . 0)
  348.                  )
  349.                  (mapcar '(lambda (p) (cons 10 (trans (list (car p) (cadr p)) 1 0))) pl)
  350.         )
  351.       )
  352.     )
  353.  )
  354.  
  355. ;; distinct#    by ymg  (Derived from Distinct by Gile Chanteau               ;
  356. ;; Returns a list of distinct Item and Quantity ((item qty)......)            ;
  357. ;; Argument                                                                   ;
  358. ;; l   List                                                                   ;
  359. ;;                                                                            ;
  360.  
  361. ;(defun distinct# (l)
  362. ;   (if l
  363. ;     (cons (cons (car l) (- (length l) (length (setq l (vl-remove (car l) l))))) (distinct# l))    
  364. ;   )
  365. ;)
  366.  
  367. ; Modified to return ((qty (pattern) waste) (...) (...))
  368. (defun distinct# (l / i)
  369.    (if l
  370.       (cons (cons (- (length l) (length (setq l (vl-remove (setq i (car l)) l)))) i) (distinct# l))    
  371.    )
  372. )
  373.  
  374. ; take   by ymg                                                               ;
  375. ;                                                                             ;
  376. ; Returns the first n items from a list as a list                             ;
  377. ;                                                                             ;
  378. ; Iterative version of Gile Chanteau's take                                   ;
  379.  
  380. (defun take (n l / r)
  381.    (repeat n
  382.       (setq r (cons (car l) r) l (cdr l))
  383.    )
  384.    (reverse r)
  385. )
  386.  
  387.  
  388. ;; printres                                                                   ;
  389. ;;                                                                            ;
  390. ;; Crude Patterns and Statistic Output to the Text Screen.                    ;
  391. ;;                                                                            ;
  392.  
  393. (defun printres (tit l d ls p / a su w)
  394.    ;(textscr)
  395.    (princ (strcat "\n" tit))
  396.    (princ (strcat "\n D: " (vl-princ-to-string d)))
  397.    (princ (strcat "\n L: " (vl-princ-to-string l)))
  398.    (princ (strcat "\nLs: " (if (= 'INT (type ls)) (itoa ls) (rtos ls 2 3))))
  399.    (princ "\n")
  400.    (foreach i p
  401.       (princ (strcat "\n" (vl-princ-to-string i)))
  402.    )
  403.    (princ "\n")
  404.    (princ (strcat "\nNb of Stock used    : " (itoa (setq su (apply '+ (mapcar 'car p))))))
  405.    (princ (strcat "\nNb of Parts Cut     : " (itoa (apply '+ (mapcar '(lambda (a) (* (car a) (length (cadr a)))) p)))))
  406.    (princ (strcat "\nTotal Length Wasted : " (if (= 'INT (type (setq w (apply '+ (mapcar '(lambda (a) (* (car a) (caddr a))) p))))) (itoa w) (rtos w 2 2))))
  407.    (princ (strcat "\nNb Patterns used    : " (itoa (length p))))
  408.    (princ (strcat "\nPercent Efficiency  : " (rtos (* 100 ( / (- (* su (float ls)) w) (* su ls))) 2 4) " %"))
  409.    (princ "\n\n")
  410. )
  411.  

ymg
« Last Edit: April 13, 2015, 11:18:11 AM by ymg »

serge_c

  • Newt
  • Posts: 39
Few lessons from Ymg mastermind !!! Should pattent this invention !!!  :)
You know I am gonna ask you again , if it's possible to help me , with my case (must be cutted per diameters ).
one more request : can you attach also your cvs file , mine is not working with your lisps anymore.
Thanks in advance .

ymg

  • Guest
sergiu,

Well not so "Mastermind" cause I believe I found
a huge bug in the above.

Although it converges toward a solution, the decoding
by ff-binpack is flawed.

I will address the by size once I have a solid solution
that also includes the contiguity constraints.

ymg

ymg

  • Guest
sergiu,

Turns out that I was wrong in above post.

The decoding is OK and respect the authors
way of doing it.

Where I do have a bug is when I create the initial
population, I wanted the first individual in the population
to be a First Fit Decreasing one.

This to bypass a series of useless solution.

However, my implementation is flawed.

Will revise and post again.

ymg

serge_c

  • Newt
  • Posts: 39
The world still wating, for the last version ; :)
We still have patience .. Don't  hury , do it good  !

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: The Cutting Stock Problem (Optimizing Cutting of Rebar or Other Material)
« Reply #27 on: September 16, 2015, 04:14:31 AM »
Thank you Ymg for starting this thread. It has been on my 'Topics worth studying list' ever since.

Before reading this thread I have analysed the code by CAB and T.Willey linked to in the OP, and have tried to come up with my own algorithm for the problem. The results of my code are similar to those in the OP. So I have probably reinvented a wheel. I have yet to completely read this thread and check.

For reference my attempt:
Code - Auto/Visual Lisp: [Select]
  1. ; Testing with CAB's example.
  2. ; (c:Roy_Cut_Test)
  3. ;   => (
  4. ;        (44 (9.71) 101.2)
  5. ;        (23 (7.65 4.0) 8.28)
  6. ;        (10 (5.3 4.0 2.66) 0.5)
  7. ;        (29 (4.0 4.0 4.0) 0.29)
  8. ;        (19 (3.67 2.66 2.66 2.66) 6.84)
  9. ;        (11 (3.67 3.67 3.67) 11.0)
  10. ;        (1 (3.67 3.67) 4.67)
  11. ;      )
  12. ;
  13. ;      137 Standard lengths
  14. (defun c:Roy_Cut_Test ( / resLst standLen todoLst)
  15.   (setq standLen 12.01)
  16.   (setq todoLst '((23 7.65) (10 5.30) (54 3.67) (67 2.66) (44 9.71) (120 4.0)))
  17.   (setq todoLst (vl-sort todoLst '(lambda (a b) (> (cadr a) (cadr b)))))
  18.   (setq todoLst
  19.     (apply
  20.       'append
  21.       (mapcar
  22.         '(lambda (itm / lst) (repeat (car itm) (setq lst (cons (cadr itm) lst))))
  23.         todoLst
  24.       )
  25.     )
  26.   )
  27.   (setq resLst (Roy_Cut todoLst standLen))
  28.   (print resLst)
  29.   (princ
  30.     (strcat
  31.       "\n\n"
  32.       (itoa (apply '+ (mapcar 'car resLst)))
  33.       " Standard lengths "
  34.     )
  35.   )
  36.   (princ)
  37. )
  38.  
  39. ; (Roy_Cut '(9 9 3 2 2 2 2 1 1) 12)
  40. ; Format of return:
  41. ; ((numberOfOccurences (pattern as list of lengths) totalWaste) ...)
  42. (defun Roy_Cut (todoLst standLen / doneLst patternAndRest tmpLst)
  43.   (while todoLst
  44.     (setq patternAndRest
  45.       (car
  46.         (Roy_Cut_PatternsSort
  47.           (Roy_Cut_Patterns
  48.             (cdr todoLst)
  49.             (list (car todoLst))
  50.             (- standLen (car todoLst))
  51.           )
  52.         )
  53.       )
  54.     )
  55.     (setq tmpLst (Roy_Cut_RemovePattern todoLst (car patternAndRest)))
  56.     (setq doneLst
  57.       (cons
  58.         (list
  59.           (cadr tmpLst)        ; Number of occurences.
  60.           (car patternAndRest) ; Pattern.
  61.           (* (cadr tmpLst) (cadr patternAndRest)) ; Total waste.
  62.         )
  63.         doneLst
  64.       )
  65.     )
  66.     (setq todoLst (car tmpLst))
  67.   )
  68.   (reverse doneLst)
  69. )
  70.  
  71. ; (Roy_Cut_Patterns '(9 3 3 3 2 2 1) '(9) 3)
  72. ;   => (((9 3) 0) ((9 3) 0) ((9 3) 0) ((9 2 1) 0) ((9 2 1) 0) ((9 1 1) 1))
  73. (defun Roy_Cut_Patterns (todoLst doneLst rest)
  74.   (cond
  75.     (
  76.       (apply
  77.         'append
  78.         (mapcar
  79.           '(lambda (len)
  80.             (if (<= len rest)
  81.               (Roy_Cut_Patterns
  82.                 (setq todoLst (cdr todoLst))
  83.                 (append doneLst (list len))
  84.                 (- rest len)
  85.               )
  86.             )
  87.           )
  88.           todoLst
  89.         )
  90.       )
  91.     )
  92.     (
  93.       (list (list doneLst rest))
  94.     )
  95.   )
  96. )
  97.  
  98. ; (Roy_Cut_PatternsSort (Roy_Cut_Patterns '(9 3 3 3 2 2 1) '(9) 3))
  99. ;   => (((9 3) 0) ((9 2 1) 0) ((9 1 1) 1))
  100. (defun Roy_Cut_PatternsSort (lst)
  101.     (_List_DuplicateRemoveAll lst) ; Required.
  102.     '(lambda (a b)
  103.       (or
  104.         (< (cadr a) (cadr b)) ; Compare rest.
  105.         (and
  106.           (= (cadr a) (cadr b))
  107.           (< (length (car a)) (length (car b))) ; Compare number of lengths.
  108.         )
  109.       )
  110.     )
  111.   )
  112. )
  113.  
  114. ; (Roy_Cut_PatternIndexList '(9 9 3 3 3 2 2 1) '(3 2)) => (2 5)
  115. (defun Roy_Cut_PatternIndexList (todoLst pattern / idx idxLst)
  116.   (setq idx -1)
  117.   (if
  118.     (not
  119.       (vl-position
  120.         nil
  121.         (setq idxLst
  122.           (mapcar
  123.             '(lambda (itm / fndIdx)
  124.               (if (setq fndIdx (vl-position itm todoLst))
  125.                 (progn
  126.                   (setq todoLst (cdr (member itm todoLst)))
  127.                   (setq idx (+ fndIdx idx 1))
  128.                 )
  129.               )
  130.             )
  131.             pattern
  132.           )
  133.         )
  134.       )
  135.     )
  136.     idxLst
  137.   )
  138. )
  139.  
  140. ; Format of return:
  141. ; (newTodoLst numberOfOccurences)
  142. (defun Roy_Cut_RemovePattern (todoLst pattern / cnt idxLst)
  143.   (setq cnt 0)
  144.   (while (setq idxLst (Roy_Cut_PatternIndexList todoLst pattern))
  145.     (setq cnt (1+ cnt))
  146.     (setq todoLst (_List_IndexListRemove todoLst idxLst))
  147.   )
  148.   (list todoLst cnt)
  149. )
  150.  
  151. ;;; Library stuff:
  152.  
  153. ; (_List_DuplicateRemoveAll '(nil (1 1) nil (1 1) 3 5 6 7 3 7 7 3 nil)) => (NIL (1 1) 3 5 6 7)
  154. (defun _List_DuplicateRemoveAll (lst / ret)
  155.   (mapcar
  156.     '(lambda (itm) (if (not (vl-position itm ret)) (setq ret (cons itm ret))))
  157.     lst
  158.   )
  159.   (reverse ret)
  160. )
  161.  
  162. ; (_List_IndexListRemove '("a" "b" "c" "d" "e" "f") '(0 1 5)) => ("c" "d" "e")
  163. (defun _List_IndexListRemove (lst idxLst)
  164.   (apply ; A (vl-remove nil ...) structure is impossible here.
  165.     'append
  166.     (mapcar
  167.       '(lambda (idx itm) (if (not (vl-position idx idxLst)) (list itm)))
  168.       (_List_IndexSeqMakeLength (length lst))
  169.       lst
  170.     )
  171.   )
  172. )
  173.  
  174. ; Make a zero based list of integers.
  175. ; With speed improvement based on Reini Urban's (std-%setnth).
  176. ; (_List_IndexSeqMakeLength 7) => (0 1 2 3 4 5 6)
  177. (defun _List_IndexSeqMakeLength (len / ret)
  178.   (repeat (rem len 4)
  179.     (setq ret (cons (setq len (1- len)) ret))
  180.   )
  181.   (repeat (/ len 4)
  182.     (setq ret
  183.       (vl-list*
  184.         (- len 4)
  185.         (- len 3)
  186.         (- len 2)
  187.         (- len 1)
  188.         ret
  189.       )
  190.     )
  191.     (setq len (- len 4))
  192.   )
  193.   ret
  194. )
  195.  

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: The Cutting Stock Problem (Optimizing Cutting of Rebar or Other Material)
« Reply #28 on: September 16, 2015, 02:32:13 PM »
First conclusion: Ymg's code is much more efficient than my poor attempt. In some cases my code even has memory issues...

ymg

  • Guest
Re: The Cutting Stock Problem (Optimizing Cutting of Rebar or Other Material)
« Reply #29 on: September 17, 2015, 04:51:18 AM »
roy,

The problem itself is quite hard, np hard as a matter of fact.

The algorithm by Dikili and Barlas works some of the time.
Binpack works also some of the time (More or less 90%)

The evolutive algorithm that I've proposed works quite well
but is much slower.  However in this particular example after
10000 generations and 1 hour of running time, it still had not found
the solution with 137 bars.  Would probably converge if I leave it
enough time.

ymg