a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 245|回复: 5

[C语言] 2011年计算机等级考试二级C辅导实例编程(3)

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
贪心算法在背包中的应用  贪心法是一种改进了的分级处理方法。用贪心法设计算法的特点是一步一步地进行,根据某个优化测度(可能是目标函数,也可能不是目标函数),每一步上都要保证能获得局部最优解。每一步只考虑一个数据,它的选取应满足局部优化条件。若下一个数据与部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加为止。这种能够得到某种度量意义下的最优解的分级处理方法称为贪心法。9 q# v" I( |9 R: L. H/ ^- b8 D
  选择能产生问题最优解的最优度量标准是使用贪心法的核心问题。
, l/ G6 {. b: i+ A, h7 P3 q( b. z+ d& s
  假定有n个物体和一个背包,物体i 有质量wi,价值为pi,而背包的载荷能力为M。若将物体i的一部分xi(1
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:09 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(3)

  18 {
5 Y$ \7 t3 N* @  19 temp = tempArray[j];3 Y1 f( v- |& x4 b3 w8 h3 l
  20 index = j;
! q* d/ [& ^! E& o  21 }
7 I  p4 R& |. |5 [  22 }$ \0 f% R2 Y4 w* E% M8 {
  232 E# {# y- k( i( Y
  24 //对w排序
9 T! N' `; u6 _  m8 P( B) H  25 swapMemory = w[index];
7 q( }4 _+ @& ]! s3 b! F4 c  26 w[index] = w;6 X# S) s4 d' I' S4 b% @, }
  27 w = swapMemory;* u4 s1 ~2 Y/ c
  28 }, ~) E& o9 l1 q. J9 a8 ?
  29! S8 J- d4 g5 B
  30 return;
8 L. q% ?! N: Q* a$ j  31 }  Y% r2 o- L; P' o
  然而仔细对算法分析后可以发现,“拿来主义”在这里用不上了!! X6 z# v2 i$ ^% h) a
  对算法的测试用例是p[3] = {25, 24, 15};w[3] = {18, 15, 10}。得到的结果如下:
. X' Q; x" p) K7 Y& y( p3 r% _1 e  K  please input the total count of object: 3( G0 F: n. ]9 [: K2 N' G
  Please input array of p :
2 P1 v! S& o. B6 h, u/ ^  25 24 15% c. A% v+ X( i! `/ N; T
  Now please input array of w :
$ S+ t4 [, \$ R# W, r& H- W  18 15 10
1 e1 d8 L6 D' A, k  sortResult is :% m; X; M: D: y2 V1 S  P
  1 -107374176.000000 1 1.600000 2 1.6000003 E1 R$ O8 t; U# V- W( F
  after arithmetic data: x5 m' y8 A& r9 J2 Z0 }+ y) t- P
  0.000000 0.333333 0.000000
" z, l- S# r* J" \7 S" h  可以看到其效益为x[3] = {1.4, 1.6, 1.5},于是在M = 20的情况下,其预想中的输出结果是0,1,0.5。然而事实上是不是就这样呢?
! Y! }# }0 w; ~' B# n* N- h# `" A$ y5 A  当程序进入此函数经过必要的变量初始化后,进入了外围循环,也就是程序的第7行。第一轮循环中,temp = tempArray[0] = 1.4,index = i = 0;程序运行到第15行,也就是进入了内层循环。! z) J) f: l' n9 Q/ A& H
  内层循环的主要任务是从第i + 1个元素之后找到一个最大的效益并保存此时的下标。到了第24行后,就开始对w进行排序。# I1 s, _" f+ p6 ]! w6 U7 ^
  问题就在这里了!排序后的w = {1.6, 1.6, 1.5},因此对w排序后就既改变了w的原有顺序,还改变了w的原来值!
5 k- J. M8 W$ A9 w  据此,做出一些修改,得到了如下的一段代码:
$ O- |8 V. p$ B6 B- a  1 void sort(float tempArray[], int sortResult[], int n)
7 h, T  N; |+ y4 a$ J) u. V  2 {
6 O/ ^& e; L: Y3 v3 R  3 int i = 0, j = 0;
  ~. |0 H/ R5 G. N  Q% v  4 int index = 0, k = 0;0 R  g. K/ J) [- {6 k. Y
  5: R( h# |, ^# m7 t  l
  6 for (i = 0; i < n; i++)//对映射数组赋初值0  e1 g) z) w# T7 g" B8 r- A
  7 {
. M- @/ q# R/ v: d9 M8 R  8 sortResult = 0;, T+ B/ G" g0 h  B
  9 }6 P. T; M# r/ L; U6 @
  10" P! ]& h/ o, N1 }. s
  11 for (i = 0; i < n; i++)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:10 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(3)

 12 {  13 float swapMemory = 0;) h/ L. E0 `: f: j
  14 float temp;
, T6 L+ w7 K+ b3 B  15
# [+ g. @; e; o* u# Q( ]* R9 s  ?  16 temp = tempArray;4 k8 r0 \7 F2 u2 J0 l2 r+ M; `
  17 index = i;1 e4 n7 e# c% S6 [1 I2 m" I5 O
  18
# j; p2 h4 f- N5 P  19 for (j = i; j < n; j++)- g* W0 X9 }' r/ c% w3 I% ^: K
  20 {4 ~7 N1 J) k' l" C! k5 F
  21 if ((temp < tempArray[j]) && (sortResult[j] == 0))
4 @( w2 T5 l1 m# C! Q% V  b  22 {5 Z& ^0 a# d# C% M' E5 a
  23 temp = tempArray[j];3 e+ O* ^( O8 W9 m  W, B* \
  24 index = j;% R5 x$ Z  g& `5 B; T
  25 }
2 ~/ ]3 U7 B$ |4 }4 k  26 }
$ P4 ~2 S! D8 ~. l1 E( a  276 M! g7 c; g) g& z" }) n% J- t
  28 if (sortResult[index] == 0)% \$ W* }& `9 ~. A) F
  29 {& E( n6 t0 w1 b; J
  30 sortResult[index] = ++k;3 S' q/ h' |- X2 ?
  31 }  ?5 Q- i( J8 m. q
  32 }: C5 |' H* m$ T, C
  33
& _4 O+ S5 G) s) U, V  34 for (i = 0; i < n; i++). S. ?# L7 L+ ^. u/ w$ f6 l
  35 {) E  `1 n* a1 g. f( @
  36 if (sortResult == 0)( q4 @2 x+ r5 B  K) c2 d3 J
  37 {; L+ i6 N: ]) Y( C" n  s) S2 e& {
  38 sortResult = ++k;: i2 j+ j' W, Z4 i
  39 }8 H" E( c/ Q6 T1 U
  40 }7 Y, h# ]% }0 Q8 m. V5 |. k
  41- b& O' I5 {+ O& K
  42 return;
- Z$ [4 X; T- b2 s4 F- y* Y9 T  43 }
8 [! l5 {# v" I. e+ f  f4 i4 B5 G  修改后最大的一个改变是没有继续沿用直接对w排序,而是用w的一个映射数组sortResult。sortResult中元素值存放的是根据效益计算得w的大小顺序!这样w原有的值和位置都没有改变,从而使算法得以实现!9 n/ b/ A+ A$ i+ z, [
  至于有没有更好的实现版本,还在探索中!$ S5 ]8 L5 Z# W3 J% ~
  #include
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:11 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(3)

 #define MAXSIZE 100 //假设物体总数  #define M 20 //背包的载荷能力: V* }6 b! a6 x. c) c
  //算法核心,贪心算法" P0 T4 P/ E0 |4 x, V# h
  void GREEDY(float w[], float x[], int sortResult[], int n)
( B& Z! V  O# ^' c+ ~, J8 y: d4 m3 }  {4 J* R! l6 E7 n$ [( v
  float cu = M;& X) s# R( i2 B4 V
  int i = 0;8 s  \3 I! O# a. u; J: s* Z
  int temp = 0;/ I) P4 G' K/ Q5 s" S# f" a0 \8 P
  for (i = 0; i < n; i++)//准备输出结果
& l$ o4 e: e2 B# H7 Q2 |  {( r7 S3 j6 F* n. R2 r
  x = 0;
8 L! K" B5 M1 m6 j; `: h  }& g5 z! c+ U& @) s4 \& O
  for (i = 0; i < n; i++). ]$ ~9 ?7 h& F" L# }7 H
  {- {' R' d! e$ z& Y$ s7 ~6 [
  temp = sortResult;//得到取物体的顺序; a) g2 a! I. q, g
  if (w[temp] > cu)
7 [- w' S8 Z- R0 ~  u  {
+ Z9 ~0 u0 u2 R: V! I  break;9 `7 z9 i2 I$ |1 k& a, L" A5 o
  }( c9 \# m% @" i  w/ Q' d
  x[temp] = 1;//若合适则取出, j% a9 M/ V' |9 h% F
  cu -= w[temp];//将容量相应的改变
6 E9 w/ B2 D% ]. r) y9 E. i  }
( E9 f; f/ T  X9 `5 ]# L* _' F0 ]! i1 F, H2 t
  if (i
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:12 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(3)

{  if ((temp < tempArray[j]) && (sortResult[j] == 0))8 V( j2 L0 Z0 W2 f
  {/ ^# m9 A2 `) y& w. b
  temp = tempArray[j];: ?- w$ r' i0 U/ k7 o
  index = j;
8 l9 l" |  n6 c! {3 T; _  c  }9 d. l. u! V: {& j$ I
  }
& N8 v; p) X' [9 p  i  //对w作标记排序
, m3 I9 h- L3 w& B  if (sortResult[index] == 0)
9 c- G* l  m) C: z  {
6 ?. r1 c7 H! Z( k  sortResult[index] = ++k;+ @, _0 a% g- V4 {1 p5 D" b
  }
4 H$ w0 N, e/ o5 ^9 `& s! Q  }
0 l, I# D3 o- E  //修改效益最低的sortResult标记
& i! x! `- Y' {% g5 D: g  for (i = 0; i < n; i++)2 x3 B/ i1 y/ x1 d* X0 `: P. ~
  {
& C, a/ y7 A3 x) e" t  if (sortResult == 0)
/ N9 @# R$ C: u" Z9 B/ K' v  {
; y* C3 {" v1 m# D  sortResult = ++k;
, v2 O- e# s. E. n$ u0 ~  }! a3 r8 K6 ]5 E
  }
8 `2 O: o& X1 G  return;
2 W. }1 {' i8 p. U. b& _  W  }
& O/ R* O9 x! m% D9 y! K, \) |  //得到本算法的所有输入信息6 e# a5 P8 S1 J$ y
  void getData(float p[], float w[], int *n)
9 E# `, V0 U8 f0 w; G' q' w  {
* A' y; u  l( E1 |  int i = 0;
% v& z5 V/ D( q1 A' k  printf("please input the total count of object: ");
4 S# t# w* Q* M& n* E5 D) }  scanf("%d", n);
  G# u9 P- L& [9 d! m- z9 A3 X/ }  printf("Please input array of p :\n");) @3 H1 |) E5 K# T5 `
  for (i = 0; i < (*n); i++)1 u& @: ?  Q4 {8 o
  {
, `) [- \7 c8 f' z$ M  scanf("%f", &p);
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:13 | 显示全部楼层

2011年计算机等级考试二级C辅导实例编程(3)

  }! j+ K  _0 V9 k% l
  printf("Now please input array of w :\n");  ?5 N- B( y7 J1 \' {- @1 |
  for (i = 0; i < (*n); i++)& I! v0 A6 k0 E: ^( H$ `
  {
! T1 m. m7 x$ @, W( o3 r: Y2 t  scanf("%f", &w);
& _+ p0 N5 }4 a' b  }3 D) Q7 [; C# W
  return;
  _9 `4 e: y, h) {7 y( j$ P2 z  }$ l7 X- n( R: {6 z# S, ~
  void output(float x[], int n)
) n, i2 y# K# @  {4 t6 F. Z) j! x! l
  int i;
6 z5 N: `0 v0 K/ h+ I5 G" b5 F  printf("\n\nafter arithmetic data: advise method\n");
% k; C5 |' f$ D! e- v. l) E  for (i = 0; i < n; i++)# R  {, [1 m% ]8 T, R
  {
/ [5 A7 w7 _: f  [  printf("x[%d]\t", i);
) V# c6 m2 d% x9 q3 w  }* w( A  h0 T- e. W
  printf("\n");
9 e3 y: h7 G/ z7 o# x- g( [  for (i = 0; i < n; i++)
9 }% d+ u, b, q2 g: v  {
. A. d& C9 u) m) X5 ^  printf("%2.3f\t", x);5 u6 D, M* ]2 @! b
  }
$ i0 i2 n) |; p# p  p/ N  return;
* L# _7 ^$ z. @  }
1 U* H: u6 l0 [  void main()5 s0 S% `5 i7 y- h# |3 c4 ^
  {
$ j6 J3 {. u) s4 A  float p[MAXSIZE], w[MAXSIZE], x[MAXSIZE];
. p  i1 A; V9 X: k  int i = 0, n = 0;
+ I! X6 N; n5 w  int sortResult[MAXSIZE];
% c  B( w3 P  x% K5 E  getData(p, w, &n);* n* o/ K, s7 e; H% j: e* Q7 V# A
  for (i = 0; i < n; i++)2 Q8 w# H  J& @7 O9 B0 G2 m
  {, ^+ P& [8 g$ C% t7 q
  x = p / w;
+ R) v! O' v$ W. t% z( O  }/ @/ y: Y1 a, Z; Z6 Y# b6 o
  sort(x, sortResult, n);
# l4 e! O% W0 y1 I" W  GREEDY(w, x, sortResult, n);
' Q! i5 [2 Y' z7 ^* f, Z5 D  output(x, n);
" N2 J3 r4 I' x. m! R6 q. @  getch();: B, t8 u0 B) A, k' W( M
  }
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-6-14 07:03 , Processed in 0.409490 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表