我是否正在计划方案中的背包问题?我的程序不必考虑对象“值”,只考虑它们的权重。我们的目标是采用最好的物品组合,这样我的包里就有大约一半的重量。
(define (split-equip wlst)
(define (sum lst)
(define (sum-h accum lst1)
(if (null? lst)
(/ accum (length lst))
(sum-h (+ (car lst1) accum) (cdr lst1))))
(sum-h 0 lst))
(define (split-equip-h)
(let ((target-w (/ (sum wlst) 2)))
我很想编写我的程序来输出一个列表,其中包含所有不同权重组合,然后遍历列表,直到找到最佳权重集,但不知道如何实现这一点。
答案 0 :(得分:1)
由于这已经是您的第二次尝试(第一个问题被删除),我将向您展示Racket中的解决方案。您应该像伪代码一样阅读它,并将其翻译成您所教授的Scheme变体。
免责声明:我很喜欢这种练习。这应该是你理解和重新制定这个的另一个原因。但我的代码结果似乎仍然正确。
以下是代码:
#lang racket
(define (knapsack lst)
(define half (/ (apply + lst) 2)) ; compute half of total
(printf "list : ~a\nhalf : ~a\n" lst half)
(define (combs lst1 (lst2 null)) ; compute all the combinations
(if (null? lst1)
(if (null? lst2)
null
(list (reverse lst2)))
(append
(combs (cdr lst1) lst2) ; case 1 -> we don't carry the iten
(combs (cdr lst1) (cons (car lst1) lst2))))) ; case 2 -> we do
(for/fold ((delta half) (res null)) ((c (in-list (combs lst)))) ; determine the best fit
(let* ((sm (apply + c)) (newdelta (abs (- half sm))))
(cond
((< newdelta delta) (values newdelta (list c)))
((= newdelta delta) (values delta (cons c res)))
(else (values delta res))))))
(time
(let-values (((delta res) (knapsack (cdr (range 0 24 3)))))
(printf "result: ~a\ndelta : ~a\n" res delta)))
以及它的内容:
list : (3 6 9 12 15 18 21)
half : 42
result: ((3 6 12 21) (3 6 15 18) (3 9 12 18) (3 18 21) (6 9 12 15) (6 15 21) (9 12 21) (9 15 18))
delta : 0
cpu time: 6 real time: 5 gc time: 0
希望这会有所帮助。如果你有什么不明白的话,不要犹豫提问!