5

Thứ nhất: Tại sao?

Phương pháp Monte Carlo là tuyệt vời cho các vấn đề đủ phức tạp mà một giải pháp chính xác là không thể và không thể chính xác hoàn hảo 100%. Loại vấn đề nào? Vâng, điều tôi sẽ giải quyết trong bài viết này là tìm khu vực dưới một đường cong (Tích hợp AKA cho tính toán nghiêng).

Nhưng nó là gì?

Các phương pháp của Monte Carlo là khi bạn chạy NHIỀU mô phỏng ngẫu nhiên, và sử dụng các kết quả để tính toán một giải pháp chính xác hợp lý. Trong trường hợp ví dụ tích hợp của chúng tôi, chúng tôi sẽ tạo ngẫu nhiên hàng ngàn điểm, tính tỷ lệ phần trăm xảy ra dưới đường cong được đề cập, sau đó sử dụng kiến ​​thức đó để tính diện tích.

Ma thuật đen!

INORITE? Nhưng nghiêm túc. Đây là một trợ giúp trực quan cho những gì tôi sẽ làm: 

(từ bài viết trên wikipedia  tại đây )

Tôi sẽ chọn một loạt các điểm ngẫu nhiên dọc theo trục x và tìm nơi hàm nói giá trị y tối đa và tối thiểu của tôi sẽ ở đó. Khi tôi có được điều này, chức năng của tôi sẽ chia khu vực hình chữ nhật này thành hai phần. Đây là nơi phép màu xảy ra. Chúng tôi biết làm thế nào để tính diện tích của  bất kỳ  hình chữ nhật. Bằng cách kiểm tra ngẫu nhiên các khu vực trong hình chữ nhật và theo dõi tỷ lệ các thử nghiệm của chúng tôi nằm dưới đường cong, chúng tôi sẽ kết thúc với tỷ lệ phần trăm. Tỷ lệ phần trăm đó sẽ đại diện cho phần trăm của khu vực hình chữ nhật nằm dưới đường cong của chức năng của chúng tôi.

Nó có vẻ đơn giản cho đến khi tôi gõ nó ra

Mật mã

Hãy bắt đầu với mức cao nhất trong mã của tôi để cung cấp cho bạn bản tóm tắt về tất cả những gì tôi đang làm.

var integrate = function(fn, left_x, right_x, sample_count){
	var random_x_points = generate_x_values(left_x, right_x, sample_count);
	var y_bounds = compute_y_bounds(fn, random_x_points);
	var random_points = create_random_points(random_x_points, y_bounds);
	var points_under_curve = count_points_under_curve(fn, random_points)

	var percent_under_curve = points_under_curve / (1.0*random_points.length);
	var rectangle_area = (y_bounds.upper_bound-y_bounds.lower_bound)*(right_x-left_x)
	var area_under_curve = percent_under_curve * rectangle_area;

	return area_under_curve;
};

Trước hết hãy nhìn vào các tham số. Hàm tích hợp lấy một hàm 'fn' để đánh giá, một ranh giới x trái và phải cho tích phân xác định của chúng ta và một số mẫu. Số lượng mẫu là một số lạ. Bạn có nhớ hình ảnh ở trên nơi chúng tôi ngẫu nhiên bắn hàng ngàn điểm vào biểu đồ của chúng tôi không? Đó là cái này. Đây là số điểm ngẫu nhiên chúng tôi sẽ lấy mẫu trên khu vực nhất định mà chúng tôi quan tâm để tính toán khu vực.

Trong thực tế, một điểm thú vị là vài dòng đầu tiên của hàm. Đầu tiên tôi tạo ra một loạt các giá trị x ngẫu nhiên, sau đó tôi kết hợp các giá trị đó và tìm ra ranh giới y là gì. Bằng cách này tôi có thể tạo một hình chữ nhật bao gồm diện tích càng nhỏ càng tốt.

Khi tôi đã nhận được điểm x của mình và phát hiện ra giới hạn của mình, tôi có đủ thông tin để tạo tất cả các điểm ngẫu nhiên của mình. Khi xong, tôi lấy tất cả các điểm ngẫu nhiên của mình và so sánh chúng với hàm thực tế và xem có bao nhiêu điểm ngẫu nhiên của tôi nằm dưới đường cong của hàm.

Phần còn lại của chức năng là khá thẳng về phía trước một khi bạn hình dung nó. Về cơ bản, tôi đã phân định một khu vực hình chữ nhật có chứa hàm và tất cả các điểm mẫu của tôi. Chúng tôi có ranh giới trái và phải của chúng tôi (được đưa ra bởi left_x và right_x) và giới hạn trên và dưới (được đưa ra bởi y_bound.upper_bound và y_bound.lower_bound).

Bạn có thể xem toàn bộ ví dụ của tôi và mã ở đây:  Bấm vào đây để dùng thử

Trong mẫu tôi đã mã hóa cứng chức năng trở thành một thứ có vẻ thách thức: sin (log (x) ^ 2). Đây là cách tôi gọi nó:

var fn = function(x){
	return Math.sin(Math.pow(Math.log(x),2));
};
var result = integrate(fn, 0, 2, 10000);

Nhưng một gotcha

Có một gotcha cụ thể và đó là khi đường cong xuống dưới trục x. Trong Giải tích, bạn có thể nhớ phải kiểm tra điều này và sửa vùng âm thành dương (tùy thuộc vào ứng dụng kỹ thuật của bạn). Phương pháp này không có vấn đề đó. Thay vào đó, theo mặc định, bạn có thể kết thúc bằng mã đang kiểm tra khu vực bên dưới đường cong xuống đến ranh giới y thấp hơn.

Trong hàm Count_point_under_curve, ở đây, bạn có thể thấy nơi tôi đang kiểm tra fn_value để được ở trên hoặc dưới 0 trước khi quyết định định nghĩa nào về đường dưới đường cong Tôi quyết định kiểm tra.

var count_points_under_curve = function(fn, random_points){
	var points_under_curve = 0;
	for(var i in random_points){
		var random_point = random_points[i];
		var fn_value = fn(random_point.x);
		if(fn_value >= 0){
			if(random_point.y < fn_value){
				points_under_curve += 1;
			}
		} else {
			if(random_point.y > fn_value){
				points_under_curve += 1;
			}
		}
	}
	return points_under_curve;
};

Lần tới

Đây là một cách để sử dụng phương pháp Monte Carlo. Tôi có một bài viết khác tôi đang làm việc về nơi tôi sẽ sử dụng các phương pháp Monte Carlo để khám phá thử nghiệm phân tách và hy vọng xác minh một số lý thuyết. Trước đây tôi cũng đã từng sử dụng nó để kiểm tra một mô hình phát triển phần mềm đơn giản hóa.

Nếu bạn từng nghĩ, thì tôi hoàn toàn có thể tìm thấy câu trả lời nếu tôi có thể viết mã cho hàng triệu ví dụ khác nhau và xem kết quả. Có lẽ bạn đã tìm thấy một lý do tuyệt vời để sử dụng công cụ này.

|