Recursion 方案中的0/1背包

Recursion 方案中的0/1背包,recursion,scheme,knapsack-problem,Recursion,Scheme,Knapsack Problem,在scheme中编程背包问题,我的思路是正确的吗?我的程序不必考虑对象的“值”,只考虑它们的权重。我们的目标是采取最好的组合项目,使我有大约一半的重量在我的包 (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))

在scheme中编程背包问题,我的思路是正确的吗?我的程序不必考虑对象的“值”,只考虑它们的权重。我们的目标是采取最好的组合项目,使我有大约一半的重量在我的包

(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)))

我很想写我的程序来输出一个包含所有可能的不同权重组合的列表,然后遍历该列表,直到找到最佳权重集,但不确定如何实现这一点。

因为这已经是您第二次尝试了(第一个问题被删除),我将在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)))

希望这有帮助。如果有什么你不懂的,不要犹豫问问题

你的想法是对的;计算所有组合,然后找到最接近(总重量)/2的组合。可能有多个组合具有正确的权重,因此结果应该是一个组合列表。试着先做组合部分。你介意解释一下你答案中的“for/fold”部分吗?如果它更接近目标重量,那么这篇文章是否只是通过“combs”函数将delta设置为newdelta来遍历您创建的列表?是的。delta和res被初始化(一次),然后c被依次设置为combs的每个组合。结果是(值delta res)。
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