免费注册 查看新帖 |

Chinaunix

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

[算法] 最佳组合算法 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-09-10 14:43 |只看该作者
可以用动态规划,计算出所有可能的结果,再取适当的。

论坛徽章:
0
12 [报告]
发表于 2006-09-10 23:01 |只看该作者
思路却是应该是动态规划,但是现在如果让这一段程序在单片机中间运行呢?采用复杂的算法单片机不可能运算出来的!

论坛徽章:
0
13 [报告]
发表于 2006-09-11 09:33 |只看该作者
大概想了一下。
1、讲所有的数排序从大到小。
2、讲给定的数从排序数组第一个开始比较,得到第一个小于给定数的值,将其和给定数差作为第二给定数,重复步骤2,直到无法在数组中找出给定数。

论坛徽章:
0
14 [报告]
发表于 2006-09-11 09:44 |只看该作者
procedure seek()
read_array();
sort_array(desc);
read(given_num);
printf("%d=",given_num);
while (given_num>0)
{
     for(i=0;i<array_len;i++)
    {
        if array(i)<=given_num break;
    }
    if (i!=array_len && array(i)<=given_num)
    {
           printf("%d ",array(i));
           given_num-=array(i);
     }
}
printf("\n");

论坛徽章:
0
15 [报告]
发表于 2006-09-11 12:46 |只看该作者
组合问题也许是算法当中最难的一类问题了。。。

论坛徽章:
0
16 [报告]
发表于 2006-09-11 12:54 |只看该作者
查表吧,反正也只有100以内的数,最多使用100个数组...如果你的单片机能放得下这100个数组。。

论坛徽章:
0
17 [报告]
发表于 2006-09-11 13:50 |只看该作者
对了我给的近似算法。会出现下面例外。
假设我的算法求出解序列a0,a1,a2...,an(降序数列),原数列为list[0]....list[n](降序数列)。并有sum(a[i])+t=K(K是给定数)。从我的算法可以知道t比小于list[n],有可能存在a[x]<list[i]+list[j]<=a[x]+t。那么list[i],list[j]将取代a[x]。反复应用取代,得出最优解。

论坛徽章:
0
18 [报告]
发表于 2006-09-11 15:11 |只看该作者
很朴素的背包问题了,集合{s0,s1,s3...sn},给定的目标数m,
复杂度O(n*(m+min(m,max{si})))=O(nm)
200个位就行了,如果要记录解,就多一个大小200的数组

论坛徽章:
0
19 [报告]
发表于 2006-09-11 16:50 |只看该作者
发个测试版的
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. float list[]={47,33,22,22,10,5,4.7,7.2};
  7. int *result=NULL,*test=NULL;
  8. int list_size=8,result_size=0,test_size=0;
  9. float given_num,t,k;
  10. int i,j;
  11. int comp( const void *arg1, const void *arg2 )
  12. {
  13.         if (list[*(const int *)arg1]>list[*(const int *)arg2]) return -1;
  14.         if (list[*(const int *)arg1]<list[*(const int *)arg2]) return 1;
  15.         return 0;
  16. }

  17. int compF( const void *arg1, const void *arg2 )
  18. {
  19.         if (*(const int *)arg1>*(const int *)arg2) return -1;
  20.         if (*(const int *)arg1<*(const int *)arg2) return 1;
  21.         return 0;
  22. }

  23. int insertNum(int num)
  24. {
  25.         int *temp;
  26.         int i;
  27.         for(i=0;i<result_size;i++)
  28.         if (result[i]==num) return 0;
  29.         temp=(int *)calloc(result_size+1,sizeof(int));
  30.         if (temp==NULL)
  31.         {
  32.                 fprintf(stderr,"memory overflow in insertNum, result size is %d\n",result_size);
  33.                 free(result);
  34.                 exit(1);       
  35.         }
  36.         memcpy(temp,result,sizeof(int)*result_size);
  37.         temp[result_size++]=num;
  38.         free(result);
  39.         result=temp;
  40.         qsort(result,result_size,sizeof(int),comp);
  41.         return 1;
  42.        
  43. }
  44. int insertTestNum(float num)
  45. {
  46.         int *temp;
  47.         int i;
  48.         for(i=0;i<test_size;i++)
  49.         if (test[i]==num) return 0;
  50.         for(i=0;i<result_size;i++)
  51.         if (result[i]==num) return 0;
  52.         temp=(int *)calloc(test_size+1,sizeof(int));
  53.         if (temp==NULL)
  54.         {
  55.                 fprintf(stderr,"memory overflow in insertNum, test size is %d\n",test_size);
  56.                 free(test);
  57.                 free(result);
  58.                 exit(1);       
  59.         }
  60.         memcpy(temp,test,sizeof(int)*test_size);
  61.         temp[test_size++]=num;
  62.         free(test);
  63.         test=temp;
  64.         qsort(test,test_size,sizeof(int),comp);
  65.         return 1;
  66.        
  67. }


  68. float sumArray(int * array,int array_size)
  69. {
  70.         int i;
  71.         float sum;
  72.         sum=0;
  73.         for(i=0;i<array_size;i++) sum+=list[array[i]];
  74.         return sum;
  75. }

  76. void showArray(int *array, int array_size)
  77. {
  78.         int i;
  79.         float sum;
  80.         sum=0;
  81.         for(i=0;i<array_size;sum+=list[array[i]],i++) printf("%3.3f ",list[array[i]]);
  82.         printf("total:%3.3f\n",sumArray(array,array_size));       
  83. }


  84. int main(void)
  85. {
  86.         float sum;
  87.         qsort(list,list_size,sizeof(float),compF);
  88.         given_num=k=50;
  89.         for (i=0;i<list_size;i++)
  90.         {
  91.                 if (list[i]>k) continue;
  92.                 if (insertNum(i)) k-=list[i];
  93.         }
  94.         showArray(result,result_size);
  95.         i=0;
  96.         while(i<result_size)
  97.         {
  98.                 if(test!=NULL) free(test);
  99.                 test_size=0;
  100.                 t=given_num-sumArray(result,result_size);
  101.                 k=list[result[i]]+t;
  102.                 for(j=result[i]+1;j<list_size;j++)
  103.                 {
  104.                         if (k<list[j]) continue;
  105.                         if (insertTestNum(j)) k-=list[j];
  106.                 }
  107.                 sum=sumArray(test,test_size);
  108.                 if (list[result[i]]<=t+sum && sum>list[result[i]])
  109.                 {
  110.                         for(j=0;j<test_size;j++)
  111.                         {
  112.                                 if (j>0) insertNum(test[j]);
  113.                                 else result[i]=test[j];
  114.                         }
  115.                 }
  116.                 if (k==0) break;
  117.                 i++;
  118.         }
  119.         showArray(result,result_size);
  120.         if (result!=NULL) free(result);
  121.         if (test!=NULL) free(test);
  122. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP