免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: cobras
打印 上一主题 下一主题

[算法] 01背包问题如何求得最佳取法,而不仅是最大价值。 [复制链接]

论坛徽章:
35
双子座
日期:2014-05-09 17:56:38程序设计版块每日发帖之星
日期:2015-08-30 06:20:00程序设计版块每日发帖之星
日期:2015-12-24 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-27 11:07:07程序设计版块每日发帖之星
日期:2016-01-12 06:20:0015-16赛季CBA联赛之北京
日期:2016-01-15 01:01:2115-16赛季CBA联赛之浙江
日期:2016-01-15 22:38:20程序设计版块每日发帖之星
日期:2016-01-18 06:20:00每日论坛发贴之星
日期:2016-01-18 06:20:0015-16赛季CBA联赛之北控
日期:2016-01-30 21:43:01程序设计版块每日发帖之星
日期:2016-02-08 06:20:0015-16赛季CBA联赛之山西
日期:2016-02-20 10:54:41
11 [报告]
发表于 2014-08-29 11:59 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
12 [报告]
发表于 2014-08-30 14:25 |只看该作者
发个背包问题贪心算法与动态规划比较。少数情况下贪心算法不能求最佳答案。
  1. /* knapsack.c */

  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <time.h>

  6. struct item
  7. {
  8.         int choosed;
  9.         int id;
  10.         int size;
  11.         int value;
  12. };

  13. struct item *create_items(int count)
  14. {
  15.         struct item *items;
  16.         int size;

  17.         size = count * sizeof(struct item);
  18.         items = (struct item *)malloc(size);
  19.         if (items != NULL) {
  20.                 memset(items, 0, size);
  21.                 return items;
  22.         }
  23.         return NULL;
  24. }

  25. int generate_items(struct item *items, int count)
  26. {
  27.         int i;

  28.         memset(items, 0, count * sizeof(struct item));
  29.         srand(time(NULL));
  30.         for (i = 0; i < count; ++i) {
  31.                 items[i].choosed = 0;
  32.                 items[i].id = i;
  33.                 items[i].size = rand() % 100 + 1;
  34.                 items[i].value = rand() % 100;
  35.         }
  36.         return 0;
  37. }

  38. int release_items(struct item *items)
  39. {
  40.         free(items);
  41.         return 0;
  42. }

  43. int compare_item_value(const struct item *item1, const struct item *item2)
  44. {
  45.         long data1, data2;

  46.         data1 = item1->value * item2->size;
  47.         data2 = item2->value * item1->size;
  48.         if (data1 < data2) {
  49.                 return 1;
  50.         }else if (data1 > data2) {
  51.                 return -1;
  52.         }else {
  53.                 return 0;
  54.         }
  55. }

  56. int compare_item_id(const struct item *item1, const struct item *item2)
  57. {
  58.         if (item1->id < item2->id) {
  59.                 return -1;
  60.         }else if (item1->id > item2->id) {
  61.                 return 1;
  62.         }else {
  63.                 return 0;
  64.         }
  65. }

  66. int compare_item_c(const struct item *item1, const struct item *item2)
  67. {
  68.         if (item1->size < item2->size) {
  69.                 return -1;
  70.         }else if (item1->size > item2->size) {
  71.                 return 1;
  72.         }else {
  73.                 return 0;
  74.         }
  75. }

  76. int choose_items(struct item *items, int count, int capability)
  77. {
  78.         int i;

  79.         for (i = 0; i < count; ++i) {
  80.                 if (items[i].size <= capability) {
  81.                         items[i].choosed = 1;
  82.                         capability -= items[i].size;
  83.                 }
  84.         }
  85.         return 0;
  86. }

  87. int print_items(struct item *items, int count)
  88. {
  89.         int i;

  90.         for (i = 0; i < count; ++i) {
  91.                 printf("id=%d, size=%d, value=%d, %d\n", items[i].id, items[i].size, items[i].value, items[i].choosed);
  92.         }
  93.         return 0;
  94. }

  95. int knapsack_items(struct item *items, int count, int capability)
  96. {
  97.         int *f;
  98.         int *line;
  99.         int i;
  100.         int j;
  101.         int size;
  102.         int value;

  103.         size = count * (capability + 1) * sizeof(int);
  104.         f = (int *)malloc(size);
  105.         if (f != NULL) {
  106.                 memset(f, 0, size);
  107.                 line = f + (count - 1) * (capability + 1);
  108.                 for (j = 0; j <= capability; j++) {
  109.                         if(j < items[count - 1].size) {
  110.                                 line[j] = 0;
  111.                         }else {
  112.                                 line[j] = items[count - 1].value;
  113.                         }
  114.                 }
  115.                 for(i = count - 2; i >= 0; i--) {
  116.                         line -= capability + 1;
  117.                         for (j = 0; j <= capability; j++) {
  118.                                 if(j < items[i].size) {
  119.                                         line[j] = (line + capability + 1)[j];
  120.                                 }else {
  121.                                         line[j] = (line + capability + 1)[j] > (line + capability + 1)[j-items[i].size] + items[i].value ? (line + capability + 1)[j] : (line + capability + 1)[j-items[i].size] + items[i].value;
  122.                                 }
  123.                         }
  124.                 }
  125.                 value = line[capability];

  126.                 j = capability;
  127.                 for(i = 0; i <= count - 2; i++) {
  128.                         if(f[i * (capability + 1) + j] == f[(i + 1) * (capability + 1) + j]) {
  129.                                 items[i].choosed = 0;
  130.                         }else {
  131.                                 items[i].choosed = 1;
  132.                                 j = j - items[i].size;
  133.                         }
  134.                 }
  135.                 items[count - 1].choosed = f[(count - 1) * (capability + 1) + j] ? 1 : 0;
  136.                 free(f);
  137.                 return value;
  138.         }
  139.         return -1;
  140. }

  141. int clear_items_choose(struct item *items, int count)
  142. {
  143.         int i;

  144.         for (i = 0; i < count; ++i) {
  145.                 items[i].choosed = 0;
  146.         }
  147.         return 0;
  148. }

  149. int sum_choosed_item_value(struct item *items, int count)
  150. {
  151.         int i;
  152.         int sum;

  153.         sum = 0;
  154.         for (i = 0; i < count; ++i) {
  155.                 if (items[i].choosed) {
  156.                         sum += items[i].value;
  157.                 }
  158.         }
  159.         return sum;
  160. }

  161. int sum_choosed_item_capability(struct item *items, int count)
  162. {
  163.         int i;
  164.         int sum;
  165.        
  166.         sum = 0;
  167.         for (i = 0; i < count; ++i) {
  168.                 if (items[i].choosed) {
  169.                         sum += items[i].size;
  170.                 }
  171.         }
  172.         return sum;
  173. }

  174. int main(void)
  175. {
  176.         struct item *items;
  177.         int count;
  178.         int capability;
  179.         int value;
  180.         int a_value;
  181.         int cnt;

  182.         count = 10;
  183.         capability = 100;
  184.         printf("Please Input (Count, Capability): ");
  185.         scanf("%d %d", &count, &capability);
  186.         printf("N=%d, V=%d\n", count, capability);
  187.         items = create_items(count);
  188.         if (items != NULL) {
  189.                 cnt = 1;
  190.                 do {
  191.                         generate_items(items, count);
  192.                         printf("-------------- ITEM %d -------------\n", cnt);

  193.                         qsort(items, count, sizeof(struct item), (int(*)(const void*,const void*))compare_item_value);
  194.                         choose_items(items, count, capability);
  195.                         print_items(items, count);
  196.                         a_value = sum_choosed_item_value(items, count);
  197.                         printf("Choosed value: %d\n", a_value);
  198.                         printf("SUM choosed capability: %d\n", sum_choosed_item_capability(items, count));

  199.                         clear_items_choose(items, count);
  200.                         value = knapsack_items(items, count, capability);
  201.                         print_items(items, count);
  202.                         printf("KNAPSACK VALUE: %d\n", value);
  203.                         printf("SUM choosed capability: %d\n", sum_choosed_item_capability(items, count));
  204.                         ++cnt;
  205.                 }while (a_value == value);
  206.                 release_items(items);
  207.                 return 0;
  208.         }
  209.         return -1;
  210. }
复制代码

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
13 [报告]
发表于 2014-08-30 19:32 |只看该作者
cobras 发表于 2014-08-30 14:25
发个背包问题贪心算法与动态规划比较。少数情况下贪心算法不能求最佳答案。


哥们,我刚刚也实现了一个贪心算法和动态规划的对比,只要很少的情况下,贪心算法是不能得到最优解的,而且即使得不到最优解,也是相差很小的。

我实现了Matlab和C++两个版本。。。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
14 [报告]
发表于 2014-08-30 20:34 |只看该作者
回复 12# cobras

有空帮我看看,不保证对错,不过咱俩的结论基本一致。

http://bbs.chinaunix.net/thread-4152500-1-1.html

   

论坛徽章:
12
射手座
日期:2014-10-02 11:31:29程序设计版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-27 06:20:00程序设计版块每日发帖之星
日期:2016-05-27 06:20:00程序设计版块每日发帖之星
日期:2016-05-25 06:20:00每日论坛发贴之星
日期:2016-05-24 06:20:00程序设计版块每日发帖之星
日期:2016-05-24 06:20:0015-16赛季CBA联赛之深圳
日期:2016-05-23 15:33:59程序设计版块每日发帖之星
日期:2016-05-20 06:20:00程序设计版块每日发帖之星
日期:2016-04-26 06:20:00神斗士
日期:2015-12-03 09:27:3215-16赛季CBA联赛之八一
日期:2016-12-29 09:56:05
15 [报告]
发表于 2014-09-02 16:15 |只看该作者
哈哈。这个问题,
有意思,我感觉百思不得其解。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP