您的位置:首页 > 其它

蒙特卡洛方法及数学建模算法与应用第二章习题

2016-04-24 00:17 459 查看
蒙特卡洛的方法又称为随机取样法,所以他是根据大量随机数来跑出满意解

比如上一章用遗传算法的完全可以用蒙特卡洛方法(一口血吐出....)

 以下为c语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int check(int x[])
{
if (x[0]+x[1]+x[2]+x[3]+x[4]>400)
return 0;
if (x[0]+2*x[1]+2*x[2]+x[3]+6*x[4]>800)
return 0;
if (2*x[0]+x[1]+6*x[2]>200)
return 0;
if (x[2]+x[3]+5*x[4]>200)
return 0;
return 1;

}
int main()
{
int x[5];
int ans[5];
int i,j,max;
srand(time(NULL));
max=-2;
memset(ans,0,sizeof(ans));
for (i=0;i<100000;i++)
{
for (j=0;j<5;j++)
x[j]=rand()%100;
if (check(x))
if ((x[0]*x[0]+x[1]*x[1]+x[2]*x[2]*3+4*x[3]*x[3]+2*x[4]*x[4]-8*x[0]-2*x[1]-3*x[2]-x[3]-2*x[4])>max)
{
for (j=0;j<5;j++)
ans[j]=x[j];
max=x[0]*x[0]+x[1]*x[1]+x[2]*x[2]*3+4*x[3]*x[3]+2*x[4]*x[4]-8*x[0]-2*x[1]-3*x[2]-x[3]-2*x[4];
}
}
printf("最大值为:%d\n",max);
for (j=0;j<5;j++)
printf("%d ",ans[j]);
}


2.1:
换元,另y=x1*x2,接下来挺难想到的~~

 0<=x1<=1;

0<=x2<=1;

故(x1-1)*(x2-1)>=0

   x1*x2-x1-x2+1>=0

   x1*x2>=x1+x2-1

   y>=x1+x2-1

   (x1-1)*x2<=0

  x1*x2-x2<=0

   y<=x2

   同理得y<=x1

  综上       x1+x2-1<=y<=x1

                 x1+x2-1<=y<=x2

     >> f=[-1 0 1 -1];
>> a=[-2 3 1 0;
      1 1 0 -1;
      -1 0 0 1;
      0 -1 0 1];
>> b=[3;1;0;0];
>> c=[1,2,3,4];
>> [x,fval]=intlinprog(f,c,a,b,[],[],zeros(4,1),ones(4,1))


2.2
   设xi为第i个小区是否被选,选为1,不被选为0

  minz=x1+x2+x3+x4+x5+x6

   对于每一个小区又必须要有一所学校

 x1+x2+x3>=1

x2+x4>=1

x3+x5>=1

x4+x6>=1

x1+x2+x3>=1

x5+x6>=1

x1>=1

x2+x4+x6>=1

>> f=[1,1,1,1,1,1];
>> a=[1,2,3,4,5,6];
>> b=[-1 -1 -1 0 0 0;0 -1 0 -1 0 0;0 0 -1 0 -1 0;0 0 0 -1 0 -1;-1 -1 -1 0 0 0;0 0 0 0 -1 -1;-1 0 0 0 0 0;0 -1 0 -1 0 -1];
>> c=[-1;-1;-1;-1;-1;-1;-1;-1];
>> [x,fval]=intlinprog(f,a,b,c,[],[],zeros(6,1),ones(6,1))

例2.3题目描述貌似有点问题,搜了下答案应该意思是每个企业有且只有1台,每一个设备至少要购入一件。
整数规划问题,用蒙特卡洛方法可解。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
int value[7][5];
void init()
{
value[1][1]=4;
value[1][2]=2;
value[1][3]=3;
value[1][4]=4;
value[2][1]=6;
value[2][2]=4;
value[2][3]=5;
value[2][4]=5;
value[3][1]=7;
value[3][2]=6;
value[3][3]=7;
value[3][4]=6;
value[4][1]=7;
value[4][2]=8;
value[4][3]=8;
value[4][4]=6;
value[5][1]=7;
value[5][2]=9;
value[5][3]=8;
value[5][4]=6;
value[6][1]=7;
value[6][2]=10;
value[6][3]=8;
value[6][4]=6;
}
int check(int x[])
{
int i,j;
int vis[5];
memset(vis,0,sizeof(vis));
for (i=1;i<=6;i++)
vis[x[i]]++;
for (i=1;i<=4;i++)
if (vis[i]==0)
return 0;
return 1;
}
int find(int x[])
{
int sum,i;
sum=0;
for (i=1;i<=6;i++)
sum=sum+value[i][x[i]];
return sum;
}
int main()
{
int i,j,k;
int x[7];
int ans[7];
int max;
srand(time(NULL));
init();
max=-1;
memset(ans,0,sizeof(ans));
for (i=1;i<=10000;i++)
{
for (j=1;j<=6;j++)
x[j]=rand()%4+1;
if (check(x))
if (find(x)>max)
{
max=find(x);
for (j=1;j<=6;j++)
ans[j]=x[j];
}
}
printf("最大值为:%d\n",max);
for (i=1;i<=6;i++)
printf("%d ",ans[i]);

}
最大利润为44 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: