0/1背包问题的分支定界法算法

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. #define  MAXNUM   100
  5.  
  6. struct node {
  7.     int step ;
  8.     double price ;
  9.     double weight ;
  10.     double max, min ;
  11.     unsigned long po ;
  12. } ;
  13.  
  14. typedef struct node DataType ;
  15. struct  SeqQueue {         /* 顺序队列类型定义 */
  16.     int  f, r ;
  17.     DataType  q [MAXNUM ] ;
  18. } ;
  19. typedef   struct SeqQueue *PSeqQueue ;    
  20.  
  21.  
  22. PSeqQueue createEmptyQueue_seq ( void ) {  
  23.     PSeqQueue paqu ;
  24.     paqu = (PSeqQueue ) malloc ( sizeof ( struct SeqQueue )) ;
  25.     if (paqu == NULL )
  26.         printf ( “Out of space!! /n ) ;
  27.     else
  28.         paqu >f = paqu >r = 0 ;
  29.  
  30.     return paqu ;
  31. }
  32.  
  33. int  isEmptyQueue_seq ( PSeqQueue paqu ) {
  34.     return paqu >f == paqu >r ;
  35. }
  36.  
  37. /* 在队列中插入一元素x */
  38. void  enQueue_seq ( PSeqQueue paqu, DataType x ) {
  39.     if ( (paqu >r + 1 ) % MAXNUM == paqu >f   )
  40.         printf ( “Full queue./n ) ;
  41.     else {
  42.         paqu >q [paqu >r ] = x ;
  43.         paqu >r = (paqu >r + 1 ) % MAXNUM ;
  44.     }
  45. }
  46.  
  47. /* 删除队列头元素 */
  48. void  deQueue_seq ( PSeqQueue paqu ) {
  49.     if ( paqu >f == paqu >r )
  50.         printf ( “Empty Queue./n ) ;
  51.     else
  52.         paqu >f = (paqu >f + 1 ) % MAXNUM ;
  53. }
  54.  
  55. /* 对非空队列,求队列头部元素 */
  56. DataType  frontQueue_seq ( PSeqQueue paqu ) {
  57.     return (paqu >q [paqu >f ]) ;
  58. }
  59.  
  60. /* 物品按性价比从新排序*/
  61. void sort ( int n, double p [], double w []){
  62.     int i, j ;
  63.     for (i = 0 ; i < n 1 ; i ++ )
  64.         for (j = i ; j < n 1 ; j ++ ) {
  65.             double a = p [j ] /w [j ] ;
  66.             double b = p [j + 1 ] /w [j + 1 ] ;
  67.             if (a < b ) {
  68.                 double temp = p [j ] ;
  69.                 p [j ] = p [j + 1 ] ;
  70.                 p [j + 1 ] = temp ;
  71.                 temp = w [j ] ;
  72.                 w [j ] = w [j + 1 ] ;
  73.                 w [j + 1 ] = temp ;
  74.             }
  75.         }
  76. }
  77.  
  78. /* 求最大可能值*/
  79. double up ( int k, double m, int n, double p [], double w []){
  80.     int i = k ;
  81.     double s = 0 ;
  82.     while (i < n && w [i ] < m ) {
  83.         m = w [i ] ;
  84.         s + = p [i ] ;
  85.         i ++ ;
  86.     }
  87.     if (i < n && m > 0 ) {
  88.         s + = p [i ] * m / w [i ] ;
  89.         i ++ ;
  90.     }
  91.     return s ;
  92. }
  93.  
  94. /* 求最小可能值*/
  95. double down ( int k, double m, int n, double p [], double w []){
  96.     int i = k ;
  97.     double s = 0 ;
  98.     while (i < n && w [i ] <= m ) {
  99.         m = w [i ] ;
  100.         s + = p [i ] ;
  101.         i ++ ;
  102.     }
  103.     return s ;
  104. }
  105.  
  106. /* 用队列实现分支定界算法*/
  107. double solve ( double m, int n, double p [], double w [], unsigned long * po ){
  108.     double min ;
  109.     PSeqQueue q = createEmptyQueue_seq () ;
  110.     DataType x = { 0, 0, 0, 0, 0, 0 } ;
  111.     sort (n, p, w ) ;
  112.     x. max = up ( 0, m, n, p, w ) ;
  113.     x. min = min = down ( 0, m, n, p, w ) ;
  114.     if (min == 0 ) return 1 ;
  115.     enQueue_seq (q, x ) ;
  116.     while ( !isEmptyQueue_seq (q )){
  117.         int step ;
  118.         DataType y ;
  119.         x = frontQueue_seq (q ) ;
  120.         deQueue_seq (q ) ;
  121.         if (x. max < min ) continue ;
  122.         step = x. step + 1 ;
  123.         if (step == n + 1 ) continue ;
  124.         y. max = x. price + up (step, m x. weight, n, p, w ) ;
  125.         if (y. max >= min ) {
  126.             y. min = x. price + down (step, m x. weight, n, p, w ) ;
  127.             y. price = x. price ;
  128.             y. weight = x. weight ;
  129.             y. step = step ;
  130.             y. po = x. po << 1 ;
  131.             if (y. min >= min ) {
  132.                 min = y. min ;
  133.                 if (step == n ) *po = y. po ;
  134.             }
  135.             enQueue_seq (q, y ) ;
  136.         }
  137.         if (x. weight + w [step 1 ] <= m ) {
  138.             y. max = x. price + p [step 1 ] +
  139.                     up (step, m x. weight w [step 1 ], n, p, w ) ;
  140.             if (y. max >= min ) {
  141.                 y. min = x. price + p [step 1 ] +
  142.                         down (step, m x. weight w [step 1 ], n, p, w ) ;
  143.                 y. price = x. price + p [step 1 ] ;
  144.                 y. weight = x. weight + w [step 1 ] ;
  145.                 y. step = step ;
  146.                 y. po = (x. po << 1 ) + 1 ;
  147.                 if (y. min >= min ) {
  148.                     min = y. min ;
  149.                     if (step == n ) *po = y. po ;
  150.                 }
  151.                 enQueue_seq (q, y ) ;
  152.             }
  153.         }
  154.     }
  155.     return min ;
  156. }
  157.  
  158. #define n 4
  159.  
  160. double m = 15 ;
  161. double p [n ] = { 10, 10, 12, 18 } ;
  162. double w [n ] = { 2, 4, 6, 9 } ;
  163.  
  164. int main () {
  165.     int i ;
  166.     double d ;
  167.     unsigned long po ;
  168.     d = solve (m, n, p, w, &po ) ;
  169.     if (d == 1 )
  170.         printf ( “No solution!/n ) ;
  171.     else {
  172.         for (i = 0 ; i < n ; i ++ )
  173.             printf ( “x%d is %d/n, i + 1, ((po & ( 1 << (n i 1 ))) ! = 0 )) ;
  174.         printf ( “The max weight is %f/n, d ) ;
  175.     }
  176.     getchar () ;
  177.     return 0 ;
  178. }
    原文作者:分支限界法
    原文地址: https://blog.csdn.net/lewutian/article/details/4552213
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞