• 主页
• 问答

# 高手来区分几个概念:动态规划、线性规划、最优控制......

qiuzhenguang 百度 学生  2009-08-23 02:29:17

...全文
3232 1 收藏 27

27 条回复

firePhoenix1981 2009-09-01
Mark!

zhongjiekangping 2009-08-28

linren 2009-08-27
[Quote=引用 22 楼 qiuzhenguang 的回复:]
linren 见多识厂，令人佩服！！谢谢你的解答！
[/Quote]

【程序】
``````#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**只用修改这里***********************************/
#define M 6
#define N 8
double tariff[M][N]={//运费
6, 2, 6, 7, 4, 2, 5, 9,
4, 9, 5, 3, 8, 5, 8, 2,
5, 2, 1, 9, 7, 4, 3, 3,
7, 6, 7, 3, 9, 2, 7, 1,
2, 3, 9, 5, 7, 2, 6, 5,
5, 5, 2, 2, 8, 1, 4, 3
};
double product[M]={60,55,51,43,41,52};//产量
double need[N]={35,37,22,32,41,32,43,38};//需求
/***********************************只用修改这里**/

struct ssp{
double p;
int m,n;
};

int compar(const void *a,const void *b){
struct ssp *aa,*bb;
aa=(struct ssp*)a;
bb=(struct ssp*)b;
if((aa->p)>(bb->p)) return 1;
if((aa->p)==(bb->p)) return 0;
return -1;
}

void find_loop(int pmc,int pnc,char* map,int m,int n,struct ssp* pssp,int* k);

void fun(double *tar,double *pro,int m,double *nee,int n){
struct ssp* pssp;
double *t,*pm,*pn;
int i,j,k;
double a,b,c;
char *map,*mpm,*mpn;
int pmc,pnc;

pssp=(struct ssp*)malloc(sizeof(struct ssp)*m*n);
t=(double*)malloc(sizeof(double)*m*n);
pm=(double*)malloc(sizeof(double)*m);
pn=(double*)malloc(sizeof(double)*n);
map=(char*)malloc(sizeof(char)*m*n);
mpm=(char*)malloc(sizeof(char)*m);
mpn=(char*)malloc(sizeof(char)*n);

memset(t,0,sizeof(double)*m*n);
memcpy(pm,pro,sizeof(double)*m);
memcpy(pn,nee,sizeof(double)*n);

/*基本可行解*/
k=0;
for(i=0;i<m;i++){
for(j=0;j<n;j++){
pssp[k].p=*(tar+i*n+j);
pssp[k].m=i;pssp[k].n=j;
k++;
}
}
qsort(pssp,m*n,sizeof(struct ssp),compar);
for(k=0;k<m*n;k++){
a=pm[pssp[k].m];
b=pn[pssp[k].n];
if(a<b){
*(t+pssp[k].m*n+pssp[k].n)=a;
pm[pssp[k].m]=0;pn[pssp[k].n]-=a;
}else{
*(t+pssp[k].m*n+pssp[k].n)=b;
pn[pssp[k].n]=0;pm[pssp[k].m]-=b;
}
}

/*寻找最优解*/
while(1){
memset(map,0,sizeof(char)*m*n);
memset(pm,0,sizeof(double)*m);
memset(pn,0,sizeof(double)*n);
memset(mpm,0,sizeof(char)*m);
memset(mpn,0,sizeof(char)*n);

/*判断方案是否最优*/
k=0;
for(i=0;i<m;i++){
for(j=0;j<n;j++){
if(*(t+i*n+j)!=0){
*(map+i*n+j)=1;
}else{
pssp[k].p=*(tar+i*n+j);
pssp[k].m=i;pssp[k].n=j;
k++;
}
}
}
mpm[0]=1;
pmc=1;pnc=0;
while(pnc!=n||pmc!=m){
for(i=0;i<m;i++){
if(mpm[i]==0) continue;
for(j=0;j<n;j++){
if(*(map+i*n+j)==0) continue;
if(mpn[j]==1) continue;
pn[j]=*(tar+i*n+j)-pm[i];
mpn[j]=1;pnc++;
}
}
for(i=0;i<n;i++){
if(mpn[i]==0) continue;
for(j=0;j<m;j++){
if(*(map+j*n+i)==0) continue;
if(mpm[j]==1) continue;
pm[j]=*(tar+j*n+i)-pn[i];
mpm[j]=1;pmc++;
}
}
}
b=0;j=-1;
for(i=0;i<k;i++){
a=pssp[i].p-pm[pssp[i].m]-pn[pssp[i].n];
if(a<0&&(b==0||a<b)){
b=a;j=i;
}
}
if(j==-1) break;
pmc=pssp[j].m;//记录入基空格坐标
pnc=pssp[j].n;//记录入基空格坐标

/*下一个基本可行解*/
find_loop(pmc,pnc,map,m,n,pssp,&k);
b=0;
for(i=0;i<k;i++){
if(pssp[i].p<0){
a=*(t+pssp[i].m*n+pssp[i].n);
if(b==0||a<b) b=a;
}
}
for(i=0;i<k;i++){
if(pssp[i].p<0){
*(t+pssp[i].m*n+pssp[i].n)-=b;
}else{
*(t+pssp[i].m*n+pssp[i].n)+=b;
}
}
}

/*打印最优解*/
c=0;
printf("【 solution 】\n\n");
for(i=0;i<m;i++){
for(j=0;j<n;j++){
if(*(t+i*n+j)==0) printf("%8s","------");
else printf("%8.3f",*(t+i*n+j));
c+=(*(t+i*n+j))*(*(tar+i*n+j));
}
printf("\n");
}
printf("\ncost: %-8.3f\n\n",c);

free(t);free(pm);free(pn);free(pssp);free(map);free(mpm);free(mpn);
}

void find_loop(int pmc,int pnc,char* map,int m,int n,struct ssp* pssp,int* k){
int i,d,c;
int x,y;
x=pmc;y=pnc;
*(map+x*n+y)=3;
d=1;c=0;
pssp[c].m=x;pssp[c].n=y;pssp[c].p=1;
while(d!=0){
if(d==1){
for(i=0;i<n;i++){
if(c!=0&&*(map+x*n+i)==3){
d=0;break;
}
if(*(map+x*n+i)==1){
*(map+x*n+i)=2;
c++;
d=2;y=i;
pssp[c].m=x;pssp[c].n=y;
if(c%2==0) pssp[c].p=1;
else pssp[c].p=-1;
break;
}
}
if(i==n){
*(map+x*n+y)=0;
d=2;c--;
x=pssp[c].m;
}
}else{
for(i=0;i<m;i++){
if(c!=0&&*(map+i*n+y)==3){
d=0;break;
}
if(*(map+i*n+y)==1){
*(map+i*n+y)=2;
c++;
d=1;x=i;
pssp[c].m=x;pssp[c].n=y;
if(c%2==0) pssp[c].p=1;
else pssp[c].p=-1;
break;
}
}
if(i==m){
*(map+x*n+y)=0;
d=1;c--;
y=pssp[c].n;
}
}
}
*k=c+1;
}

int main(){
fun(&tariff[0][0],product,M,need,N);
return 0;
}``````

【运行结果】
``````【 solution 】

------  19.000  ------  ------  41.000  ------  ------  ------
1.000  ------  ------  32.000  ------  ------  ------  ------
------  11.000  ------  ------  ------  ------  40.000  ------
------  ------  ------  ------  ------   5.000  ------  38.000
34.000   7.000  ------  ------  ------  ------  ------  ------
------  ------  22.000  ------  ------  27.000   3.000  ------

cost: 664.000

Press any key to continue``````

linren 2009-08-26
[Quote=引用 20 楼 linren 的回复:]

[/Quote]

``````please input the data file name: 1.txt

=============Data File================
6.000     2.000     6.000     7.000     4.000     2.000     5.000     9.000
60.000
4.000     9.000     5.000     3.000     8.000     5.000     8.000     2.000
55.000
5.000     2.000     1.000     9.000     7.000     4.000     3.000     3.000
51.000
7.000     6.000     7.000     3.000     9.000     2.000     7.000     1.000
43.000
2.000     3.000     9.000     5.000     7.000     2.000     6.000     5.000
41.000
5.000     5.000     2.000     2.000     8.000     1.000     4.000     3.000
52.000
35.000    37.000    22.000    32.000    41.000    32.000    43.000    38.000
38.000

=============init Solution===================
******    37.000    ******    ******    23.000    ******    ******    ******

******    ******    ******    12.000    18.000    ******     3.000    ******

******    ******    22.000    ******    ******    ******    29.000    ******

******    ******    ******    ******    ******    ******     5.000    38.000

35.000    ******    ******    ******    ******    ******     6.000    ******

******    ******    ******    20.000    ******    32.000    ******    ******

The Cost is: 730.0000

=============Best Solution===================
******    19.000    ******    ******    41.000    ******    ******    ******

1.000    ******    ******    32.000    ******    ******    ******    ******

******    11.000    ******    ******    ******    ******    40.000    ******

******    ******    ******    ******    ******     5.000    ******    38.000

34.000     7.000    ******    ******    ******    ******    ******    ******

******    ******    22.000    ******    ******    27.000     3.000    ******

The min Cost is: 664.0000
Press any key to continue``````

linren 2009-08-26
[Quote=引用 18 楼 qiuzhenguang 的回复:]

[/Quote]

XGJ889 2009-08-26

qiuzhenguang 2009-08-26

qiuzhenguang 2009-08-26
linren 见多识厂，令人佩服！！谢谢你的解答！

Victor_Dinho 2009-08-25

http://zh.wikipedia.org/zh-cn/%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92

16L的链接是http://zh.wikipedia.org/zh-cn/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92

Victor_Dinho 2009-08-25

linren 2009-08-25

fiwiner 2009-08-25

linren 2009-08-25
[Quote=引用 12 楼 linren 的回复:]

[/Quote]

“动态规划最重要的是它的优化原理：”

linren 2009-08-25

qiuzhenguang 2009-08-25
18楼数据排列不整齐，真抱歉，重新贴一下。

A1 6 2 6 7 4 2 5 9 60
A2 4 9 5 3 8 5 8 2 55
A3 5 2 1 9 7 4 3 3 51
A4 7 6 7 3 9 2 7 1 43
A5 2 3 9 5 7 2 6 5 41
A6 5 5 2 2 8 1 4 3 52

qiuzhenguang 2009-08-25

A1 6 2 6 7 4 2 5 9 60
A2 4 9 5 3 8 5 8 2 55
A3 5 2 1 9 7 4 3 3 51
A4 7 6 7 3 9 2 7 1 43
A5 2 3 9 5 7 2 6 5 41
A6 5 5 2 2 8 1 4 3 52

model:
!6发点8收点运输问题;
sets:
warehouses/wh1..wh6/: capacity;
vendors/v1..v8/: demand;
endsets
!目标函数;
!需求约束;
@for(vendors(J):
@sum(warehouses(I): volume(I,J))=demand(J));
!产量约束;
@for(warehouses(I):
@sum(vendors(J): volume(I,J))<=capacity(I));

!这里是数据;
data:
capacity=60 55 51 43 41 52;
demand=35 37 22 32 41 32 43 38;
cost=6 2 6 7 4 2 9 5
4 9 5 3 8 5 8 2
5 2 1 9 7 4 3 3
7 6 7 3 9 2 7 1
2 3 9 5 7 2 6 5
5 5 2 2 8 1 4 3;
enddata
end

youdandan 2009-08-24

qiuzhenguang 2009-08-23
6楼 讲的好像是说动态规划是一个决策问题。我认同。但是有些算法书上讲动态规划要有两个部分：（1）最优子结构 （2）重叠子问题 。 书上还说动态规划要存储一些已求解子问题，以便后面要重复使用。

qiuzhenguang 2009-08-23

DarkChampion 2009-08-23

3.2w+