作者在 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;
}
#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;
}