运筹学0003

作者在 2009-08-27 11:07:05 发布以下内容
表上作业法的实现:

#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;
}
日志 | 阅读 884 次
文章评论,共0条
游客请输入验证码
浏览8474次