数値合わせ

 投稿者:しばっち  投稿日:2009年 5月10日(日)15時44分24秒
  目標値を越えず、数値の合計値が最大(目標値との差が最小)
となる数値の組み合わせを求める

組み合わせを利用して探索する

N個の中から1個選ぶ組み合わせ
N個の中から2個選ぶ組み合わせ
N個の中から3個選ぶ組み合わせ
            :
N個の中からN個選ぶ組み合わせ

総探索数は COMB(N,1)+COMB(N,2)+...+COMB(N,N)=2^N-1

DECLARE EXTERNAL FUNCTION COMB
PUBLIC NUMERIC MAXSIZE,MSIZE,B(20),EPS
PUBLIC STRING T$(20),TT$(20)
DIM A(20),C(20),TI$(20),TEMP(20) !'個数は10~15程度を想定
LET N=1
LET EPS=0
LET SUM=0
DO
   INPUT  PROMPT "数値(" & STR$(N) & ") ":A(N) !'(ファイルサイズ、演奏時間等)
   IF A(N)=0 THEN !' 0で入力終了
      LET N=N-1
      EXIT DO
   END IF
   LET SUM=SUM+A(N)
   !' INPUT  PROMPT "タイトル(" & STR$(N) & ") ":T$(N) !'(ファイル名、曲名等)
   LET N=N+1
LOOP
INPUT  PROMPT "目標値=":MAXSIZE !'(メディア容量、空き容量等)
IF MAXSIZE >= SUM THEN
   CALL DISPLAY(N,A,T$)
   STOP
END IF
!' INPUT  PROMPT "許容範囲=":EPS !'目標値 - 合計値 <= 許容範囲 となる組み合わせの表示
LET MMIN=MAXSIZE
LET K=0
DO
   LET K=K+1
   FOR I=1 TO N
      IF A(I) >= MAXSIZE/K THEN EXIT DO
   NEXT I
LOOP UNTIL K=N
FOR R=K TO N-1
   LET MSIZE=MAXSIZE
   MAT TEMP=ZER
   LET RR=R
   CALL COMB(A,N,RR,TEMP,1)
   IF MSIZE < MMIN THEN
      LET MMIN=MSIZE
      MAT C=B
      MAT TI$=TT$
   END IF
NEXT R
IF MMIN > 0 THEN CALL DISPLAY(N,C,TI$)
END

EXTERNAL SUB COMB(X(),N,R,A(),K)
IF R=0 THEN
   LET S=0
   FOR I=1 TO N
      IF A(I)=1 THEN
         LET S=S+X(I)
      END IF
      IF S > MAXSIZE THEN EXIT SUB
   NEXT I
   IF MAXSIZE >= S AND MAXSIZE-S <= MSIZE THEN
      LET MSIZE=MAXSIZE-S
      MAT B=ZER
      MAT TT$=NUL$
      LET M=0
      FOR J=1 TO N
         IF A(J)=1 THEN
            LET M=M+1
            LET B(M)=X(J)
            LET TT$(M)=T$(J)
         END IF
      NEXT  J
      IF MSIZE <= EPS THEN
         CALL DISPLAY(N,B,TT$)
      END IF
   END IF
ELSE
   FOR I=K TO N-R+1
      LET A(I)=1
      CALL COMB(X,N,R-1,A,I+1)
      LET A(I)=0
   NEXT I
END IF
END SUB

EXTERNAL  SUB DISPLAY(N,A(),K$())
LET S=0
FOR I=1 TO N
   IF A(I)<>0 THEN
      PRINT "No.";I;":";A(I);"  ";K$(I)
      LET S=S+A(I)
   END IF
NEXT I
PRINT "計";S;"残差";MAXSIZE-S
END SUB

ex.1
目標値と合計値との差が最小となる組み合わせ

37  39  43  69  75  81  88  108  120  122  128
目標値 700

ex.2
必ずしも目標値と合計値は一致しない

20  23  26  44  54  58  75  78  90  95  110  132
目標値 700
 

戻る