2009-07-24 15 views
6

Tôi đã tự hỏi nếu có ai có bất kỳ đề xuất nào để giảm thiểu hàm, f (x, y), trong đó x và y là số nguyên. Tôi đã nghiên cứu rất nhiều kỹ thuật tối ưu hóa và tối ưu hóa, như BFGS và các kỹ thuật khác trong GSL, và những thứ trong số Công thức số. Cho đến nay, tôi đã thử implenting một vài đề án khác nhau. Các công trình đầu tiên bằng cách chọn hướng lớn nhất f (x + 1, y), f (x-1, y), f (x, y + 1), f (x, y-1), và làm theo hướng đó với giảm thiểu dòng. Tôi cũng đã thử sử dụng phương thức downhill simplex (Nelder-Mead). Cả hai phương pháp đều bị kẹt ở mức tối thiểu. Cả hai đều xuất hiện để làm việc trên các chức năng đơn giản, như tìm tối thiểu paraboloid, nhưng tôi nghĩ rằng cả hai, và đặc biệt là trước đây, được thiết kế cho các chức năng trong đó x và y có giá trị thực (tăng gấp đôi). Một vấn đề nữa là tôi cần gọi f (x, y) càng ít lần càng tốt. Nó nói chuyện với phần cứng bên ngoài, và mất một vài giây cho mỗi cuộc gọi. Bất kỳ ý tưởng cho điều này sẽ được đánh giá rất nhiều.Giảm thiểu f (x, y) trong đó x và y là số nguyên

Dưới đây là ví dụ về chức năng lỗi. Xin lỗi tôi đã không đăng bài này trước đây. Hàm này mất một vài giây để đánh giá. Ngoài ra, thông tin chúng tôi truy vấn từ thiết bị không thêm vào lỗi nếu nó thấp hơn giá trị mong muốn của chúng tôi, chỉ khi nó ở trên

double Error(x,y) 
{ 
    SetDeviceParams(x,y); 
    double a = QueryParamA(); 
    double b = QueryParamB(); 
    double c = QueryParamC(); 
    double _fReturnable = 0; 
    if(a>=A_desired) 
    { 
    _fReturnable+=(A_desired-a)*(A_desired-a); 
    } 
    if(b>=B_desired) 
    { 
    _fReturnable+=(B_desired-b)*(B_desired-b); 
    } 
    if(c>=C_desired) 
    { 
    _fReturnable+=(C_desired-c)*(C_desired-c); 
    } 
    return Math.sqrt(_fReturnable) 
} 
+1

Bất kỳ ý tưởng nào về lớp học và hành vi của hàm cũng sẽ được đánh giá cao. – EFraim

+1

Câu hỏi thú vị. Hài hước như thế nào toán học đầu tiên trở nên khó khăn khi bạn bắt đầu tìm hiểu về phân số và số thực, và khó khăn một lần nữa một khi bạn loại bỏ chúng và quay trở lại các số tự nhiên. =) –

+1

Bạn có biết phương trình cho f (x, y) không? – Noldorin

Trả lời

2

Làm thế nào để bạn xác định f (x, y)? Giảm thiểu là một vấn đề khó, tùy thuộc vào độ phức tạp của chức năng của bạn.

Thuật toán di truyền có thể là một ứng cử viên tốt.

Resources:

Genetic Algorithms in Search, Optimization, and Machine Learning

Implementing a Genetic Algorithms in C#

Simple C# GA

+0

Bạn có bất cứ đề xuất nào về nguồn lực tốt để bắt đầu với các thuật toán di truyền không? – Tim

+1

Có vô số sách về chủ đề này. Điều khiến tôi bắt đầu là cuốn sách của Goldberg. http://www.amazon.com/Genetic-Algorithms-Optimization-Machine-Learning/dp/0201157675 – Indy9000

3

Bạn đã xem thuật toán di truyền chưa? Họ rất, rất giỏi trong việc tìm kiếm tối thiểu và tối đa, trong khi tránh tối thiểu/tối đa địa phương.

+0

Vâng, chúng dần trở nên tốt hơn, một thế hệ tại một thời điểm! –

+0

Chúng không tuyến tính mặc dù :) – Indy9000

2

Nếu đó là một chức năng tùy ý, không có cách nào để thực hiện việc này một cách gọn gàng.

Giả sử chúng ta có một chức năng được xác định như sau:

f(x, y) = 0 for x==100, y==100 
      100 otherwise 

Làm thế nào có thể bất kỳ thuật toán thực tế tìm (100, 100) là tối thiểu? Nó có thể là bất kỳ sự kết hợp nào của các giá trị.

Bạn có biết bất kỳ điều gì về chức năng bạn đang thử nghiệm không?

+0

f (x, y) là hàm lỗi hiệu chuẩn. Có hai tham số mà tôi quan tâm. Cả hai đều bị ảnh hưởng bởi các thay đổi trong x và y. Hàm này khá liên tục, nhưng đạo hàm của nó có thể không phải vì ngay khi một trong hai tham số nằm trong spec, tôi chỉ đặt nó là 0 – Tim

+2

@Jon Skeet: Đó là tất nhiên giả định rằng hàm có thể là * bất cứ thứ gì *, thực sự buộc bạn phải thử mọi kết hợp (x, y). Nếu bạn biết hàm này là liên tục giả, mọi thứ được đơn giản hóa rất nhiều. – Noldorin

+0

@Noldorin: Đó là lý do tại sao tôi hỏi OP biết gì về chức năng này. Vào thời điểm tôi đăng, chức năng tôi đưa ra sẽ thỏa mãn mọi thứ chúng tôi biết. –

4

Có rất nhiều, rất nhiều giải pháp ở đây. Trong thực tế, có toàn bộ sách và môn học dựa trên chủ đề. Tôi đang đọc một tài liệu xuất sắc ngay bây giờ: How to Solve It: Modern Heuristics.

Không có giải pháp nào đúng - các giải pháp khác nhau có những ưu điểm khác nhau dựa trên kiến ​​thức cụ thể về chức năng của bạn. Nó thậm chí đã được chứng minh rằng không có một heuristic mà thực hiện tốt nhất ở tất cả các nhiệm vụ tối ưu hóa.

Nếu bạn biết rằng hàm của bạn là bậc hai, bạn có thể sử dụng Newton-Gauss để tìm số tiền tối thiểu trong một bước. Một thuật toán di truyền có thể là một công cụ đa năng tuyệt vời, hoặc bạn có thể thử ủ mô phỏng, ít phức tạp hơn.

+0

Tại sao các liên kết của tôi bị hỏng? Nó không giống như thế này trên bản xem trước. –

1

Điều bạn thường tìm kiếm được gọi là optimisation technique trong toán học.Nói chung, chúng áp dụng cho các hàm có giá trị thực, nhưng nhiều hàm có thể được điều chỉnh cho các hàm có giá trị tích phân.

Cụ thể, tôi khuyên bạn nên xem xét non-linear programminggradient descent. Cả hai sẽ có vẻ khá thích hợp cho ứng dụng của bạn.

Nếu bạn có thể cung cấp thêm bất kỳ chi tiết nào, tôi có thể đề xuất một chút cụ thể hơn một chút.

+0

Như tôi đã nói trước khi nó sẽ được sử dụng trong một chương trình hiệu chuẩn, vì vậy sẽ có rất nhiều thiết bị có hình dạng tương tự nhưng không giống nhau cho chức năng lỗi của chúng. Tôi không biết chính xác hình dạng trông như thế nào, bởi vì có rất nhiều dữ liệu mà tôi cần để có được. cả x và y nằm trong khoảng từ 0 đến 65535 và phải mất một vài giây để thu thập một phần dữ liệu. – Tim

+0

@Tim: Đủ công bằng. Có lẽ bạn có thể cho chúng ta hình thức của chức năng lỗi này tuy nhiên? Tôi không lạc quan về thành công ở đây, nếu yêu cầu chỉ mất vài giây! – Noldorin

+0

Đây là cơ bản những gì sẽ xảy ra. Tôi xin lỗi nếu một chút mơ hồ của nó. lỗi kép (x, y) { SetDeviceParams (x, y); double a = QueryParamA(); double b = QueryParamB(); double c = QueryParamC(); double _fReturnable = 0 nếu (a> = A_desired) { _fReturnable + = (A_desired-a) * (A_desired-a); } nếu (b> = B_desired) { _fReturnable + = (B_desired-b) * (B_desired-b); } nếu (c> = C_desired) { _fReturnable + = (C_desired-c) * (C_desired-c); } trả lại Math.sqrt (_fReturnable) } – Tim

1

Câu trả lời của Jon Skeet là chính xác. Bạn thực sự cần thông tin về f và dẫn xuất của nó ngay cả khi f là ở khắp mọi nơi liên tục. Cách dễ nhất để đánh giá cao những khó khăn của những gì bạn yêu cầu (chỉ giảm thiểu f ở các giá trị số nguyên) chỉ là suy nghĩ về một hàm f: R-> R (f là một hàm thực giá trị thực của một biến). làm cho chuyến du ngoạn lớn giữa các số nguyên riêng lẻ. Bạn có thể dễ dàng xây dựng một hàm như vậy để KHÔNG có sự sửa đổi giữa các mức tối thiểu cục bộ trên đường thực và mức tối thiểu ở các số nguyên cũng như không có mối quan hệ với đạo hàm đầu tiên.

Đối với một chức năng tùy ý, tôi không thấy cách nào ngoại trừ sức mạnh vũ phu.

+0

Dựa trên thử nghiệm mà tôi đã thực hiện, gradient nhỏ ở khắp mọi nơi, vì vậy hàm không thay đổi nhiều giữa các giá trị số nguyên, nhưng tôi không thể dự đoán theo hướng nào nó sẽ thay đổi. Lực lượng vũ phu sẽ không hoạt động, vì mất quá nhiều thời gian để có được một mẩu dữ liệu duy nhất – Tim

+0

vì vậy hiện tại bạn đang nói rằng ngoài vấn đề chỉ xem xét các giá trị tích phân bạn không biết sự kiện f và bạn sẽ chỉ lấy mẫu tập hợp con của {(x, y)} và cố gắng rút ra kết luận từ một tập con giới hạn? –

+0

@pgast Thật không may, đó là khá nhiều những gì tôi đang nói. Tôi có đủ dữ liệu mà tôi có một dự đoán tốt về một điểm khởi đầu, nhưng đó là về nó. Tin tốt là tôi không nhất thiết phải quan tâm đến giải pháp "tốt nhất", miễn là giải pháp tôi nhận được đáp ứng thông số – Tim

0

Rất tiếc, định dạng này quá tệ trước đó. Dưới đây là ví dụ về hàm lỗi

double Error(x,y) 
{ 
SetDeviceParams(x,y); 
double a = QueryParamA(); 
double b = QueryParamB(); 
double c = QueryParamC(); 
double _fReturnable = 0; 
if(a>=A_desired) 
{ 
    _fReturnable+=(A_desired-a)*(A_desired-a); 
} 
if(b>=B_desired) 
{ 
_fReturnable+=(B_desired-b)*(B_desired-b); 
} 
if(c>=C_desired) 
{ 
    _fReturnable+=(C_desired-c)*(C_desired-c); 
} 
return Math.sqrt(_fReturnable) 
} 
+0

Tim, chỉnh sửa CÂU HỎI của bạn để đăng bài này. –

+0

Ah, vâng, tôi đã làm nó cho bạn. Định dạng đã kết thúc khác nhau, như tôi đã sao chép ngu ngốc từ văn bản được hiển thị thay vì văn bản chỉnh sửa. –

+0

Xong. Xin lỗi về điều đó – Tim

1

Vì vậy, hãy xem xét vấn đề của bạn khi nói toán. Đây là tất cả giả sử tôi hiểu hoàn toàn về vấn đề của bạn . Vui lòng sửa tôi nếu tôi nhầm.

chúng tôi muốn giảm thiểu sau đây:

\ sqrt ((a-a_desired)^2 + (b-b_desired)^2 + (c-c_desired)^2)

hoặc trong ký hiệu khác || Pos (x - x_desired) || _2

trong đó x = (a, b, c) và Pos (y) = max (y, 0) có nghĩa là chúng tôi muốn "phần dương" (tài khoản này cho các câu lệnh if của bạn). Cuối cùng, chúng tôi muốn hạn chế chính mình đến các giải pháp trong đó x là số nguyên có giá trị.

Không giống như các áp phích trên, tôi không nghĩ rằng thuật toán di truyền là những gì bạn muốn.
Thực tế, tôi nghĩ giải pháp dễ dàng hơn nhiều (giả sử tôi hiểu vấn đề của bạn).

1) Chạy bất kỳ thường trình tối ưu hóa nào trên hàm ở trên. Điều này sẽ cung cấp cho bạn giải pháp x^* = (a^*, b^*, c^*). Khi hàm này tăng lên với các tham số cho các biến, giải pháp số nguyên tốt nhất bạn có thể hy vọng là (ceil (a^*), ceil (b^*), ceil (c^*)).

Bây giờ bạn nói rằng chức năng của bạn có thể khó đánh giá. Có tồn tại các công cụ cho điều này không dựa trên chẩn đoán. Việc đi theo tên Derivative-Free Tối ưu hóa. Mọi người sử dụng những công cụ này để tối ưu hóa mục tiêu dựa trên mô phỏng (tôi có thậm chí còn nghe về một trường hợp mà chức năng mục tiêu dựa trên sản lượng thu hoạch cây trồng!)

Mỗi phương pháp này có các tính chất khác nhau, nhưng nói chung họ cố gắng giảm thiểu không chỉ mục tiêu mà còn là số lượng đánh giá chức năng khách quan.

+0

+1 cho tối ưu hóa không có nguồn gốc, nhưng phép toán lại có thể sử dụng đề cập rõ ràng rằng "x" là hàm và có thể đổi tên "x" để nó không va chạm với các biến nguồn được đăng. – outis

+0

x không phải là hàm, chỉ là tập hợp các biến a, b, c thành một vectơ đơn. – SplittingField

+1

Tim không muốn giảm thiểu 'Err_A (x) = || Pos (x - A) || ₂', mà đúng hơn là' Err_A (Dev (u)) ', trong đó' Dev (u): Z² -> R³ '. Nếu soln. nằm trong 'x', nó không cần phải là số nguyên. Hơn nữa, 'ceil · x'' có thể không phải là một soln hợp lệ. trong 'x', vì có thể không có' u'' sao cho 'ceil · x '= Dev (u')'. Đối với các phần mở rộng của 'Dev' cho một số' Dev '(u): R² -> R³' Tôi có thể tưởng tượng (terraces, meshes), solns. trong 'u' sẽ có giá trị số nguyên. Nếu một 'Dev '(u)' kỳ lạ có giá trị tối thiểu tại 'u'∉Z²', các phần tử của' {ceil, floor} ² · u'' có thể không phải là giải pháp. – outis