Tính diện tích phần dương và phần âm của đồ thị (1 người xem)

  • Thread starter Thread starter pdle
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

pdle

Thành viên mới
Tham gia
4/1/11
Bài viết
3
Được thích
0
Em có một vấn đề như sau: Cho một bộ điểm XY - 23 điểm. Các giá trị của X và Y được nhập tương ứng vào 2 cột như trong hình minh hoạ. Sau đó đồ thị được tạo từ 23 điểm này, với giá trị ở trục tung là Y và trục hoành là X.
Excel-1.jpg

Bài toán đặt ra ở đây là:
Tính diện tích phần dương (nằm trên trục X) và diện tích phần âm (nằm dưới trục X).

Để giải quyết bài toán này (vì em có khá nhiều đồ thị nên muốn tạo một macro để thao tác cho nhanh, hơn nữa sau này cũng còn nhiều bài toán dạng này nữa), em đề xuất thuật toán với VBA như sau:


1) Nhập dữ liệu của cột X vào mảng X, và cột Y vào mảng Y. Vì khai báo dữ liệu mảng trong VBA cần phải xác định kích cỡ ma trận trước, nên trong module của macro ta sẽ khai báo một mảng với kích cỡ đủ lớn để thao tác.

2) Tiếp theo, ta cho biến chạy i từ 1 đến 23 (23 điểm) và xác định các vị trí đổi dấu bằng cách xét Y*Y[i+1]<0 hay không. Nếu trường hợp này xảy ra, có nghĩa là đồ thị đổi dấu, khi đó ta sẽ tính tọa độ đồ thị cắt trục X. Ta sẽ gán giá trị này cho X[24], còn Y[24]=0, cho điểm cắt đầu tiên. Sau đó, gán các giá trị tiếp theo cho lần lượt X[25], X[26], ...
Ghi nhớ biến DimMatrix cho số giá trị trong các mảng (DimMatrix = 23 + số điểm đồ thị cắt trục X)

3) Sắp xếp theo thứ tự từ bé đến lớn cho mảng X , còn mảng Y được sắp xếp phụ thuộc mảng X.

4) Đặt 2 biến NegativeAreaPositiveArea cho phần diện tích trên và dưới trục X của đồ thị. Sau đó ta thiết lập một vòng lặp từ i=1 đến DimMatrix. Xét Y và Y[i+1]:
Nếu Y>=0 and Y[i+1]>=0, PositiveArea=PositiveArea + 0.5*(Y+Y[i+1])*(X[i+1]-X)
Nếu Y<=0 and Y[i+1]<=0, NegativeArea=NegativeArea + 0.5*(-Y-Y[i+1])*(X[i+1]-X)

5) Xuất giá trị của NegativeAreaPositiveArea.



Xin mọi người cho ý kiến. Đây la lần đầu tiên em dùng VBA cho excel :) Em cảm ơn nhiều!
 
Em đã viết một macro cho bài toán này như sau:
PHP:
Public Sub GraphArea()
Dim XY(1 To 50, 1 To 2) As Double
Dim NegativeArea, PositiveAre As Double
Dim i, j As Integer
    i = 1
    j = 1
    For Each row In Selection.Rows    ' Nhập giá trị từ vùng chọn vào mảng với XY(i,1)=X ; XY(i,2)=Y
        For Each cell In row.Cells
            XY(i, j) = cell.Value
            j = j + 1
        Next cell
        j = 1
        i = i + 1
    Next row                           ' Kết thúc phần nhập giá trị
    DimMatrix = 23                    ' Tìm các điểm giao cắt của đồ thị với trục hoành
    j = 0
    For i = 1 To DimMatrix - 1 Step 1
        If XY(i, 2) * XY(i + 1, 2) < 0 Then
            j = j + 1
            XY(DimMatrix + j, 1) = XY(i, 1) + Abs(XY(i, 2)) / (Abs(XY(i, 2)) + Abs(XY(i + 1, 2))) * (XY(i + 1, 1) - XY(i, 1))
            XY(DimMatrix + j, 2) = 0
        End If
    Next i
    DimMatrix = DimMatrix + j          ' Kết thúc phần tìm điểm giao cắt với trục hoành
    For i = 1 To DimMatrix - 1         ' Sắp xếp XY theo thứ tự tăng dần của XY(i,1) (tức là X)
    For j = i + 1 To DimMatrix
        If XY(i, 1) > XY(j, 1) Then
            gt1 = XY(i, 1)
            XY(i, 1) = XY(j, 1)
            XY(j, 1) = gt1
            gt2 = XY(i, 2)
            XY(i, 2) = XY(j, 2)
            XY(j, 2) = gt2
        End If
    Next j
    Next i
    NegativeArea = 0                 ' Tính diện tích phần âm và dương của đồ thị
    PositiveArea = 0
    For i = 1 To DimMatrix - 1 Step 1
        If XY(i, 2) >= 0 And XY(i + 1, 2) >= 0 Then
            PositiveArea = PositiveArea + 0.5 * (XY(i, 2) + XY(i + 1, 2)) * (XY(i + 1, 1) - XY(i, 1))
        End If
        If XY(i, 2) <= 0 And XY(i + 1, 2) <= 0 Then
            NegativeArea = NegativeArea + 0.5 * (XY(i, 2) + XY(i + 1, 2)) * (XY(i + 1, 1) - XY(i, 1))
        End If
    Next i
    Selection.Cells(24, 1).Value = "PA"                             ' Xuất dữ liệu ra excel
    Selection.Cells(24, 2).Value = PositiveArea
    Selection.Cells(25, 1).Value = "NA"
    Selection.Cells(25, 2).Value = NegativeArea
   
End Sub

Kết quả (cho đồ thị trong ảnh):
NegativeArea = -8.106471306
PositiveArea= 0.798200706

Để đánh giá độ chính xác của kế quả, em đã dùng chương trình Graph (version 4.3, by Ivan Johansen) để kiểm tra. Nhập bộ điểm đã cho vào Graph, sau đó dùng công cụ Insert trendline, nội suy đừng gấp khúc đó thành một đa thức 22 bậc (bộ điểm đã cho là 23 điểm). Sau đó sử dụng công cụ calculate của Graph để tính diện tích phần dương là phần âm ta được:
NegativeArea=-8.1281
PositiveArea=0.8358
So sánh với kết quả nhận được bằng macro, có thể nhận thấy lời giải trên là chấp nhận được (chú ý là đường cong để tính diện tích trong Graph không trùng khíp với đồ thị trong excel, vì đường cong trong Graph là đường cong của đa thức nội suy bậc 22 qua 23 điểm đã cho)
2011-05-08_142950.jpg
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom