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

Tiểu luận tối ưu hóa "Cài đặt thuật toán đơn hình trên ngôn ngữ C"

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 (1.1 MB, 34 trang )





TRƯỜNG ĐH HỒNG ĐỨC
KHOA CNTT&TT








BÀI TIỂU LUẬN

HỌC PHẦN TỐI ƯU HÓA


Đề tài:
“Cài đặt thuật toán đơn hình trên ngôn ngữ C”




SVTH : Bùi Hữu Giáp
Lớp : Đại học tin – K15
MSV : 1261030003





Thanh Hóa, 5/2014



TRƯỜNG ĐH HỒNG ĐỨC
KHOA CNTT&TT







BÀI TIỂU LUẬN

HỌC PHẦN TỐI ƯU HÓA


Đề tài:
“Cài đặt thuật toán đơn hình trên ngôn ngữ C”




SVTH : Bùi Hữu Giáp
Lớp : Đại học tin – K15
MSV : 1261030003
GVHD : Trịnh Thị Phú





Thanh Hóa, 5/2014



LỜI CẢM ƠN

Trong quá trình học tập tại trường, em đã được học hỏi và tiếp thu rất nhiều
kiến thức đại cương cũng như chuyên ngành nhằm nâng cao vốn hiểu biết và là
hành trang quý báu giúp em vững bước vào đời. Em xin gửi lời cảm ơn chân thành
đến khoa Công Nghệ Thông Tin và truyền thông, quý thầy cô đã giảng dạy
chúng em trong suốt thời gian qua, cũng như tất cả quý thầy cô trong trường Đại
học Hồng Đức. Đặc biệt em xin chân thành cảm ơn cô Trịnh Thị Phú – Giảng
viên trực tiếp giảng dạy học phần Tối ưu hóa và đồng thời là người tận tình hướng
dẫn em trong suốt thời gian thực hiện đề tài này.
Tuy nhiên, dù rất cố gắng nhưng do thời gian có hạn nên chắc rằng bài tiểu
luận của em khó tránh khỏi những thiếu sót. Em rất mong nhận được sự thông
cảm và đóng góp ý kiến của quý thầy cô và các bạn để bài tiểu luận của em được
hoàn chỉnh hơn.
Em xin chân thành cảm ơn!


Thanh Hóa, 5/2014
Sinh viên thực hiện






MỤC LỤC

CHƯƠNG I: MỞ ĐẦU 1
1.1. Lí do chọn đề tài 1
1.2. Mục tiêu và nhiệm vụ của đề tài 1
1.1.1. Mục tiêu đề tài 1
1.1.2. Nhiệm vụ đề tài 1
1.3. Khách thể, đối tượng và phạm vi nghiên cứu 2
1.1.1. Khách thể nghiên cứu 2
1.1.2. Đối tượng và phạm vi nghiên cứu 2
1.4. Các phương pháp nghiên cứu 2
CHƯƠNG II: CƠ SỞ LÍ LUẬN 3
2.1. Dạng chính tắc và dạng chuẩn tắc 3
2.1.1. Định nghĩa 3
2.1.2. Các phép biến đổi 3
2.1.3. Phương án cơ bản 4
2.1.4. Các tính chất 5
2.2. Phương pháp đơn hình 5
2.2.1. Nội dung 5
2.2.2. Bảng đơn hình 6
2.2.3. Cơ sở lí luận 7
2.2.4. Các bước giải bài toán đơn hình 7
2.2.5. Bài toán ẩn phụ 9
2.2.6. Bài toán ẩn giả 10
PHẦN III: NỘI DUNG 14
3.1. Tổ chức lưu trữ bài toán 14
3.2. Đọc dữ liệu từ tệp 15
3.3. Chuẩn hóa bài toán 17
3.4. Tìm các phần tử thuộc ma trận đơn vị 20

3.5. Khởi tạo giá trị 21
3.6. Kiểm tra tính dừng của thuật toán 22
3.7. Biến đổi bảng đơn hình 24
3.8. Các hàm khác trong chương trình 26
3.9. Thực hiện công việc giải bài toán. 26
PHẦN IV: KẾT LUẬN 28
4.1. Tóm tắt kết quả nghiên cứu 28
4.2. Đề xuất và hướng phát triển 28
TÀI LIỆU THAM KHẢO 30
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
1
GVHD: Trịnh Thị Phú


PHẦN I: MỞ ĐẦU


1.1. Lí do chọn đề tài
Cùng với sự phát triển mạnh mẽ của khoa học – kĩ thuật, các bài toán tối ưu
trong các lĩnh vực thực tiễn xuất hiện ngày càng nhiều với quy mô ngày càng lớn
và tính phức tạp ngày càng cao. Phạm vi và khả năng ứng dụng của chúng cũng
ngày càng đa dạng và phong phú nhằm mục đích đưa chi phí sử dụng xuống mức
tối thiểu và mang lại hiệu quả tối đa. Những bài toán thực tế này khi được tối ưu
tốt có thể ảnh hưởng sống còn đối với sự phát triển của một doanh nghiệp, một
công ti, một quốc gia, … mang lại một hiệu quả kinh tế không hề nhỏ.
Thuật toán đơn hình (simplex algorithm) được George Bernard Dantzig đưa
ra năm 1947 cùng lúc với việc ông khai sinh ra quy hoạch tuyến tính. Đây là một

phương pháp thực sự có hiệu quả để giải những bài toán quy hoạch tuyến tính cỡ
lớn trong thực tế. Nó là một trong những thuật toán làm thay đổi thế giới, được
tạp chí Ecommerce Times xếp vào top 10 thuật toán của mọi thời đại.
Nhằm mang lại cho các bạn những kiến thức cơ bản về thuật toán đơn hình,
đồng thời đưa ra một giải pháp cụ thể để cài đặt chương trình, tôi đã quyết định
lựa chọn đề tài “Cài đặt thuật toán đơn hình bằng ngôn ngữ C”. Để có thể nắm rõ
được những thuật toán, các bước cài đặt cũng như cách thức tổ chức hoạt động
của chương trình, mời các bạn tìm hiểu phần nội dung đề tài.
1.2. Mục tiêu và nhiệm vụ của đề tài
1.1.1. Mục tiêu đề tài
Đề tài này được thực hiện nhằm tạo ra một chương trình thực hiện việc giải
bài toán quy hoạch tuyến tính bằng thuật toán đơn hình.
1.1.2. Nhiệm vụ đề tài
- Tổ chức lưu trữ bài toán.
- Tổ chức đọc giữ liệu từ tệp.
- Chuẩn hóa bài toán.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
2
GVHD: Trịnh Thị Phú


- Tìm các phần tử thuộc ma trận đơn vị.
- Khởi tạo giá trị cho các biến tại bảng đơn hình đầu tiên.
- Kiểm tra tính dừng của thuật toán.
- Biến đổi bảng đơn hình.
- Thực hiện công việc lặp để giải bài toán đồng thời hiển thị từng bước ra
màn hình.

1.3. Khách thể, đối tượng và phạm vi nghiên cứu
1.1.1. Khách thể nghiên cứu
Cài đặt một chương trình thực hiện công việc giải bài toán quy hoạch tuyến
tính bằng phương pháp đơn hình trên ngôn ngữ C.
1.1.2. Đối tượng và phạm vi nghiên cứu
Chương trình giải bài toán quy hoạch tuyến tính bằng phương pháp đơn hình.
1.4. Các phương pháp nghiên cứu
- Phương pháp thu thập tài liệu: thu thập tài liệu từ những bài báo khoa học,
các trang web tin học và một số ebook về đề tài nghiên cứu, giáo trình và các tài
liệu học tập khác.
- Phương pháp phân tích và tổng hợp tài liệu: từ những tài liệu đã thu thập,
tiến hành tìm hiểu, phân tích và tồng hợp nội dung liên quan đến đề tài.
- Phương pháp chuyên gia: trong quá trình nghiên cứu có sự góp ý, điều
chinh từ giáo viên hướng dẫn.
- Phương pháp phân tích và tổng hợp kinh nghiệm: sau quá trình tìm hiểu và
đúc kết kinh nghiệm, tiến hành tổng hợp và hoàn thiện đề tài.
- Phương pháp thực nghiệm: sau khi cài đặt xong chương trình cần xây dựng
một số bộ test tiêu biểu và thực hiện kiểm tra tính đúng đắn dựa trên kết quả thu
được từ chương trình.

Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
3
GVHD: Trịnh Thị Phú


PHẦN II: CƠ SỞ LÍ LUẬN



2.1. Dạng chính tắc và dạng chuẩn tắc
2.1.1. Định nghĩa
Trong thực tế, đa số các bài toán có điều kiện không âm của các ẩn. Từ đó
có định nghĩa dạng chính tắc là bài toán (Ɗ, ƒ) như sau:

(

)
=





→


(1)






=


(
=1 

)
(2)




≥0
(
=1 
)
(3)

Trong đó, (2) gọi là ràng buộc cưỡng bức, (3) gọi là ràng buộc tự nhiên. Với
bài toán (Ɗ, ƒ) chính tắc, có thể giả sử m ≤ n.
Một trường hợp đặc biệt của dạng chính tắc là ma trận số liệu A = (a
ij
)
m x n

có chứa đủ m vector cột là m vector đơn vị của không gian R
m
và b
i
≥ 0 (i = 1 m)
gọi là dạng chuẩn tắc. Không mất tính tổng quát, có thể định nghĩa bài toán (Ɗ,
ƒ) chuẩn tắc như sau:

(

)

=







→



+







=

(=1 )


≥0
(
=1 
)



Trong đó: b
i
≥ 0 (i = 1 m).
2.1.2. Các phép biến đổi
Các phép biến đổi sau để đưa bài toán (Ɗ, ƒ) bất kì về dạng chính tắc tương
đương để giải, và từ đó suy ra nghiệm của bài toán ban đầu.
- ƒ(x) → max ⟺ g(x) = - ƒ(x) → min
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
4
GVHD: Trịnh Thị Phú


-





≤










+

=



với x
n+i
≥ 0





≥









−




=

với x
n+i
≥ 0
x
i+n
gọi là ẩn phụ. Có kết luận sau:
Nếu  = (x
1
, x
2
, …, x
n
, x
n+1
, …, x
n+m
) là nghiệm của bài toán chính tắc
biến đổi thì x = (x
1
, x
2
, …, x
n
) là nghiệm của bài toán gốc.
- Nếu ẩn x
j
không ràng buộc về dấu thì được thay bằng hiệu hai ẩn
không âm. Nghĩa là đặt x

j
= 


+ 


với 


≥ 0 và 


≥ 0.
- Trường hợp b
j
< 0 thì nhân hai vế phương trình với -1 có được b
j
> 0.
Vậy: Mọi bài toán quy hoạch tuyến tính đều có thể đưa về bài toán dạng
tương đương. Hơn nữa, có thể các hệ số tự do bj trong hệ ràng buộc là không âm.
2.1.3. Phương án cơ bản
Xét bài toán (Ɗ, ƒ) dạng chính tắc:

(

)
=






→









=


(
=1 
)




≥0
(
=1 
)


Đặt A

j
= (a
1j
, a
2j
, …, a
mj
) là vector cột thứ j trong ma trận A
mxn

b = (b
1
, b
2
, …, b
m
) là cột hệ số tự do.
Giả sử X = (

,

,…,

) là phương án của bài toán thì hệ vector {A
j
|

>0}
gọi là hệ vector liên kết với phương án X.
Định nghĩa: X


Ɗ là phương án cơ bản nếu hệ vector liên kết với X độc lập
tuyến tính. Ẩn x
j
gọi là ẩn cơ bản nếu 

> 0.
Nhận xét:
- Phương án cơ bản có tối đa m thành phần dương. Phương án cơ bản
có đúng m thành phần dương gọi là không suy biến. Ngược lại được
gọi là suy biến. Bài toán có phương án cơ bản suy biến gọi là bài toán
suy biến.
- Số phương án cơ bản của một bài toán (Ɗ, ƒ) là hữu hạn.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
5
GVHD: Trịnh Thị Phú


- Với bài toán dạng chuẩn tắc thì có phương án cơ bản là X
0
= (b
1
, b
2
,
…, b
m

, 0, …, 0).
2.1.4. Các tính chất
Tính chất 1: Bài toán (Ɗ, ƒ) chỉ xảy ra 1 trong 3 trường hợp sau:
- Vô nghiệm.
- Có một nghiệm duy nhất.
- Vô số nghiệm.
Tính chất 2: Nếu hàm mục tiêu ƒ(x) là chặn dưới (trên) đối với bài toán
dạng min (max) trên tập phương án Ɗ thì bài toán (Ɗ, ƒ) có nghiệm.
Tính chất 3: Nếu bài toán (Ɗ, ƒ) có nghiệm thì có nghiệm là phương án cơ
bản.
2.2. Phương pháp đơn hình
2.2.1. Nội dung
Xuất phát từ phương án cơ bản nào đó, tìm cách đánh giá nó. Nếu chưa tối
ưu thì chuyển sang phương án cơ bản mới tốt hơn. Nếu bài toán có nghiệm thì sau
hữu hạn bước sẽ tìm được phương án cơ bản tối ưu. Hơn nữa dấu hiệu vô nghiệm
cũng đươc thể hiện trên thuật toán.
Ví dụ 2.1: Xét bài toán (Ɗ, ƒ) dạng chuẩn tắc:
ƒ(x) = x
1
– 2x
2
+ 3x
3
– 2x
4
→ min

2

−3


+

=4


+

+

=5


≥0
(
=1 4
)


Có phương án cơ bản X
0
= (0, 0, 4, 5) và ƒ(X
0
) = 2 với x
3
, x
4
là ẩn cơ bản.
Đánh giá:
∀ x = (x

1
, x
2
, x
3
, x
4
) ∈ Ɗ:

2

−3

+

=4


+

+

=5


≥0
(
=1 4
)






=4−2

+3



=5−

−



≥0
(
=1 4
)


ƒ(x) = x
1
– 2x
2
+ 3x
3
– 2x
4


= x
1
– 2x
2
+ 3(4 – 2x
1
+ 3x
2
) – 2(5 – x
1
– x
2
)
= 2 – 3x
1
+ 9x
2

Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
6
GVHD: Trịnh Thị Phú


= 2 - ∆
1
x

1
– ∆
2
x
2
Vì x
1
, x
2
≥ 0 nên nếu ∆
1
, ∆
2
≤ 0 thì ƒ(X) ≥ 2 và X
0
là phương án tối ưu. Tuy
nhiên, ở đây ∆
1
= 3 > 0 nên X
0
chưa phải là nghiệm.
Thử chọn x
1
, x
4
làm ẩn cơ bản, cho x
2
= 0 và x
3
= 0. Có:


2

=4


+

=5
⇒ x
1
= 2 và x
4
=3.
Rõ ràng A
1
, A
4
độc lập tuyến tính nên có phương án cơ bản là  = (2, 0, 0,
3) và ƒ() = -4.
Đánh giá:
∀ x = (x
1
, x
2
, x
3
, x
4
) ∈ Ɗ:


2

−3

+

=4


+

+

=5




=2+












=3−




+





ƒ(x) = x
1
– 2x
2
+ 3x
3
– 2x
4

= (2 +


x
2



x

3
) – 2x
2
+ 3x
3
– 2(3 –


x
2
+


x
3
)
= -4 +


x
2
+


x
3
(= -4 – ∆
2
x
2

– ∆
3
x
3
)
≥ -4
Vì x
2
, x
3
≥ 0 nên  là phương án tối ưu (∆
2
, ∆
3
≤ 0).
2.2.2. Bảng đơn hình
Cho bài toán (Ɗ, ƒ) chuẩn tắc:

(

)
=







→




+







=

(=1 )


≥0
(
=1 
)


Trong đó: b
i

≥ 0 (i = 1 m).
∀j = 1 n đặt ∆
j

=






−



và gọi là ước lượng của ẩn x
j
đối với
phương án cơ bản X
0
= (b
1
, b
2
, …, b
m
, 0, …, 0) với ƒ(X
0
) =









Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
7
GVHD: Trịnh Thị Phú


Lưu ý: ∆
i
= 0, ∀ i = 1 m
Có bảng đơn hình sau:
2.2.3. Cơ sở lí luận
Cho bài toán (Ɗ, ƒ) chuẩn tắc:

(

)
=







→




+







=

(=1 )


≥0(=1 )

Trong đó: b
i
≥ 0 (i = 1 m).
∀j =1 , đặt ∆
j
=





−





Có phương án cơ bản X
0
= (b
1
, b
2
, …, b
m
, 0, , 0) với ƒ(X
0
) =







.
Định lí 1 (Dấu hiệu tối ưu): Nếu ∆
j

≤ 0 ∀j = 1 n thì X
0
là phương án tối ưu.
Định lí 2 (Dấu hiệu vô nghiệm): Nếu ∃∆
k


> 0 và a
jk
≤ 0 ∀i =1 m thì bài toán
vô nghiệm.
Định lí 3 (Điều chỉnh phương án): Nếu ∃∆
k

> 0 và ∃a
jk
> 0 thì có thể tìm
được phương án cơ bản mới tốt hơn X
0
, trong trường hợp bài toán không suy biến.
2.2.4. Các bước giải bài toán đơn hình
Bước 1: Kiểm tra tính tối ưu của phương án X
0
= (b
1
, b
2
, …, b
m
, 0, , 0)
- Nếu ∆
j
≤ 0 ∀j =1 n thì X
0
là phương án tối ưu và ƒ
min
= ƒ(X

0
)
=








- Nếu ∃∆
k

> 0 thì chuyển tới bước 2.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
8
GVHD: Trịnh Thị Phú


Bước 2: Kiểm tra điều kiện vô nghiệm
- Nếu ∃∆
k

> 0 và a
jk
≤ 0 ∀i = 1 m thì bài toán vô nghiệm.

- Nếu ∃∆
k

> 0 và ∃a
jk
> 0 thì chuyển tới bước 3.
Bước 3: Tìm ẩn thay thế và loại ra
- Nếu ∆
s

= max {∆
j
} với

j

> 0 (i = 1 n) thì đưa x
s
vào tập ẩn cơ bản.
- Nếu




= min {




} với a

is
> 0 thì loại x
r
ra khỏi tập ẩn cơ bản.
- Chuyển sang bước 4.
Bước 4: Biến đổi bảng đơn hình
- Biến đổi bảng đơn hình theo công thức sau:




=








=








(≠)






=Ѳ



=








(≠)

- Tính lại các ∆
j
, quay lại bước 1.
Quá trình này có thể được mô tả như việc biến đổi sơ cấp về hàng trên ma
trận bổ sung của của hệ ràng buộc sao cho vector A
s
, trở thành đơn vị thứ r, và
các vector đơn vị khác vẫn giữ nguyên.
Nhận xét: Các công thức biến đổi cho a
ij

cũng đúng cho cả b
j
và ∆
j
nếu xem
b là cột thứ 0 và ∆ là hàng thứ m + 1 của ma trận số liệu A
mxn
.
Ví dụ 2.2:
ƒ(x) = 5x
1
+ 4x
2
+ 5x
3
+2x
4
+x
5
+ 3x
6
→ min



2

+4

+3


+

=52
4

+2

+3

+

=60
3

+

+

=36


≥0
(
=1 6
)


Cài đặt chương trình thực hiện các phép toán trên đa thức một biến



SVTH: Bùi Hữu Giáp
9
GVHD: Trịnh Thị Phú



j
≤ 0 ∀j = 1 6, x
opt
= (12, 6, 0, 4, 0, 0) và ƒ
min
= 92.
2.2.5. Bài toán ẩn phụ
Cho phép biến đổi để đưa bài toán (Ɗ, ƒ) về dạng chính tắc





≤










+

=



với x
n+i
≥ 0





≥









−

=




với x
n+i
≥ 0
x
n+i
được gọi là ẩn phụ. Có kết luận sau:
Nếu  = (x
1
, x
2
, …, x
n
, x
n+1
, , x
n+m
) là nghiệm của bài toán chính tắc biến
đổi thì X = (x
1
, x
2
, …, x
n
) là nghiệm của bài toán gốc.
Ví dụ 2.4:
Bài toán chính tắc tương đương:

Cài đặt chương trình thực hiện các phép toán trên đa thức một biến



SVTH: Bùi Hữu Giáp
10
GVHD: Trịnh Thị Phú


Trong đó x
5
, x
6
là ẩn phụ.
Đây là bài toán (Ɗ, ƒ) chuẩn tắc nên được đưa vào bảng đơn hình để giải.

j
≤ 0 ∀ j = 1 6, x
opt
= (4, 5, 0, 0, 0, 11) và ƒ
min
= -11. Vậy nghiệm của bài
toán gốc là x
opt
= (4, 5, 0, 0) và ƒ
min
= -11.
Nếu các giá trị min/max đạt được tại nhiều vị trí thì chọn tùy ý một vị trí bất
kì trong số đó. Thông thường chọn chỉ số nhỏ nhất.
2.2.6. Bài toán ẩn giả
Cho bài toán (Ɗ, ƒ) dạng chính tắc:

(


)
=







→








=

(=1 )


≥0(=1 )

Trong đó: b
i

≥ 0 (i = 1 m).
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến



SVTH: Bùi Hữu Giáp
11
GVHD: Trịnh Thị Phú


Xét bài toán:




=







+





→







+

=

(=1 )




≥0
(
=1 +
)


Với M là số dương khá lớn (M ⟶ ∞).
Bài toán này gọi là bài toán mở rộng của bài toán trên, hay bài toán M.
Với bài toán M có ngay phương án cơ bản ban đầu với x
n+i
(i =1,) là các ẩn cơ
bản.
Dùng thuật toán đơn hình để giải.
x
n+i
gọi là các ẩn giả.
Sau khi giải bài toán M có được quan hệ giữa bài toán M và bài toán (Ɗ, ƒ)
như sau:

- Nếu bài toán M vô nghiệm thì bài toán (Ɗ, ƒ) vô nghiệm.
- Nếu bài toán M có nghiệm = (x
1
, x
2
, …, x
n
, 0, , 0) thì X = (x
1
, x
2
,
…, x
n
) là nghiệm của bài toán (Ɗ, ƒ).
- Nếu bài toán M có nghiệm = (x
1
, x
2
, …, x
n+m
) và ∃ x
m+n
> 0 thì bài
toán (Ɗ, ƒ) vô nghiệm.
Tiến trình giải bài toán M là loại dần các ẩn giả ra khỏi tập ẩn cơ bản cho
đến khi loại tất cả là bắt đầu giải bài toán gốc. Nên từ đó có thể không cần tính
cho các cột ẩn giả. Nếu cuối cùng không loại được các ẩn giả mà nhận giá trị 0 thì
bài toán gốc cũng có nghiệm.
Ở đây giả sử bài toán (Ɗ, ƒ) trong ma trận số liệu A không có vector đơn vị

nào. Tuy nhiên, chỉ cẩn thêm một số (<m) ẩn giả cho đủ m vector đơn vị.
Ví dụ 2.5:
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
12
GVHD: Trịnh Thị Phú


Dạng chính tắc tương đương:
Trong đó x
4
, x
5
là hai ẩn phụ.
Bài toán chính tắc trên cần thêm hai ẩn giả để đưa về bài toán chuẩn tắc là
x
6
, x
7
.
Bài toán M tương ứng :
Đây là bài toán dạng chuẩn tắc nên ta đưa vào bảng đơn hình để giải.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
13
GVHD: Trịnh Thị Phú



Nghiệm của bài toán là  = (


,


,


, 0, 0, 0, 0), ẩn giả đã bị loại từ bảng 3.
Nghiệm của bài toán gốc chính tắc là X = (


,


,


, 0, 0), với x
4
, x
5
là ẩn phụ, nên
có nghiệm của bài toán gốc là X
opt
= (



,


,


, 0, 0) và ƒ
max
=


.

Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
14
GVHD: Trịnh Thị Phú


PHẦN III: NỘI DUNG


3.1. Tổ chức lưu trữ bài toán
Để lưu trữ được bài toán này, những biến sau đã được sử dụng:
Code:
int num_unknown, num_equation, target;
float fx[3][max+1], a[max+1][max+4], Fx[3][max+1], condition[max+1],

Cj[3] [max+1], Xj[max+1];
int Aj[max+1];
Trong đó:
- Hàm mục tiêu được lưu trữ bằng ba biến là target, num_unknown và
fx[3][max+1], num_unknown là số ẩn của bài toán; target là mục
tiêu, nó nhận giá trị -1 nếu hàm mục tiêu tiến tới min và nhận giá trị 1
nếu hàm mục tiêu tiến tới max; fx[3][max+1] là biến dùng để lưu trữ
hệ số của hàm mục tiêu với dòng thứ nhất của ma trận để lưu lại những
hệ số tương ứng trong hàm mục tiêu, dòng thứ hai dùng để đánh dấu
những ẩn có hệ số là M sau khi chuẩn hóa.
- Những điều kiện ràng buộc của bài toán được lưu trữ bằng các biến
num_equation và a[max+1][max+4], num_equation là số ràng
buộc của bài toán; a[max+1][max+4] là biến dùng để lưu trữ các ràng
buộc của bài toán, a[i][j] (i = 1,num_equation, j =
1,num_unknown) ứng với a[i][j] của bài toán, a[i][num_unknown
+1] dùng để lưu dấu của ràng buộc và a[i][num_unknown+2] ứng
với giá trị b
j
của bài toán.
- Những ràng buộc về dấu của biến được lưu trữ bằng biến
condition[max+1] với giá trị của condition[i] ứng với ràng buộc về
dấu của biến x
i
tương ứng.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
15
GVHD: Trịnh Thị Phú



- Fx[3][max+1], Cj[3] [max+1], Xj[max+1], Aj[max+1] lần lượt ứng
với ∆, C
j
, X
j
, A
j
khi tiến hành các bước giải bài toán.
3.2. Đọc dữ liệu từ tệp
Dữ liệu được nhập từ file Sinplex.inp với cấu trúc:
- Dòng đầu tiên là số nguyên dương num_unknown ứng với số ẩn của
bài toán.
- Dòng thứ hai gồm num_unknown + 1 con số với num_unknown con
số đầu tiên kiểu thực ứng với hệ số của các ẩn tương ứng trong hàm
mục tiêu, số nguyên dương thứ num_unknown + 1 ứng với dấu của
hàm mục tiêu, bằng 1 nếu hàm mục tiêu tiến tới max và bằng -1 nếu
hàm mục tiêu tiến tới min.
- Dòng thứ ba chứa số nguyên dương num_equation ứng với số điều
kiện ràng buộc của bài toán.
- num_equation dòng tiếp theo, mối dòng gồm num_unknown + 2
con số ứng với các hàm mục tiêu. Trong đó, num_unknown số thực
đầu tiên ứng với hệ số các phần tử thuộc vế trái của hàm mục tiêu; con
số nguyên thứ num_unknown + 1 ứng với dấu của ràng buộc, nó nhận
giá trị:
+ -2 nếu dấu là <.
+ -1 nếu dấu là <=.
+ 1 nếu dấu là >=.
+ 2 nếu dấu là >.

Con số thực thứ num_unknown + 2 ứng với giá trị của b
j
tương ứng.
- num_unknown dòng tiếp theo, mỗi dòng chứa một con số nguyên
ứng với ràng buộc về dấu của biến tương ứng:
+ -2 nếu dấu là <.
+ -1 nếu dấu là <=.
+ 0 nếu không có ràng buộc về dấu.
+ 1 nếu dấu là >=.
+ 2 nếu dấu là >.
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
16
GVHD: Trịnh Thị Phú


Nếu file Simplex.inp không tồn tại hoặc giá trị num_unknown quá lớn so
với số lượng quy định của chương trình thì thông báo cho người dùng và kết thúc
chương trình.
Ví dụ: Để nhập dữ liệu cho bải toán
ƒ(x) = x
1
– 2x
2
+ 3x
3
– 2x
4

→ min

2

−3

+

=4


+

+

=5


≥0
(
=1 4
)


ta nhập bộ dữ liệu vào file Sinplex.inp với nội dung như sau:
Code:
void read()
{
FILE *f=fopen("Simplex.inp","r");
if (f==NULL)

{
printf("File Problem.inp khong ton tai, vui long kiem tra va chay lai chuong
trinh!");
printf("\nNhan phim bat ki de thoat ");
getch();
exit(0);
}
fscanf(f,"%d",&num_unknown);
num_unknown_i=num_unknown;
for (int i=1; i<=num_unknown; i++)
{
fscanf(f,"%f",&fx[1][i]);
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
17
GVHD: Trịnh Thị Phú


fx[2][i]=0;
}
fscanf(f,"%d",&target);
fscanf(f,"%d",&num_equation);
for (int i=1; i<=num_equation; i++)
for (int j=1; j<=num_unknown+2; j++)
fscanf(f,"%f",&a[i][j]);
for (int i=1; i<=num_unknown; i++)
fscanf(f,"%f",&condition[i]);
fclose(f);

}
3.3. Chuẩn hóa bài toán
Công việc này sẽ được hàm int standardize() thực hiện với các công việc
sau:
Duyệt lần lượt điều kiện xác định của các ẩn, nếu x
j
không ràng buộc về dấu
hoặc có ràng buộc nhưng là dấu âm thì ta thay bằng hiệu hai ẩn không âm. Nghĩa
là đặt x
j
= x’
j
– x’’
j
với x’
j

≥ 0 và x’’
j
≥ 0.
Code:
for (int i=1; i<=num_unknown; i++)
if (condition[i]<=0)
{
num_unknown++;
for (int j=num_unknown+2; j>i+1; j )
{
fx[1][j]=fx[1][j-1];
fx[2][j]=fx[2][j-1];
for (int k=1; k<=num_equation; k++)

a[k][j]=a[k][j-1];
condition[j]=condition[j-1];
}
fx[1][i+1]=-fx[1][i];
fx[2][i+1]=-fx[1][i];
for (int k=1; k<=num_equation; k++)
a[k][i+1]=-a[k][i];
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
18
GVHD: Trịnh Thị Phú


condition[i]=1;
condition[i+1]=1;
}
- Duyệt lần lượt các ràng buộc của bài toán, nếu ràng buộc nào mà b
j

có dấu âm thì ta nhân cả hai vế với -1 để có b
j
> 0.
Code:
for (int i=1; i<=num_equation; i++)
if (a[i][num_unknown+2]<0)
{
for (int j=1; j<=num_unknown; j++)
a[i][j]=-a[i][j];

a[i][num_unknown+2]=-a[i][num_unknown+2];
}
- Nếu tồn tại phần tử a[r][j] khác 0 mà a[i][j] bằng 0 với mọi i thì ta
tiến hành chia hai vế của ràng buộc thứ r cho a[r][j].
Code:
for (int i=1; i<=num_unknown; i++)
{
int j=1;
while (j<=num_equation&&a[j][i]==0)
j++;
if (j<=num_equation&&a[j][i]!=1)
{
int check2=1;
for (int k=j+1; k<=num_equation; k++)
if (a[k][i]!=0)
{
check2=0;
break;
}
if (check2)
{
for (int k=1; k<=num_unknown; k++)
if (k!=i)
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
19
GVHD: Trịnh Thị Phú



a[j][k]=(float)a[j][k]/a[j][i];
a[j][num_unknown+2]=(float)a[j][num_unknown+2]/a[j][i];
a[j][i]=1;
}
}
}
- Nếu ràng buộc nào đó không phải là một đẳng thức thì ta tiến hành
thêm ẩn giả.
Code:
for (int i=1; i<=num_equation; i++)
if (a[i][num_unknown+1]!=0)
{
check=1;
num_unknown++;
fx[1][num_unknown]=0;
fx[2][num_unknown]=0;
for (int j=1; j<=num_equation; j++)
{
a[j][num_unknown+2]=a[j][num_unknown+1];
a[j][num_unknown+1]=a[j][num_unknown];
a[j][num_unknown]=0;
}
if (a[i][num_unknown+1]>0)
a[i][num_unknown]=-1;
else if (a[i][num_unknown+1]<0)
a[i][num_unknown]=1;
a[i][num_unknown+1]=0;
condition[num_unknown]=1;
}

- Nếu chưa tồn tại ma trận đơn vị thì ta tiến hành thêm vào các ẩn phụ
cho tới khi nào xuất hiện ma trận đơn vị.
Code:
for (int i=1; i<=num_equation; i++)
Aj[i]=matrix_einheiten(i);
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
20
GVHD: Trịnh Thị Phú


for (int i=1; i<=num_equation; i++)
if (Aj[i]==0)
{
check=1;
M=1;
num_unknown++;
fx[1][num_unknown]=0;
if (target==1)
fx[2][num_unknown]=-1;
else
fx[2][num_unknown]=1;
for (int j=1; j<=num_equation; j++)
{
a[j][num_unknown+2]=a[j][num_unknown+1];
a[j][num_unknown+1]=a[j][num_unknown];
a[j][num_unknown]=0;
}

a[i][num_unknown]=1;
condition[num_unknown]=1;
}
3.4. Tìm các phần tử thuộc ma trận đơn vị
Công việc này được đảm nhiệm bởi hàm int matrix_einheiten(int n). Hàm
này sẽ trả về phần tử thứ n của ma trận đơn vị, nếu không tìm được phần tử này,
hàm trả về giá trị 0.
Hàm này thực hiện các công việc: duyệt từ 1 tới num_unknown, nếu phần
tử a[n][i] có hệ số bằng 1 thì kiểm tra tất cả các phần tử a[j][i] (j ≠ n) xem hệ số
có bằng 0 không, nếu đúng thì trả về giá trị của cột i tương ứng, nếu sai thì tiếp
tục duyệt. Khi đã duyệt hết tất cả các phần tử ở dòng n mà không tìm thấy phần
tử thứ n của ma trận đơn vị thì trả về giá trị 0.
Code:
int matrix_einheiten(int n)
{
for (int i=1;i<=num_unknown;i++)
Cài đặt chương trình thực hiện các phép toán trên đa thức một biến


SVTH: Bùi Hữu Giáp
21
GVHD: Trịnh Thị Phú


if (a[n][i]==1)
{
int check=1;
for (int j=1;j<=num_equation;j++)
if (j!=n&&a[j][i]!=0)
check=0;

if (check)
return i;
}
return 0;
}
3.5. Khởi tạo giá trị
Sau khi dữ liệu được nhập vào, hàm void initial() sẽ được gọi tới để tính giá
trị các biến ở bảng đơn hình thứ nhất để tạo dữ liệu cho các bước lặp sau.
Các công việc được thực hiện báo gồm:
- Chuẩn hóa bài toán bằng cách gọi hàm standardize().
- Tìm ma trận đơn vị, phương án cơ sở và hệ số của ẩn ứng với cơ sở
trong hàm mục tiêu.
Code:
for (int i=1;i<=num_equation;i++)
{
Xj[i]=a[i][num_unknown+2];
Aj[i]=matrix_einheiten(i);
if (fx[1][Aj[i]]!=0)
{
Cj[1][i]=fx[1][Aj[i]];
Cj[2][i]=0;
}
else
{
Cj[1][i]=0;
Cj[2][i]=fx[2][Aj[i]];

×