Chuyên đề Chương 4: Thuật toán gomory thứ hai
Chương này trình bày hai thuật toán: thuật toán Gomory thứhai dùng đểgiải bài
toán quy hoạch tuyến tính nguyên bộphận, thuật toán Dalton - Llewellyn dùng đểgiải
bài toán quy hoạch tuyến tính với các biến nhận giá trịrời rạc.
1. LƯỢC ĐỒLOGIC CHUNG CỦA THUẬT TOÁN
Xét bài toán quy hoạch rời rạc:
ed long far *t; long int t1,t2; char *s1,*s2; FILE *f1,*f2; int ktnguyen(double x); int cotquay(); void biendoi(); void inbang(int cuoi); int dhdoingau(); void main() {clrscr(); t= (unsigned long far *)MK_FP(0,0X46C); t1=*t; printf("\nCo in trung gian hay khong 1/0 ? "); scanf("%d%*c",&tg); // Nhap du lieu printf("\nVao ten tep so lieu : "); gets(s1); f1=fopen(s1,"r"); fscanf(f1,"%d%d%lf%d%d%d",&n,&m,&gz,&n1,&x0,&ss); for (i=0;i<=n;i++) for (j=0; j<=m;j++) { fscanf(f1,"%lf",&r); s[i][j]=r; } for (i=0; i<=n;i++) fscanf(f1,"%d",&cs[i]) ; Bùi Thế Tâm IV.14 Quy hoạch rời rạc for (j=1; j<=m; j++) fscanf(f1,"%d",&nc[j]); fclose(f1); sb=1; blap=0; // In du lieu nhap de kiem tra printf("\nn,m,gz,n1,x0,ss=%d %d %13.5lf %d %d%d",n,m,gz,n1,x0,ss); if (tg==1){ printf("\nVao ten tep chua ket qua : "); gets(s2); f2=fopen(s2,"w"); fprintf(f2,"\nn,m,gz,n1,x0,ss=%d%d%13.5lf%d%d%d",n,m,gz,n1,x0,ss); } printf("\nBang 1, so lieu ban dau"); if (tg==1) fprintf(f2,"\nBang 1, so lieu ban dau"); inbang(0); if (ss==1){ printf("\nBang 1, so lieu ban dau, l- chuan, chap nhan duoc"); if (tg==1) fprintf(f2,"\nBang 1, so lieu ban dau, l- chuan, chap nhan duoc"); lc = n; goto Lap1;} if (ss==2){ printf("\nBang1,ban dau,l-chuan,khong chap nhan duoc,chay DHDN"); if (tg==1) fprintf(f2,"\nBang 1,ban dau,l- chuan, khong chap nhan duoc,chay DHDN"); lc = n; goto L1;} // Them rang buoc phu sb=1; cs[n+1]=n+1; s[n+1][0]=gz; for (j=1;j<=m; j++) s[n+1][j]=1; printf("\nBang 1, so lieu ban dau them rang buoc phu"); if (tg==1) fprintf(f2,"\nBang 1,so lieu ban dau them rang buoc phu"); inbang(1); l=n+1; // dong quay la dong cuoi cung // Xac dinh cot quay cmin=1; for (j=2;j<=m;j++) { for (i=0; i<=n;i++) { if (s[i][cmin] > s[i][j]) {cmin=j; break;} if (s[i][cmin] < s[i][j]) break; Bùi Thế Tâm IV.15 Quy hoạch rời rạc } } printf("\nDong quay= %d, Cot quay= %d, Phan tu quay =%13.5lf", l,cmin,s[l][cmin]); if (tg==1) { fprintf(f2,"\nDong quay= %d, Cot quay= %d, Phan tu quay= %13.5lf", l,cmin,s[l][cmin]); } biendoi(); sb++; printf("\nBang %d, l- chuan dau tien",sb); if (tg==1) fprintf(f2,"\nBang %d, l- chuan dau tien",sb); inbang(0); lc = n+1; L1: kgd2= dhdoingau(); if (kgd2==1) { printf("\nBai toan phu khong giai duoc, STOP"); if (tg==1) fprintf(f2,"\nBai toan phu khong giai duoc,STOP"); getch(); getch(); return; } // Tim xong bang l- chuan + chap nhan duoc, sang Buoc lap lon Lap1: blap = blap+1; printf("\n------------------------------------------------"); printf("\n\nBUOC LAP LON THU %d: ",blap); if (tg==1) { fprintf(f2,"\n---------------------------------------"); fprintf(f2,"\n\nBUOC LAP LON THU %d: ",blap);} // Kiem tra loi giai toi uu bai toan phu co nguyen khong le=-1; for(i=x0;i<=n1;i++) if(ktnguyen(s[i][0])==0){le = i; break; } printf("\nThanh phan le thuoc dong = %d",le); if (tg==1) fprintf(f2,"\nThanh phan le thuoc dong = %d",le); if (le==-1) { printf("\nPHUONG AN TOI UU QHTT NGUYEN: "); if (tg==1) fprintf(f2,"\nPHUONG AN TOI UU QHTT NGUYEN: "); for (i=0; i<=n;i++) printf("\nx[%2d] = %13.5lf",cs[i],s[i][0]); printf("\nSo luong lat cat: %d lat cat",blap-1); printf("\nSo bang don hinh da lap : %d bang",sb); if (tg==1) { for (i=0; i<=n;i++) Bùi Thế Tâm IV.16 Quy hoạch rời rạc fprintf(f2,"\nx[%2d] = %13.5lf",cs[i],s[i][0]); fprintf(f2,"\nSo luong lat cat: %d lat cat",blap-1); fprintf(f2,"\nSo bang don hinh da lap : %d bang",sb); } t= (unsigned long far *)MK_FP(0,0X46C); t2=*t; printf("\nThoi gian chay chuong trinh: %ld giay", (long int)((t2-t1)/18.21)); if (tg==1) fprintf(f2,"\nThoi gian chay chuong trinh:%ld giay", (long int)((t2-t1)/18.21)); fclose(f2); getch(); return; } // Tao lat cat moi va ghi vao cuoi bang lc++; cs[n+1]=lc; s[n+1][0]= -(s[le][0]- floor(s[le][0])); for (j=1; j<=m; j++) if (nc[j]<=n1) { // khi xj <= n1 if (ktnguyen(s[le][j])) s[n+1][j]=0; else { if ((s[le][j]-floor(s[le][j]))<=fabs(s[n+1][0])) s[n+1][j]=-(s[le][j]-floor(s[le][j]) ); else s[n+1][j]=-(fabs(s[n+1][0])/(1-fabs(s[n+1][0]))) *(1-(s[le][j]-floor(s[le][j]))); } } // khi xj > n1 else { if (s[le][j]<0) s[n+1][j]=-(fabs(s[n+1][0])/(1-fabs(s[n+1][0]))) *(-s[le][j]); else s[n+1][j]=-s[le][j]; } printf("\nBang %d, sau khi them lat cat",sb); if (tg==1) fprintf(f2,"\nBang %d, sau khi them lat cat",sb); inbang(1); // Xac dinh dong quay va cot quay l=n+1 ; printf("\nDong quay = %d",l); if (tg==1) fprintf(f2,"\nDong quay = %d",l); cotquay(); printf("\nCot quay = %d, Phan tu quay = %13.5lf",cmin,s[l][cmin]); Bùi Thế Tâm IV.17 Quy hoạch rời rạc if (tg==1) fprintf(f2,"\nCot quay=%d,Phan tu quay=%13.5lf",cmin,s[l][cmin]); // Bien doi bang don hinh biendoi(); sb++; printf("\nBang %d, bang dau tien bai toan phu",sb); if (tg==1) fprintf(f2,"\nBang %d, bang dau tien bai toan phu",sb); inbang(0); kgd2= dhdoingau(); if (kgd2==1) { printf("\nBai toan phu khong giai duoc"); if (tg==1) fprintf(f2,"\nBai toan phu khong giai duoc, STOP"); getch(); getch(); return; } goto Lap1; } int ktnguyen(double x) { long int h; double z; z=fabs(x); h=(int)(z+0.5); if (fabs(z-h)<=0.0001) return 1; else return 0; } int cotquay() { k=0; for (j=1; j<=m; j++) if (s[l][j]<-0.000001) { k=j; break;} if (k==0) return 1; cmin=k; for (j=k+1;j<=m;j++) if (s[l][j]< -0.000001) { for (i=0; i<=n;i++) {t4=s[i][cmin]/fabs(s[l][cmin]);t5=s[i][j]/fabs(s[l][j]); if (t4 > t5) {cmin=j; break;} if (t4 < t5) break; } } return 0; } void biendoi() { for (j=0;j<=m;j++) if (j!= cmin) { for (i=0;i<=n;i++) if (i!=l) s[i][j]=s[i][j]-(s[l][j]/s[l][cmin])*s[i][cmin]; Bùi Thế Tâm IV.18 Quy hoạch rời rạc s[l][j]=0; } for (i=0;i<=n;i++) if (i!=l) s[i][cmin]=-s[i][cmin]/s[l][cmin]; s[l][cmin]=-1; nc[cmin]=cs[l]; } void inbang(int cuoi) { int n1; if (cuoi==1) n1=n+1; else n1=n; printf("\nCo so : "); for (i=0; i<=n1;i++) printf("%d ",cs[i]) ; printf("\n"); printf("Phi co so : "); for (j=1; j<=m; j++) printf("%d ",nc[j]);printf("\n"); for (i=0;i<=n1;i++) { for (j=0; j<=m;j++) printf(" %10.5lf ",s[i][j]); printf("\n"); } if (tg==1) {fprintf(f2,"\nCo so : "); for (i=0; i<=n1;i++) fprintf(f2,"%d ",cs[i]); fprintf(f2,"\n"); fprintf(f2,"Phi co so : "); for (j=1; j<=m; j++) fprintf(f2,"%d ",nc[j]);fprintf(f2,"\n"); for (i=0;i<=n1;i++) { for (j=0; j<=m;j++) fprintf(f2," %13.5lf ",s[i][j]); fprintf(f2,"\n"); } } getch(); } int dhdoingau() { blap2 =0;Lap2: blap2++; printf("\nBuoc lap Don hinh doi ngau thu %d : ",blap2); if (tg==1) fprintf(f2,"\nBuoc lap Don hinh doi ngau thu %d :",blap2); l=-1; for (i=1;i<=n;i++) if (s[i][0]<0) {l=i; break;} printf("\nDong quay %d ",l); Bùi Thế Tâm IV.19 Quy hoạch rời rạc if (tg==1) fprintf(f2,"\nDong quay = %d",l); if (l==-1) { printf("\nBang tren ung phuong an toi uu cua bai toan phu"); if (tg==1) fprintf(f2,"\nBang tren ung phuong an toi uu bai toan phu"); return 0; } else { kgd=cotquay(); if (kgd==1) return 1; printf("\nCot quay=%d, Phan tu quay=%13lf",cmin,s[l][cmin]); if (tg==1) fprintf(f2,"\nCot quay = %d, Phan tu quay =%13.5lf", cmin,s[l][cmin]); biendoi(); sb++; printf("\nBang %d, DHDN",sb); if (tg==1) fprintf(f2,"\nBang %d, DHDN",sb); inbang(0); goto Lap2; } } • Sau khi chạy chương trình ta nhận được lời giải tối ưu của bài toán trên là: x[ 0] = 27.00000 x[ 1] = 7.00000 x[ 2] = 0.00000 x[ 3] = 1.50000 x[ 4] = 62.00000 x[ 5] = 0.00000 x[ 6] = 57.50000 x[ 7] = 2.00000 Số lượng lát cắt: 3 lát cắt Số bảng đơn hình đã lập : 9 bảng 3. THUẬT TOÁN DALTON VÀ LLEWELLYN 3.1. Dalton cải tiến thuật toán Gomory thứ hai cho bài toán qui hoạch tuyến tính rời rạc bộ phận sau: Bùi Thế Tâm IV.20 Quy hoạch rời rạc { } 0 1 ij 1 1 2 1 1 1 2 1 Max (22) 1,..., (23) 0 1,..., (24) , ,... , 1,..., ; (25) 0 ... , 1,..., j j n j j j n j i j j j j j j jq j j jq x c x a x b i m x j n x A A A A j n n n A A A j n = = = = = ≥ = ∈ ≡ = ≤ = < < < = ∑ ∑ Nếu cần ta bổ sung bất đẳng thức 1, 1,...,jj jqx A j n≤ = (26) vào điều kiện (23), khi đó phương án X của bài toán (L0,C) (22) – (24) thoả mãn điều kiện 10 , 1,...,jj jqx A j n≤ ≤ = . 3.2. Định lý 1. Giả sử ( ), rrX L C X≡ là phương án tựa tối ưu của bài toán ( ),rL C và rijrT x= là bảng đơn hình tương ứng, 1 0 , 1 1 r i i i i n A x Aυ υ+ ≤ ≤ < < Khi đó bất đẳng thức 0 r j j j N xγ γ ∈ ≥∑ (27) hay viết lại là 0 (28) 0 (29) r j j j N Z x Z γ γ ∈ = − + ≥ ∑ là một lát cắt đúng, trong đó: ( ) 0 0 0 , 1 0 (30) 0 (31) 0 r i i r r ij ij r j r ri i ij ijr i i x A x x x A x x A x υ υ υ γ γ + = − ≥= − − < − Chứng minh định lý. Kiểm tra tính cắt: 0 00 r r r j j i i j N x x Aυγ γ ∈ = < = −∑ (do 0rjx = ). Kiểm tra tính đúng. Giả sử X là phương án của bài toán rời rạc, với i đã chọn, biểu diễn xi qua các biến phi cơ sở như sau: ( )r0 ij r r i i j j N x x x x ∈ = + −∑ (32) Có 2 khả năng: Bùi Thế Tâm IV.21 Quy hoạch rời rạc 1) , 1i ix A υ+≥ (33) 2) i ix Aυ≤ (34) Ta đưa vào các ký hiệu: ( ){ } { } ( ){ } { } ( ) ( ) r r ij ij r r ij ij r ij r ij , 0 , 0 , 0 , 0 r r r r r r r r j j N j j N N j j N x j j N x N j j N x j j N x S x x S x x − + − + − ∈ + ∈ = ∈ − ≤ = ∈ ≥ = ∈ − > = ∈ < = − = − ∑ ∑ Từ (32) ta có 0 (35) 0 (36) 0 (37) r i ix x S S S S − + − + = + + ≤ ≥ Xét Trường hợp 1, tức là , 1i ix A υ+≥ . Từ (33) và (35) ta có 0 , 1 r i ix S S A υ − + ++ + ≥ , suy ra ( ) ( ), 1 0 , 1 0 (do 0)r ri i i iS A x S A
File đính kèm:
- C4 Thuat toan Gomory2.pdf