VB2010での連立方程式の計算

このQ&Aのポイント
  • VB2010でガウスの消去法を使った連立方程式の計算を行いたいが、解が求まらない場合について質問
  • 質問者はVB初心者であり、未知数が8つの連立方程式を解くためにガウスの消去法を使いたい
  • 現在のプログラムでは、解が求まらずNAN(非数値)となる状況が発生しており、pに0が入ってしまっていることが原因と考えているが、回避する方法を知りたい
回答を見る
  • ベストアンサー

VB2010での連立方程式の計算

VB2010でガウスの消去法のプログラムを作りたいんですが、うまく解が求まらないのでメールしました。今回の例は未知数8です。ちなみにVBは初心者です。 Myarrayは、列の1-8個目までが、各未知数の係数、9個目が整数を表しています。 行は式を表していて、未知数が8個あるので8行あります。 Dim MyArray(,) As Double = {{-1, 1, -1, 1, 0, 0, 0, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 0, -1}, {0, 0, 0, 0, 0, 0, 0, 1, -1}, {0, 0, 0, 0, 1, 1, 1, 1, 0}, {0, 0, 1, 0, 0, 0, -1, 0, 0}, {0, 2, 0, 0, 0, -2, 0, 0, 0}, {-6, 2, 0, 0, 0, 0, 0, 0, 0}, {6, 2, 0, 0, 0, 0, 0, 0, 0} } Const N = 8 Dim i, j, k, l, pivot As Integer Dim x(N) As Double Dim p, q, m As Double Dim b(1, N + 1) As Double For i = 0 To N - 1 Step 1 m = 0 pivot = i For l = i To N - 1 Step 1 'i列の中で一番値が大きい列を選ぶ If System.Math.Abs(MyArray(l, i)) > m Then m = System.Math.Abs(MyArray(l, i)) pivot = l End If Next 'pivotがiと違えば、行の入れ替え If pivot <> i Then For j = 0 To 8 Step 1 b(0, j) = MyArray(i, j) MyArray(i, j) = MyArray(pivot, j) Myarray(pivot, j) = b(0, j) Next End If Next For k = 0 To N - 1 Step 1 p = Myarray(k, k) '対格要素を保存 MsgBox(p) MyArray(k, k) = 1 '対格要素は1になることが分かっているので代入 For j = k + 1 To N Step 1 MyArray(k, j) = MyArray(k, j) / p Next For i = k + 1 To N - 1 Step 1 q = MyArray(i, k) For j = k + 1 To N Step 1 MyArray(i, j) = MyArray(i, j) - q * MyArray(k, j) Next '0となることが分かってるので代入 MyArray(i, k) = 0 Next Next '解の計算 For i = N - 1 To 0 Step -1 x(i) = MyArray(i, N) For j = N - 1 To i + 1 Step -1 x(i) = x(i) - MyArray(i, j) * x(j) Next Next MsgBox(x(0)) MsgBox(x(1)) MsgBox(x(2)) MsgBox(x(3)) MsgBox(x(4)) MsgBox(x(5)) MsgBox(x(6)) MsgBox(x(7)) 出力結果としてNAN(非数値)と出てきてしまいます。原因は、pに0が入ってしまっていることがあるからだと思いますが、これを回避する方法はないでしょうか?ご教授よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.1

エラーの原因は行の入れ替えを最初の1回しかしていないからです。 行の入れ替えは、各行の計算ごとに行う必要があります。 For i = 0 To N - 1 Step 1   m = 0   pivot = i   ・・・・・   ・・・・・ Next For k = 0 To N - 1 Step 1   p = Myarray(k, k) '対格要素を保存   ・・・・・   ・・・・・ Next この部分を、 For k = 0 To N - 1 Step 1   m = 0   pivot = k   ・・・・・   ・・・・・   p = Myarray(k, k) '対格要素を保存   ・・・・・   ・・・・・ Next とすれば大丈夫でしょう。 初めのFor文のインデックスをiからkに変えているので注意してください。

jastaway0124
質問者

補足

解答ありがとうございます。修正プログラムfor分の終わりのNEXTが元のプログラムの2つ目のfor分の終わりのNEXTの場所でよいでしょうか? 色々やってみましたが if pivot <> i thenの中の b(0,j) = MyArray(i,j) の所でインデックスが配列の境界外です、ってエラーが出てしまいますね。解答の意味を勘違いしてたら申し訳ないです><

その他の回答 (1)

  • nag0720
  • ベストアンサー率58% (1093/1860)
回答No.2

>修正プログラムfor分の終わりのNEXTが元のプログラムの2つ目のfor分の終わりのNEXTの場所でよいでしょうか? それでいいです。要するに2つのFor文を1つにまとめただけです。 >色々やってみましたが if pivot <> i thenの中の >b(0,j) = MyArray(i,j) >の所でインデックスが配列の境界外です、ってエラーが出てしまいますね。 For文の変数iをkに変えたので、1つめのFor文の中のiをすべてkに変えてください。

jastaway0124
質問者

お礼

よく考えたらそうですよね。不注意失礼しました>< 無事に動きました。本当にありがとうございました!

関連するQ&A

  • 1+(1+2)+(1+2+3)....+(1+2+...+N)の計算式をVBで・・

    表すにはどうしたらいいでしょうか。 もう3時間くらい格闘しているのですが、 答えを出せません。 Dim S AS LONG DIm N As Integer Dim i As Integer N = Val(TextBox1.Text) S = 0 i = 1 For i = 1 To N Step 1 S = S + i Next Label4.Text = Format(S, "#,##0") で、1+2+3+...+Nはいけるのですが、 上記の式は、Nが1づつ増えていくにしたがって、 Sの値が1 4 10 20 ...となっていくために、…。 どなたか、回答していただける方がおりましたら、 非常に助かります。 よろしくお願いいたします。。

  • VB2008: リストメンバーの列数の求め方?

    Sub Main()   Dim I As Integer   Dim J As Integer   Dim K As Integer   Dim aDatas As New List(Of String())()   Dim N = CSVReadToArray("D:\Temp\付属一覧.csv", aDatas) - 1   K = aDatas(0).Count - 1   For I = 0 To N     For J = 0 To K       Debug.Print(aDatas(I)(J))     Next J   Next I End Sub 質問1、K = aDatas(0).Count - 1 の本当のやり方? 質問2、K の処理のされ方。 K が変数としてメモリに配置されることはないと推察しています。 多分、何がしかのスタック領域に一時的に置かれると・・・。 この辺りに関しても教えてもらえれば幸いです。

  • VB6→VS2005アップグレード後

    いつもお世話になっております。 VBを勉強中です。 VB6→2005にアップグレード後、下記のエラーが発生しました。 "オブジェクト参照がオブジェクト インスタンスに設定されていません。" 以前もこちらでアドバイスをいただき、 デザインの中でADDされているかどうかを確認し、解決に結びついたので 今回も同様かと思い、色々と行ったのですが解決しません。 frmapli_S3のデザイナ内に下記が存在しましたが 原因はここでしょうか? CType(Me.Frame1, System.ComponentModel.ISupportInitialize).EndInit() 以下はVB6での正常稼動時のソースです。 Public Sub ShowPermValue() Dim Textbox As Textbox Dim i As Long: Dim j As Long: Dim k As Long For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Set Textbox = frmapli_S3.Controls("text" & k) Textbox.Text = PermValue(k) Next Next End Sub Public Sub SetPermValue() Dim Textbox As Textbox Dim i As Long: Dim j As Long: Dim k As Long For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Set Textbox = frmapli_S3.Controls("text" & k) PermValue(k) = Textbox.Text Next Next 下記はVB2005アップグレード時のソースです。 Public Sub ShowPermValue() Dim Textbox As TextBox Dim i, j, k As Integer For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Textbox = CType(frmapli_S3.Controls("text" & k), TextBox) TextBox.Text = PermValue(k) Next Next End Sub Public Sub SetPermValue() Dim Textbox As TextBox Dim i, j, k As Integer For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Textbox = CType(frmapli_S3.Controls("text" & k), TextBox) PermValue(k) = Textbox.Text   ←ここでエラー Next Next End Sub

  • 目盛表示ができない(vb2010)

    下記のグラフのように、Y軸に目盛表示をしたいのですが、うまくできません。 PictureBoxにLineは表示できるのですが、目盛が表示できません。 どなたかお教え願います。 下記のコードでは、目盛表示ができないのでしょうか。    '目盛表示 Dim J As Integer, CurrentY As Integer, CurrentX As Integer Dim strB As String J = 0 For I = 0 To 200 Step 40 CurrentX = 120 CurrentY = 100 + I strB = CStr(0.2 - (2 / 5) * J * 0.1) J = J + 1 Next J = 0 For I = 0 To 200 Step 40 CurrentX = 120 CurrentY = 300 + I strB = CStr(0 - (2 / 5) * J * 0.1) J = J + 1 Next

  • エクセルVBA カウンタ2つを入れ子にしたくない時

    皆さんこんにちは。 エクセル2013を使用しております。 エクセルVBAの繰り返し処理について質問させていただきます。 下記のコードですと入れ子があるので A1にi、A3にi・・・・を一通り記載したあと またA1にi+2、A3にi+2・・・を繰り返し 最終的にA列には全て同じ値が入ってしまいます。 (Step 2にしたのはA1:A2のように2行毎の結合セルだからです) -----------------------------------------------------------------    Dim i As Long Dim j As long Dim n As long Dim k As long     i =Userform.textbox1.value     j =Userform.textbox2.value    For k =i To j Step 2 For n = 1 to j Step 2 Range("A" & n) = k    Range(”B”&n)=k+1        Next    Next ---------------------------------------------------------- もしiが1、jが10だとしたら A1に1、B1に2、A3に3、B3に4、・・・A9に9、B9に10 が入るようにするにはどうしたら良いでしょうか。 iが必ず1から始まるのであればまだ分かるのですが そうとも限らないので カウンタはやはり2つ必要だと思うのですが カウンタが2つあるのに入れ子にしないコードの書き方って あるのでしょうか。 いくら本やネットを見ても分かりません。 ご教授いただけると幸いです。

  • VB2005 図形

    VisualBasic2005で Dim n As Integer, m As Integer Dim i As Integer, j As Integer Const lenn = 1500, PAI = 3.14159 Dim th As Single, th1 As Single, th2 As Single Dim x1 As Integer, x2 As Integer Dim y1 As Integer, y2 As Integer n = Val(TextBox1.Text) m = Val(TextBox2.Text) If n < 2 Or m < 2 Then   Exit Sub End If For i = 0 To n - 1   For j = 1 To n - 1     th = j * (PAI / n)     th1 = i * (PAI / m) + th     th2 = i * (PAI / n) - th     x1 = Math.Cos(th1) * lenn + 2000     y1 = Math.Sin(th1) * lenn + 2000      x2 = Math.Cos(th2) * lenn + 2000      y2 = Math.Sin(th2) * lenn + 2000   Next Next の様なコードを使って 球をPictureBoxに書きたいのですが どこにどんなコードが足りないのでしょうか? 教えて下さい

  • 以前に回答いただいたVBAですが、理解できない部分があったので、抜粋し

    以前に回答いただいたVBAですが、理解できない部分があったので、抜粋して質問に投稿したところ、多くの方々から、「これでは、わからない」などの指摘をいただき、これでは、以前に回答していただいた回答者様の名誉にかかわると思い全文を記載させていただくことにしました。  あわせて、この、VBAの詳しい説明を快くしていただける方は回答よろしくお願いします。以下のとうりです。  A列  B列 1 期間  90 2 人数  21 3 4 氏名  回数 5 A   23 6 B   23 7 C   19 8 D   16 9 E   12 10 F   9 11 G   8 12 H   7 13 I   7 14 J   6 15 K   6 16 L   6 17 M   5 18 N   5 19 O   4 20 P   4 21 Q   4 22 R   4 23 S   4 24 T   4 25 U   4 Sub 当番割当() Dim 期間 As Integer Dim 人数 As Integer Dim 氏名() As String Dim 回数() As Integer Dim i As Integer Dim j As Integer Dim k As Integer Dim m As Integer Dim n As Integer Dim n1 As Integer Dim n2 As Integer Dim p As Single Dim q As Single Dim 当番() As String Dim 担当() As Single 期間 = Cells(1, 2) 人数 = Cells(2, 2) ReDim 氏名(人数) ReDim 回数(人数) For i = 1 To 人数 氏名(i) = Cells(4 + i, 1) 回数(i) = Cells(4 + i, 2) Next i ReDim 当番(期間 * 2) ReDim 担当(期間 * 2) n = 0 For i = 1 To 人数 n1 = 0 n2 = 0 For j = 1 To 人数 If 回数(j) = 回数(i) Then n1 = n1 + 1 If j <= i Then n2 = n2 + 1 End If Next j p = 期間 / 回数(i) For j = 1 To 回数(i) q = p * (n2 - 0.5) / n1 + p * (j - 1) m = 1 For k = n To 1 Step -1 If 担当(k) <= q Then m = k + 1 Exit For End If 当番(k + 1) = 当番(k) 担当(k + 1) = 担当(k) Next k 当番(m) = 氏名(i) 担当(m) = q n = n + 1 Next j Next i Range("E:G").Clear For n = 1 To 期間 Cells(n, 5) = n & "日" Cells(n, 6) = 当番(n * 2 - 1) Cells(n, 7) = 当番(n * 2) Next n End Sub

  • プログラミングVBです

    対数のeの値を出すプログラムをつくりたいのですが Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim m, n, s, k As Double k = 1 s = 1 For n = 1 To 1000 Step 1 For m = 1 To n Step 1 s = s * m Next k = k + 1 / s Next TextBox1.Text = Format(k, "#.################") End Sub 自力でつくったこれだと微妙に値が変わってしまいます どこが違いますか? おしえてください

  • エクセルで表を展開するマクロを作りたい

    こんにちは。 エクセルで表を展開したいのですがマクロが作れません。 どなたか詳しい方教えて下さい。     A   B   C  D 1  1,2,3  abc  def  ghi を    A   B   C  D 1  1 abc  def  ghi 2   2  abc  def  ghi 3  3  abc  def  ghi というように展開したいです。 10列目くらいまで対応したマクロが作りたいです。 Sub test() 'この行から Dim i, j, k As Long Dim myArray As Variant For i = Cells(Rows.Count, 1).End(xlUp).Row To 2 Step -1 If Not Cells(i, 1) Like "*" & "," & "*" Then i = i - 1 myArray = Split(Cells(i, 1), ",") k = UBound(myArray) Rows(i + 1 & ":" & i + k).Insert For j = 0 To k Cells(i + j, 1) = myArray(j) Next j Next i For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, 2) = "" Then Cells(i, 2) = Cells(i - 1, 2) End If Next i Columns("A:B").AutoFit End Sub 'この行まで これにどう付け足せばいいでしょうか? どうかご教授お願い致します。

  • 文字制限方法。

    どなたか知識ある方、教えてください。 ソートプログラムの演習をしているんですが、 どのように書いていいか悩んでます。現在の課題はtextが10個あり、sortボタンをクリックすると左から数字を小さい順に並びます、数字のみ入力可、空白でもエラーなしで(全て空白はエラー)とりあえず数字があれば10個埋めていなくても並べる、文字等はエラーを出したいです。 '配列のインデックス番号の開始に1を設定 Option Base 1 Option Explicit Private Sub cmdCLEAR_Click() '変数の宣言 Dim ans As Integer Dim i As Integer '消去する際の確認事項 ans = MsgBox("消去していいですか?", vbYesNo + vbQuestion) Select Case ans Case vbYes For i = 1 To 10 Step 1 Text(i).Text = "" Next i Case vbNo MsgBox "取り消します", vbInformation End Select End Sub Private Sub cmdSORT_Click() '変数の宣言 Dim intNum(10) As Integer Dim S As Integer Dim j As Integer Dim k As Integer Dim i As Integer '配列の整理 For i = 1 To 10 Step 1 intNum(i) = Int(Text(i).Text) Next i 'バブルソート For k = 1 To 9 Step 1 For j = 1 To 9 Step 1 If intNum(j) > intNum(j + 1) Then S = intNum(j) intNum(j) = intNum(j + 1) intNum(j + 1) = S End If Next j Next k '結果を返して表記する For i = 1 To 10 Step 1 Text(i).Text = intNum(i) Next i End Sub 現在書いたのはここまででどうしてもエラーと文字制限の方法はわからないので教えていただける方、宜しくお願いします。