Tải bản đầy đủ (.pdf) (23 trang)

QUY HOẠCH RỜI RẠC - CHƯƠNG 5 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (490.5 KB, 23 trang )


Bùi Thế Tâm V.1 Quy hoạch rời rạc

Chương 5
THUẬT TOÁN GOMORY THỨ BA
Chương này trình bày thuật toán Gomory thứ ba nhằm xây dựng các lát cắt đảm
bảo tất cả các Bảng đơn hình ở mỗi bước đều có tất cả các phần tử là nguyên
1. ẢNH HƯỞNG CỦA SAI SỐ LÀM TRÒN VÀ TƯ TƯỞNG CỦA
THUẬT TOÁN GOMORY THỨ BA
1.1.
Ảnh hưởng của sai số làm tròn có thể dẫn đến lời giải sai khi dùng phương
pháp đơn hình giải bài toán quy hoạch tuyến tính. Khi giải bài toán quy hoạch tuyến
tính nguyên ảnh hưởng sai số làm tròn tăng mạnh do các nguyên nhân sau :
- Tăng khối lượng tính toán vì dùng nhiều lần
l - phương pháp.
- Khả năng mắc sai khi xử lý các số kiểu phần thập phân 0,999999 ≈ 1,000000
- Khả năng nhận lời giải không đúng vì số nguyên có thể nhận là không nguyên.
Để tránh sai số làm tròn, Gomory đưa ra thuật toán thứ ba để giải bài toán quy
hoạch tuyến tính nguyên toàn phần :

0
1
n
ij
j=1
ax (1)
a , 1, 2, , (2)
0 , 1, 2, , (3)
ên , 1, 2, , (4)
n
jj


j
ji
j
j
mx cx
xb i m
xjn
xnguy j n
=

==
≥=
−=




1.2.
Tư tưởng của thuật toán Gomory thứ ba
Giả sử bài toán (L,C) ≡ (L
0
,C) viết ở dạng bảng T
0
,
l
- chuẩn (phần tử khác
không đầu tiên ở mỗi cột là số dương). Dùng
l
- phương pháp, ta nhận được dãy hữu
hạn các bảng

l
- chuẩn T
0
, T
1
, , T
s
mà cái cuối cùng là chấp nhận được.
Giả sử bảng xuất phát T
0
là nguyên hoàn toàn (tất cả các phần tử là số nguyên).
Các bảng tiếp theo có thể không nguyên là do: ngoài các phép toán + , - , * khi chuyển
từ T
ν
sang T
ν+1
, ta còn dùng phép tính chia trên phần tử quay. Nếu phần tử quay trên tất
cả các bước là (-1) thì các bảng T
1
, T
2
, vẫn là nguyên khi T
0
- nguyên, cuối cùng
phương án tối ưu X
s
của bài toán (L
s
,C) ứng với T
s

cũng là nguyên. Vậy X
s
là phương
án tối ưu của bài toán quy hoạch tuyến tính nguyên gốc (L
N
,C).
Vì vậy, ta sẽ cải tiến định nghĩa lát cắt đúng sao cho nếu dòng tương ứng với nó
chọn làm dòng quay thì phần tử quay bằng (-1).
Chính xác hơn, bài toán tìm lát cắt đúng nguyên được phát biểu như sau: có bài
toán (L,C), các điều kiện của nó viết dưới dạng bảng nguyên, không chấp nhận được,
l
- chuẩn
0
,
'
ij n
iQ jN
Tx
∈∈
= , vì vậy l - giả phương án mở rộng :
i
(
)
(
)
'' '
0 1 00 10 0
' , , , , , ,
nn
Xxxx xx x==



Bùi Thế Tâm V.2 Quy hoạch rời rạc

ứng với T' không là phương án mở rộng. Cần xây dựng một hàm tuyến tính :

0
() ( )
jj
jN
Z
Xr rx

=
+−

(5)
thỏa mãn các điều kiện sau :
I. Điều kiện nguyên :
r
j
- nguyên ,
0
j
N∀∈
(6)
II. Điều kiện cắt :
Z(X') = r
0
< 0 ,

(
)
'''
1
, ,
n
Xxx=
(7)
III. Điều kiện đúng: với mọi phương án X của bài toán
(,)
N
L
C
thì
Z(X) ≥ 0. (8)
IV. Điều kiện giữ gìn tính nguyên. Nếu trong các số
(
)
j
rjN∈ có số âm ,
0
1
j
j
j
nj
x
x
R
x




=




#
với
j
N∈ là cột của ma trận T' và

j
jN,r 0
ex min
j
l
l
j
R
R
l
r
r
∈<
= (9)
thì
1
l

r
=
− (10)
Điều kiện (9) - (10) có nghĩa là nếu dòng Z(X) chọn làm dòng quay thì phần tử
quay là (-1).
1.3. Lược đồ logic của thuật toán Gomory thứ ba
Nếu thành công xây dựng lát cắt đúng nguyên thỏa mãn (5) - (10) thì lược đồ
logic của thuật toán như sau.
Bắt đầu từ bảng không chấp nhận được xuất phát T
0
, xây dựng dãy các bảng
T
0
, T
1
, , T
r
, T
r+1
, mà mỗi bảng đều là nguyên và l - chuẩn.
Nếu T
r
là chấp nhận được thì l - giả phương án ứng với nó X
r
đồng thời là
phương án tối ưu của bài toán (L
N
,C).
Nếu T
r

là không chấp nhận được thì xây dựng lát cắt đúng nguyên thỏa mãn (5) -
(10). Viết dòng tương ứng ngay dưới bảng T
r
và lấy nó làm dòng quay. Sau đó, thực
hiện một bước lặp của
l
- phương pháp để nhận được bảng mới T
r+1
nguyên và
l
-
chuẩn.

Bùi Thế Tâm V.3 Quy hoạch rời rạc

2. XÂY DỰNG LÁT CẮT ĐÚNG NGUYÊN, THUẬT TOÁN
GOMORY THỨ BA
2.1.
Cơ sở xây dựng lát cắt đúng nguyên :
Định lý 1. Giả sử 0
λ
>

00
()
jj
jT
yd dy

=+ −


, trong đó T là tập hữu hạn;

()
0
j
j
jT
d
d
zy
λλ



=+ −





, trong đó [x] - phần nguyên của x;

{
}
0, 0
j
yjT≥∈∪
,
y

j
- nguyên , jT

.
Khi đó : z ≥ 0
z - nguyên.
Chứng minh. Tính nguyên của z trực tiếp suy ra từ định nghĩa phần nguyên và
tính nguyên của y
j
( jT∈ ).
Để chứng minh z ≥ 0 ta dùng phản chứng, giả sử z < 0. Từ tính nguyên của z suy
ra
z ≤ -1. (11)
Mặt khác:
00
()
j
j
jT
d
yd
y
λλ λ

=+ −

, như vậy

00 0
() ()

jj
jj
jT jT
dd
yd d
yy
λλ λ λ λ
∈∈
 
 
=+ −++ −
 


 
 
∑∑


Theo giả thiết
0
()
j
j
jT
d
d
zy
λλ




=+ −






suy ra
00
()
j
j
jT
d
yd
yz
λλ λ



=+ −+
 



, hay

00

j
j
jT
d
yd
yz
λλ λ



+
=+
 



(12)

0
10.
d
λ


−<


(do (11))
Điều này không thể sảy ra vì
{

}
0, 0
j
yjT≥∈∪ (theo giả thiết),
0
λ
>

và định nghĩa phần lẻ
,
j
d
jT
λ




. Do vậy , 0z ≥ . Định lý được chứng minh.

Bùi Thế Tâm V.4 Quy hoạch rời rạc

2.2. Từ định lý trên ta xây dựng lát cắt đúng nguyên thỏa mãn (5) - (10). Giả sử
cho bảng
0
ij
,
n
iQ jN
Tx

∈∈
= nguyên, không chấp nhận được, l - chuẩn và giả sử đối với k
(1 ≤ k ≤ n):

0
0
0,
()
k
kk kjj
jN
x
x
xxx

<
=
+−


Đặt: T = N

00
0
0
jN jN
()
()
ax ax
jkj

k
jj
jkj
dx jN
yx
yx jN
md mx
λ
∈∈
=∈
=
=∈
==

Như vậy:
0, 0
1, 0
j
j
j
d
d
d
λ




=




<



,
và ta nhận được lát cắt đúng nguyên :

0
(; ) 1 (1)( )
0
ên
kj
kj
jN
x
zz X x
z
z nguy
λ

<

==−+−−














2.3. Trong phần này ta sẽ chỉ ra trong một số trường hợp cụ thể nhận được bảng
T
0
nguyên,
l
- chuẩn :
Xét bài toán :

0
1
n
ij
j=1
ax (13)
a , 1,2, , (14)
0 , 1, 2, , (15)
ên , 1,2, , (16)
n
jj
j
ji
j

j
mx cx
xb i m
xjn
xnguy j n
=

≤=
≥=
−=



trong đó c
j
, a
ij
, b
i
nguyên
(
)
1, , ; 1, ,imjn==. Đưa vào các biến mới, bài toán trên
được viết lại như sau :

Bùi Thế Tâm V.5 Quy hoạch rời rạc


0
1

n
ij
j=1
ax ( )( )
a ( ), 1,2, ,
0, 1, 2, , , 1, ,
ên , 1, 2, , , 1, ,
n
jj
j
ni i j
j
j
mx cx
xb xi m
xj nnnm
x nguy j n n n m
=
+
≡−−
=+ − =
≥= ++
−=++



Ta có các biến x
1
, , x
n

là biến phi cơ sở , viết bảng
'
0
T (chưa
l
- chuẩn).

1 -x
1
-x
2
-x
j
-x
n

x
0
0 -c
1
-c
2
-c
j
-c
n

x
1
0 -1 0 0 0

x
2
0 0 -1 0 0
#

#

#

#


#


#

x
n
0 0 0 0 -1
x
n+1
b
1
a
11
a
12
a
1j

a
1n

x
n+2
b
2
a
21
a
22
a
2j
a
2n

#

#

#

#


#


#


x
n+i
b
i
a
i1
a
i2
a
ij
a
in

# # # #

#

#
x
n+m
b
m
a
n1
a
m2
a
mj
a
mn


(Bảng
'
0
T )
a) Nếu bảng
'
0
T là l - chuẩn (ví dụ khi c
j
< 0 ,
1, ,
j
n
=
) thì xem nó là bảng xuất
phát T
0
(lấy
'
0
T
làm T
0
xuất phát).
b) Nếu
'
0
T không là l - chuẩn, nhưng tập các phương án của bài toán (13)-(15) là
bị chặn thì ta giải bài toán quy hoạch tuyến tính với hàm mục tiêu

n
j
j=1
x

với ràng buộc
(14)-(15) và tìm được:
n
j
j=1
ax x 'mM=


Rõ ràng, với mọi phương án của bài toán (13) - (16) ta đều có :
[]
n
j
j=1
x'
M
M




Vì vậy, từ bài toán này ta có thể đưa vào biến mới :

Bùi Thế Tâm V.6 Quy hoạch rời rạc



n
1j
j=1
1
1
1.(-x ) (17)
0(18)
ên (19)
nm
nm
nm
xM
x
x nguy
++
++
++
=+




Viết dòng (17) xuống dưới bảng
'
0
T
và chọn nó làm dòng quay. Cột quay chọn
theo tiêu chuẩn:
{}
''

1, ,
ex min
lj
jn
Rl R

=
(
'
j
R
- là cột của
'
0
T ứng với biến phi cơ sở
( 1, , )
j
x
jn
=
).
Thực hiện một bước lặp của
l - phương pháp, xóa dòng x
n+m+1
(dòng cuối của
bảng
'
0
T
) và nhận được bảng T

0
nguyên, l - chuẩn. Nếu sau này biến x
n+m+1
đưa vào cơ
sở thì dòng tương ứng không được phục hồi.
2.4. Thuật toán Gomory thứ ba
Bước lặp 0.: Xây dựng bảng xuất phát
0
0
0ij
,
n
iQ jN
Tx
∈∈
=
- nguyên , l - chuẩn. Nếu
T
0
là chấp nhận được thì
l
- giả phương án mở rộng :
(
)
(
)
0000 00 0
0 1 00 10 0
, , , , , ,
nn

Xxxx xxx==


là phương án tối ưu mở rộng của bài toán (L
N
,C) và thuật toán dừng. Nếu T
0
không
chấp nhận được thì chuyển tới bước lặp đầu tiên.
Bước lặp p (p ≥ 1). Cho bảng
0
1
P-1
1ij
,
n
P
P
iQ jN
Tx


∈∈
= - nguyên , l - chuẩn nhưng
không chấp nhận được. Chọn k là chỉ số đầu tiên vi phạm tính chấp nhận được
{
}
{
}
1

0
min | 1,2, , , 0
P
i
kii nx

=
∈<

Nếu
1
1
0,
P
kj P
x
jN


≥∀∈ thì bài toán (L
N
,C) không giải được.
Nếu
1
0
P
kj
x

∃<

thì ta chọn cột cột quay l theo công thức :

1
11
,0
ex min
Pkj
PP
lj
jN x
Rl R

−−
∈<
= (20)
và xây dựng lát cắt đúng nguyên (dòng quay) :

1
1
1
0
( ) (21)
0 (22)
ên
P
P
P
kj
k
nP j

jN
nP
nP
x
x
xx
x
x nguy
λλ



+

+
+


=+ −








(23)

Quy tắc chọn λ như thế nào ta sẽ trình bày trong Mục 2.5.

Viết dòng (21) vào cuối bảng T
P-1
và lấy làm dòng quay. Thực hiện một bước lặp
của
l - phương pháp (loại x
n+P
khỏi cơ sở, đưa x
l
vào cơ sở), xóa dòng x
n+P
. Nếu l ≥ n+1
thì dòng x
l
không khôi phục nữa, ta sẽ nhận được bảng

Bùi Thế Tâm V.7 Quy hoạch rời rạc

0
P
ij
,
n
P
P
iQ jN
Tx
∈∈
=
là nguyên và
l - chuẩn, trong đó :

{
}
(
)
{
}
1
\
PP
NN l np

=
∪+

Nếu T
P
là chấp nhận được thì
(
)
(
)
0 1 00 10 0
, , , , , ,
PPPP PP P
nn
Xxxx xxx==
là phương án
tối ưu mở rộng của bài toán (L
N
,C) . Nếu T

P
không châp nhận được thì chuyển tới bước
(p+1).
2.5. Quy tắc chọn số λ . Số λ được chọn theo ba điều kiện sau

I. Phần tử quay bằng (-1) :


1
1
P
kl
x
λ


=



(24)
II. Bảng T
P
phải là l - chuẩn :


1
11
0
P

kj
PP P
jj l
x
RR R
λ

−−

=
+>



, (25)

{
}
(
)
1
\\{}
PP
jN np N l

∀∈ + =

III. Cột
0
P

R
phải là lexmin :


1
11
0
00
ex min
P
PP P
k
l
x
RR R l
λ

−−

=+ →


(26)

Chú ý :

1)
1
1
0

1
P
PP
l
nP l
R
RR


+

==>

suy ra bất đẳng thức (25) đúng với j = n + p rồi.
2) Từ (24) và
1
0
P
kl
x

<
(do(20)) suy ra
0
λ
>
2.6. Xác định λ thỏa mãn (24) - (26)
a) Điều kiện (24) có thể viết thành :

1

10
P
kl
x
λ


≤<,
do
0
λ
>
nên ta có :

1P
kl
x
λ

≥− (24')
b) Điều kiện (25) có thể đơn giản hóa bằng cách sau.
Nếu
1
0
P
kj
x

≥ thì
1

1
0
P
kj
P
l
x
R
λ







và điều kiện (25) đúng với bất kỳ
0
λ
> . Do
vậy, chỉ cần xét điều kiện (25) với :
1
\{ }
P
j
Nl



1

0
P
kj
x

<
.

Bùi Thế Tâm V.8 Quy hoạch rời rạc

Với mỗi
1P
j
N

∈ , ta đặt :
{
}
() min | 0.
p-1
ij
hj ix=>
Từ (20) suy ra
P-1
P-1 kj
( ) ax{h(j)|j N , x <0}hl m=∈
. Rõ ràng, nếu h(j) < h(l) thì
với bất kỳ
λ
ta có :

1
11
0
P
kj
PP P
jj l
x
RR R
λ

−−

=
+>




Do đó, trường hợp này (25) cũng đúng.
Như vậy, chỉ cần xét (25) với :
1
\{ }
P
j
Nl



1

0
P
kj
x

<
và h(j) = h(l).
Khi đó, điều kiện (25) được viết lại là :

1
11'
1
0,
P
kj
PP P
jj l P
x
R
RRjN
λ

−−


=+ >∀∈



(25')

{
}
'P-1
11kj
|\{},x0,()()
PP
NjjNl hjhl
−−
=∈ < =
Nếu
'
1P
N

=∅ thì (25') không cần thêm bất cứ điều kiện nào trên số 0
λ
> . Bây
giờ giả sử
'
1P
N

≠∅
. Khi đó đối với mỗi
'
1P
j
N



ta có thể tìm được số tự nhiên z
j
sao
cho :

1111
(1) 0
PPPP
jjl jjl
R
zR RzR
−−−−
−+ << − (27)

Chú ý rằng
11PP
jl
R
zR
−−
≠ với z bất kỳ, vì nếu
11PP
jl
R
zR


= thì
01
P-1

ij
,
det 0
P
iN jN
x

∈∈
= , điều này là không thể. Do đó
11
à
PP
jl
R
vR


là không tỉ lệ với
nhau.
Có 4 khả năng :
1)
11
() ()
PP
hl j hll
x
x
−−
=
. Khi đó nếu chọn z

j
= 1 thì (27) thỏa mãn.
2)
11
() ()
PP
hl j hll
x
qx r
−−
=
+ trong đó q, r là các số tự nhiên,
1
()
P
hll
rx

< . Khi đó nếu chọn
chọn z
j
= q thì (27) được thỏa mãn.
3)
11PP
ij il
x
qx
−−
= , i = h(l) , h(l) + 1 , , h(l) + t ≡ s - 1, và


11PP
s
jsl
x
qx
−−
> trong đó q là số tự nhiên ≥2.
Khi đó, nếu ta chọn z
j
= q thì (27) đúng.
4)
11PP
ij il
x
qx
−−
= , i = h(l) , h(l) + 1 , , h(l) + t ≡ s - 1, và
11PP
s
jsl
x
qx
−−
< , trong đó q là số tự nhiên ≥ 2.
Khi đó, ta chọn z
j
= q - 1 thì (27) đúng.

Bùi Thế Tâm V.9 Quy hoạch rời rạc


Từ (27) và (25') suy ra cần chọn số λ thỏa mãn:
1
'
1
,
P
kj
jP
x
zjN
λ



−≤ ∀∈



, hay
1P
kj
j
x
z
λ

≥− , suy ra
1P
kj
j

x
z
λ

≥−
. Vậy điều kiện (25') chuyển thành điều kiện sau:

P-1
kj
'
1
j
x
ax -
z
P
mjN
λθ





≥≡ ∈





(25'')

trong đó z
j
- được chọn theo 4 khả năng đã trình bày ở trên.
c) Xét điều kiện (26). Vì λ > 0 ,
11
0
0, 0
PP
kl
xR
−−
<
>
nên điều kiện (26) được viết lại
như sau :

min
λ

(26')

Cuối cùng từ (24') , (25'') , (26') ta có :

{
}
P-1
kl
ax -x ,m
λ
θ

=
(28)


2.7. Giải ví dụ bằng số
Giải bài toán quy hoạch nguyên sau:
Max
43210
3663 xxxxx


+
=

3
984
96672
59224
41
321
4321
4321

≤−+−
≥+++




xx

xxx
xxxx
xxxx
4- 8-
8

4321
,,, xxxx nguyên.
Sau khi thêm biến bù bài toán viết lại thành
Max
43210
3663 xxxxx


+
=

43215
92245 xxxxx
+
+
+

=
43216
66729 xxxxx
+
+
+
+


=
3217
9848 xxxx
+

+
=
418
483 xxx
+
+
=
876543210
,,,,,,,, xxxxxxxxx
nguyên

Bùi Thế Tâm V.10 Quy hoạch rời rạc

Từ đây ta có bảng đơn hình xuất phát (Bảng 1). Vì bảng đơn hình không là l-
chuẩn nên ta phải thêm ràng buộc phụ
100
4321
=≤
+
+
+
gzxxxx
hay
43219

100 xxxxx −−−−= - và 0
9
≥x và viết vào phía dưới bảng 1. Chọn dòng x
9

làm dòng quay.
1 -x
1
-x
2
-x
3
-x
4
x
0
0 -3 -6 6 3
x
1
0 -1 0 0 0
x
2
0 0 -1 0 0
x
3
0 0 0 -1 0
x
4
0 0 0 0 -1
x

5
5 4 -2 -2 -9
x
6
-9 -2 -7 -6 -6
x
7
8 -4 8 -9 0
x
8
3 -8 0 0 -4
Bảng 1
x
9
100 1 1* 1 1
Thực hiện một bước của đơn hình đối ngẫu từ vựng ta được bảng 2 là l-chuẩn. Vì
x
7
<0 nên sinh ra lát cắt x
10
và chọn nó làm dòng quay.











Bảng 2
x
10
-66 -1* -1 -2 -1

Tiếp tục dùng thuật toán đơn hình đối ngẫu từ vựng ta được bảng 3 là l- chuẩn và
không chấp nhận được. Vì x
5
<0 nên sinh ra lát cắt x
11
và chọn nó làm dòng quay.
1 -x
1
-x
9
-x
3
-x
4
x
0
600 3 6 12 9
x
1
0 -1 0 0 0
x
2
100 1 1 1 1
x

3
0 0 0 -1 0
x
4
0 0 0 0 -1
x
5
205 6 2 0 -7
x
6
691 5 7 1 1
x
7
-792 -12 -8 -17 -8
x
8
3 -8 0 0 -4

Bùi Thế Tâm V.11 Quy hoạch rời rạc


1 -x
10
-x
9
-x
3
-x
4
x

0
402 3 3 6 6
x
1
66 -1 1 2 1
x
2
34 1 0 -1 0
x
3
0 0 0 -1 0
x
4
0 0 0 0 -1
x
5
-191 6 -4 -12 -13
x
6
361 5 2 -9 -4
x
7
0 -12 4 7 4
x
8
531 -8 8 16 4
Bảng 3
x
11
-15 0 -1* -1 -1

Tiếp tục dùng thuật toán đơn hình đối ngẫu từ vựng ta được bảng 4 là l- chuẩn và
không chấp nhận được. Vì x
7
<0 nên sinh ra lát cắt x
12
và chọn nó làm dòng quay.
1 -x
10
-x
11
-x
3
-x
4
x
0
357 3 3 3 3
x
1
51 -1 1 1 0
x
2
34 1 0 -1 0
x
3
0 0 0 -1 0
x
4
0 0 0 0 -1
x

5
131 6 -4 -8 -9
x
6
331 5 2 -11 -6
x
7
-60 -12 4 3 0
x
8
441 -8 8 8 -4
Bảng 4
x
12
-15 0 -1 -1 -1*

Tiếp tục dùng thuật toán đơn hình đối ngẫu từ vựng ta được bảng 5 là l- chuẩn và
không chấp nhận được. Vì x
7
<0 nên sinh ra lát cắt x
13
và chọn nó làm dòng quay.

Bùi Thế Tâm V.12 Quy hoạch rời rạc


1 -x
10
-x
11

-x
3
-x
12
x
0
312 3 0 0 3
x
1
51 -1 1 1 0
x
2
34 1 0 -1 0
x
3
0 0 0 -1 0
x
4
15 0 1 1 -1
x
5
4 6 5 1 -9
x
6
421 5 8 -5 -6
x
7
-60 -12 4 3 0
x
8

471 -8 12 12 -4
Bảng 5
x
13
-5 -1* 0 0 0
Tiếp tục dùng thuật toán đơn hình đối ngẫu từ vựng ta được bảng 6 là l- chuẩn và
không chấp nhận được. Vì x
5
<0 nên sinh ra lát cắt x
14
và chọn nó làm dòng quay.
1 -x
13
-x
11
-x
3
-x
12
x
0
297 3 0 0 3
x
1
56 -1 1 1 0
x
2
29 1 0 -1 0
x
3

0 0 0 -1 0
x
4
15 0 1 1 -1
x
5
-26 6 5 1 -9
x
6
396 5 8 -5 -6
x
7
0 -12 4 3 0
x
8
511 -8 12 12 -4
Bảng 6
x
14
-3 0 0 0 -1*

Thực hiện một bước của thuật toán đơn hình đối ngẫu từ vựng ta được bảng l-
chuẩn chấp nhận được có cột phương án là nguyên và quá trình lặp kết thúc.

Bùi Thế Tâm V.13 Quy hoạch rời rạc


1 -x
13
-x

11
-x
3
-x
14
x
0
288 3 0 0 3
x
1
56 -1 1 1 0
x
2
29 1 0 -1 0
x
3
0 0 0 -1 0
x
4
18 0 1 1 -1
x
5
1 6 5 1 -9
x
6
414 5 8 -5 -6
x
7
0 -12 4 3 0
x

8
523 -8 12 12 -4
Bảng 7

Bảng tổng hợp :(Phương án và giá trị
λ
ở mỗi bước)
P
x
p
0
x
p
1
x
p
2
x
p
3
x
p
4
x
p
5
x
p
6
x

p
7
x
p
8

λ

1 600 0 100 0 0 205 691 -792 3 12
2 402 66 34 0 0 -191 361 0 531 13
3 357 51 34 0 0 -131 331 -60 411 9
4 312 51 34 0 15 4 421 -60 471 12
5 297 56 29 0 15 -26 396 0 511 9
6 288 56 29 0 18 1 414 0 523

Vậy phương án tối ưu là (56, 29, 0, 18, 1, 414, 0, 523) với trị hàm mục tiêu là
x[0]=288.
3. CHƯƠNG TRÌNH MÁY TÍNH
• Thuật toán này dùng để giải bài toán quy hoạch tuyến tính nguyên hoàn toàn ,
có dạng:
max
1
0
→=

=
j
m
j
j

xcx
ij
m
j
ij
bxa ≤

=1
,
p
i , ,1
=

0≥
j
x ,
m
j
, ,2,1
=

j
x nguyên.

Bùi Thế Tâm V.14 Quy hoạch rời rạc

các b[i] có thể dương và âm, phương án xuất phát không đối ngẫu chấp nhận được.
Nếu bài toán có ràng buộc đẳng thức dạng:
ii
m

j
ij
bxa =

=1
thì ta thay thế bằng hai
bất đẳng thức:
ii
m
j
ij
bxa ≤

=1

ii
m
j
ij
bxa ≥

=1
.

Sau khi thêm biến bù bài toán trên có thể viết ở dạng:
max))((
1
0
→−−=


=
m
j
jj
xcx
mjxx
jj
, ,2,1))(1(
=


=
., ,2,1))((
1
pixabx
j
m
j
ijiim
=−−+=

=
+

., ,2,10 pmjx
j
+
=



j
x nguyên. ., ,2,1
p
m
j
+
=

• Trong chương trình sử dụng các biến và mảng sau:
- m: số biến chính, n: số biến chính và biến bù của bài toán (n=m+p), gz là một
số dương đủ lớn và thường lấy bằng
},,{max
jiij
cba .
- ss = 1 nếu bảng đơn hình s ban đầu là l- chuẩn, =2 nếu bảng không là l - chuẩn
- Mảng s gồm n + 2 dòng và m+1 cột lúc đầu ghi dữ liệu của bài toán sau đó lưu
bảng đơn hình ở mỗi bước. Dòng n+1 để chứa ràng buộc phụ.
- s[0][0] hàm mục tiêu, cột 0 là cột phương án, dòng 0 là các ước lượng
- cs : các biến ở bên trái bảng đơn hình, nc : các biến phi cơ sở

Cách nhập dữ liệu
Dữ liệu ban đầu của bài toán được ghi trong một tệp văn bản, gồm có:
- n, m, gz, ss.
- Mảng s dữ liệu ban đầu bố trí dạng (ở dưới) và được ghi vào tệp dữ liệu theo
từng dòng :



Bùi Thế Tâm V.15 Quy hoạch rời rạc















- Tiếp đến là mảng cs: nhập các số từ 0, 1, 2,…, n
- Cuối cùng là mảng nc: nhập các số từ 1, 2,…, m

Với dữ liệu bài toán trên thì ta có tệp dữ liệu VDG3.CPPcó dạng:
8 4 100 2
0 -3 -6 6 3
0 -1 0 0 0
0 0 -1 0 0
0 0 0 -1 0
0 0 0 0 -1
5 4 -2 -2 -9
-9 -2 -7 -6 -6
8 -4 8 -9 0
3 -8 0 0 -4
0 1 2 3 4 5 6 7 8
1 2 3 4


• Văn bản chương trình
#include <stdio.h>
#include <conio.h>
#include <math.h>
-x
1
-x
2
. . . . . . . . . –x
m
0 -c
1
-c
2
. . . . . . . . –c
m
x
0
x
1
x
2
#

x
m
0
0
#
0

-1 0 . . . . . . . . . . 0
0 -1 . . . . . . . . . 0
# # % #
0 0 . . . . . . . . . . -1
x
m+1
#
x
n
b
1

#
b
p
-a
11
. . . . . . . . . - a
1m
# # #
-a
p1
. . . . . . . . . a
p,m


Bùi Thế Tâm V.16 Quy hoạch rời rạc

#include <dos.h>
#define M 30

#define N 30
long int s[N+2][M+1],gz,t1,t2,lamda; double r;
int sb,cmin,m,n,i,j,k,l,lc,tg,cs[N+2],nc[M+1], np[M+1];
int ka,blap,hl,hj,trong,zj[M+1],q,is,ss;
unsigned long far *t; char *s1,*s2;
FILE *f1,*f2;
void biendoi();
void inbang(int cuoi);
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 ban dau
printf("\nVao ten tep so lieu : "); gets(s1);
f1= fopen(s1,"r"); fscanf(f1,"%d%d%ld%d",&n,&m,&gz,&ss);
for(i=0;i<=n;i++)for(j=0;j<=m;j++) fscanf(f1,"%ld",&s[i][j]);
for (i=0; i<=n;i++) fscanf(f1,"%d",&cs[i]) ;
for (j=1; j<=m; j++) fscanf(f1,"%d",&nc[j]);
fclose(f1);
sb=1; blap=0;
// In kiem tra ket qua nhap
printf("\n n,m,gz,ss = %d %d %10ld %d",n,m,gz,ss);
if (tg==1){ printf("\nVao ten tep chua ket qua : "); gets(s2);
f2=fopen(s2,"w");
fprintf(f2,"\n n,m,gz,ss = %d %d %10ld %d",n,m,gz,ss);
}
printf("\nBang 1, so lieu ban dau:");
if (tg==1) fprintf(f2,"\nBang 1, so lieu ban dau:");
inbang(0);

// Kiem tra l- chuan
if (ss==1){
printf("\nBang 1, so lieu ban dau, l- chuan");
if (tg==1)

Bùi Thế Tâm V.17 Quy hoạch rời rạc

fprintf(f2,"\nBang 1, so lieu ban dau, l- chuan");
lc = n; goto Lap1;}
// Them rang buoc phu, tim bang l- chuan
cs[n+1]=n+1; s[n+1][0]=gz;
for (j=1;j<=m; j++) s[n+1][j]=1;
printf("\nBang %d, sau khi them rang buoc phu",sb);
if (tg==1)
fprintf(f2,"\nBang %d, sau khi them rang buoc phu",sb);
inbang(1);
l=n+1;
printf("\nDong quay = %d",l);
if (tg==1) fprintf(f2,"\nDong quay = %d",l);
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;
}
}
printf("\nCot quay= %d Phan tu quay= %10ld",cmin,s[l][cmin]);
if (tg==1)
fprintf(f2,"\nCot quay= %d Phan tu quay= %10ld", cmin,s[l][cmin]);
biendoi();sb++;

printf("\nBang %d, khong ke dong n+1, l - chuan",sb);
if (tg==1)
fprintf(f2,"\nBang %d, khong ke dong n+1, l- chuan",sb);
inbang(0); lc=n+1;
//Bat dau buoc lap lon, da tim duoc bang xuat phat l- chuan
Lap1: blap++; 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 cot phuong an con thanh phan am khong
ka=-1;
for (i=1; i<=n; i++) if (s[i][0]<0) {ka = i; break; }

Bùi Thế Tâm V.18 Quy hoạch rời rạc

printf("\nPhan tu am cua phuong an ung voi dong %d",ka);
if (tg==1)
fprintf(f2,"\nPhan tu am cua phuong an ung voi dong %d",ka);
// Bang don hinh la toi uu
if (ka==-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] = %13ld",cs[i],s[i][0]);
printf("\nSo luong lat cat: %d lat cat",blap-1);
printf("\nSo bang da lap : %d bang",sb);
if (tg==1)
{ for (i=0; i<=n;i++)

fprintf(f2,"\nx[%2d] = %13ld",cs[i],s[i][0]);
fprintf(f2,"\nSo luong lat cat: %d lat cat",blap-1);
fprintf(f2,"\nSo bang 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;
}
// Kiem tra tinh khong giai duoc
k=0;
for (j=1; j<=m; j++) if (s[ka][j]< 0) { k=j; break;}
if (k==0) {
printf("\n \nBai toan QHTT nguyen khong giai duoc, STOP");
if (tg==1)
fprintf(f2,"\n\nBai toan QHTT nguyen khong giai duoc, STOP");
getch(); getch(); getch(); return; }
// Tim cot quay

Bùi Thế Tâm V.19 Quy hoạch rời rạc

cmin=k;
for (j=k+1;j<=m;j++) if (s[ka][j]< 0)
{ for (i=0; i<=n;i++)
{ if (s[i][cmin] > s[i][j]) {cmin=j; break;}
if (s[i][cmin] < s[i][j]) break;

}
}
printf("\nCot quay = %d",cmin);
if (tg==1) fprintf(f2,"\nCot quay = %d ",cmin);
// Xay dung lat cat
lamda = -s[ka][cmin];
printf("\nlamda = %10ld",lamda);
if (tg==1) fprintf(f2,"\nlamda = %10ld",lamda);
for (j=1;j<=m;j++) np[j]=0;
for (j=1;j<=m; j++) if (s[ka][j]<0) np[j]=1; np[cmin]=0;
printf("\nMang NP : ");
for (j=1;j<=m;j++) printf("%d ",np[j]); printf("\n");
if (tg==1) {
fprintf(f2,"\nMang NP : ");
for(j=1;j<=m;j++) fprintf(f2,"%d ",np[j]); fprintf(f2,"\n"); }
// Xet np co trong hay khong
trong=1;
for (j=1; j<=m; j++) if (np[j]==1) {trong=0; break;}
if (trong==1) goto L2;
// Truong hop np khac trong, tim hl
for (i=0;i<=n;i++) if (s[i][cmin]>0) {hl=i; break;}
printf("\nh[%d] = %d",cmin,hl);
if (tg==1) fprintf(f2,"\nh[%d] = %d",cmin,hl);
// Tim cac hj ung voi cac cot ma np[j]=1
for (j=1;j<=m;j++)
if (np[j]==1)
{ for (i=0;i<=n;i++) if (s[i][j]>0) {hj=i; break;}
printf("\nh[%d] = %d",j,hj);
if (tg==1) fprintf(f2,"\nh[%d] = %d",j,hj);
if (hj != hl) np[j]=0; // np chi xet voi j ma hj=hl

}

Bùi Thế Tâm V.20 Quy hoạch rời rạc

printf("\nMang NP : ");
for (j=1;j<=m;j++) printf("%d ",np[j]); printf("\n");
if (tg==1) {
fprintf(f2,"\nMang NP : ");
for(j=1;j<=m;j++) fprintf(f2,"%d ",np[j]); fprintf(f2,"\n"); }
// Kiem tra tap np khac trong hay khong
trong=1;
for (j=1; j<=m; j++) if (np[j]==1) {trong=0; break;}
if (trong==1) goto L2;
// Tinh cac zj
for (j=1;j<=m;j++) zj[j]=0;
for (j=1;j<=m;j++) if (np[j]==1)
{ if (s[hl][j]==s[hl][cmin]) zj[j]=1; // kha nang 1
else
{if (s[hl][j]%s[hl][cmin]>0) zj[j]=s[hl][j]/s[hl][cmin]; // kha nang 2
else { q = s[hl][j]/s[hl][cmin]; is = hl;
while (s[is][j]== q* s[is][cmin]) is++;
if (s[is][j]> q* s[is][cmin]) zj[j]=q; // kha nang 3
else zj[j]=q-1; // kha nang 4
}
}
}
// In mang ZJ
printf("\nMang ZJ : ");
for (j=1;j<=m;j++) printf("%d ",zj[j]); printf("\n");
if (tg==1) {

fprintf(f2,"\nMang ZJ : ");
for(j=1;j<=m;j++) fprintf(f2,"%d ",zj[j]); fprintf(f2,"\n"); }
// Tinh lai lamda
for (j=1;j<=m;j++) if (np[j]==1)
{ if ((-s[ka][j])%zj[j]==0) q= (-s[ka][j])/zj[j];
else q= (-s[ka][j])/zj[j]+1;
if (q>lamda) lamda=q; }
// Da tinh xong lamda, xay dung lat cat
L2: printf("\nlamda cuoi cung = %ld",lamda);
if (tg==1) fprintf(f2,"\nlamda cuoi cung = %ld",lamda);

Bùi Thế Tâm V.21 Quy hoạch rời rạc

lc++; cs[n+1]=lc;
for (j=0; j<=m; j++)
{ if (s[ka][j]>=0) s[n+1][j]=s[ka][j]/lamda;
else
{ if ((-s[ka][j])%lamda==0) s[n+1][j]=s[ka][j]/lamda;
else s[n+1][j]=s[ka][j]/lamda-1; }
}
printf("\nBang %d, sau khi them lat cat moi",sb);
if (tg==1)
fprintf(f2,"\nBang %d, sau khi them lat cat moi",sb);
inbang(1);
// Bien doi bang don hinh
l=n+1 ; printf("\nDong quay = %d",l);
if (tg==1) fprintf(f2,"\nDong quay = %d",l);
biendoi(); sb++;
printf("\nBang %d, khong ke dong n+1",sb);
if (tg==1) fprintf(f2,"\nBang %d, khong ke dong n+1",sb);

inbang(0);
goto Lap1;
}
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];
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++)

Bùi Thế Tâm V.22 Quy hoạch rời rạc

printf(" %10ld ",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," %10ld ",s[i][j]);
fprintf(f2,"\n"); }
}
getch();
}
• 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] = 288
x[ 1] = 56
x[ 2] = 29
x[ 3] = 0
x[ 4] = 18
x[ 5] = 1
x[ 6] = 414
x[ 7] = 0
x[ 8] = 523
Số lượng lát cắt: 5 lát cắt
Số bảng đã lập : 7 bảng
BÀI TẬP
Giải các bài toán quy hoạch tuyến tính nguyên sau bằng thuật toán Gomory thứ
ba:
Bài 1. Max x0 = x1 + x2
3 * x1 + 2 * x2 <= 5
x2 <= 2
x1, x2 => 0 và nguyên
Đáp số : (x0, x1, x2, x3, x4) = (2; 1; 1; 0; 1)
Bài 2. Max x0 = 3 * x1 – 4 * x2
- 2 * x1 + x2 <= 3
x1 – 2 * x2 <= 3
2 * x1 + x2 <= 10


Bùi Thế Tâm V.23 Quy hoạch rời rạc

x1, x2 => 0 và nguyên
Đáp số : (x0, x1, x2, x3, x4, x5) = (9; 3; 0; 9; 0; 4)
Bài 3. Max x0 = x1 – x2
- 2 * x1 + 2 * x2 + x3 = 2
x1 – 2 * x2 + x4 = 3
x1 + x2 + x5 = 6
x1, x2, x3, x4, x5 => 0 và nguyên
Đáp số : (x0, x1, x2, x3, x4, x5) = ( 4; 5; 1; 10; 0; 0)
Bài 4. Max x0 = x1 – 2 * x2
5 * x1 – 2 * x2 <= 3
x1 + x2 => 1
-3 * x1 + x2 <= 3
x1, x2, x3 => 0 và nguyên
Đáp số : ( x0, x1, x2, x3, x4, x5) = ( -1; 1; 1; 0; 1; 5)
Bài 5.

(
)
012
123
124
125
ax
9
47 4
56 6
0, 1, ,5
ªn,

j
=1, ,5
j
j
mx xx
xxx
xxx
xxx
xj
xnguy
≡ +
++=
− ++=
− +=
≥ =


Đáp số : ( x0, x1, x2, x3, x4, x5) = (5; 3; 2; 4; 2; 3)
Bài 6. Max
43210
252 xxxxx
+
+

=

6557
4321



+

− xxxx
493765
4321

+

− xxxx
24642
4321



+
− xxxx
-3

+
+
+
4321
89 xxxx
16827
4321

+


− xxxx

43210
,,,, xxxxx
nguyên.
Đáp số: phương án tối ưu mở rộng (294, 26, 0, 40, 34, 10, 1, 192, 655, 26)

×