遊星歯車条件が成立する歯数の算出方法(2)

前回は、手計算で遊星歯車の成立歯数を求めました。それを計算で求めようというのが、今回のねらいです。
その内容ですが、前回の理論を全く無視した「総当たり」のものを今回に、前回理論に沿ったものを次回に準備しました。

総当たり計算例(VBA版)

次のVBAプログラムを見てください。素のVBAなので、ワークシート等でインターフェース作った方がよいでしょう。
プログラムは、ピニオン個数を指定しておいて、ピニオン歯数とリングギヤ歯数をそれぞれの上下限で2重ループさせます。
ループ中に「同軸条件」「等配条件」「隣接干渉条件」のif文があり、すべてを満足した組み合わせのみを出力する簡単な内容です。
ねらいの歯数の上下限幅は、あまり大きくないと思いますから、総当たりでも大して時間はかからないので、これで充分かも知れません。
変数が歯数そのものなのもわかりやすい点です。

Option Explicit

Sub main()
    ' 変数宣言
    Dim PI As Double
    PI = WorksheetFunction.PI()
    Dim zpmin%, zpmax%
    Dim zrmin%, zrmax%
    Dim zsmin%
    Dim N%
    Dim zp%, zr%, zs%
    
    ' 変数代入
    zpmin = 15      'ピニオン歯数下限値
    zpmax = 15      'ピニオン歯数上限値
    zsmin = 20      'サンギヤ歯数下限値
    zrmin = 60      'リングギヤ歯数下限値
    zrmax = 160      'リングギヤ歯数上限値
    N = 20           'ピニオン個数
    
    
    'ピニオン歯数のループ
    For zp = zpmin To zpmax
        ' リングギヤ歯数のループ
        For zr = zrmin To zrmax

            ' 同軸条件
            zs = zr - 2 * zp

            ' if分1行目隣接干渉条件,3行目等配条件
            If (zp + 2) < (zs + zp) * Sin(PI / N) _
            And zs > zsmin _
            And (zr + zs) Mod N = 0 Then
            
              Debug.Print zr, zs, zp, N

            End If
                
        Next zr
    Next zp

End Sub

ピニオン個数20、ピニオン歯数15での計算出力例です。
左からリングギヤ歯数、サンギヤ歯数、ピニオン歯数15、ピニオン個数20を示していますが、当然、前回と同じ結果です。

 125           95            15            20 
 135           105           15            20 
 145           115           15            20 
 155           125           15            20 

総当たり計算例(Python版)

実は、総当たり計算プログラムを最初に作ってくれたのは、Being chatというかMicrosoft Copilotです。Copilotに「1次不定方程式の整数解を、指定の範囲ですべて羅列するようなプログラムを書けますか」と聞いたところ、提示してきたのが次のプログラムです。てっきり、「ユークリッドの互除法」を使ってくると思っていたのですが、「総当たり」で意表を突かれました。この考え方もいいか、と思って作ったのが、冒頭のVBA版です。

Microsoft Copilot

プログラム

こちらのプログラムは、前回の通り、等配条件と同軸条件を辺々引き算した結果の式aX+bZr=cの解を求めています。

def solve_diophantine(a, b, c, x_min, x_max, y_min, y_max):
    solutions = []
    for x in range(x_min, x_max + 1):
        for y in range(y_min, y_max + 1):
            if a * x + b * y == c:
                solutions.append((x, y))
    return solutions
solutions = solve_diophantine(-10, 1, 15, 0, 100, 0, 200)
計算結果

n=20,Zp=15という条件で、リングギヤ歯数上限200として成立するXとZrのペアが、すべて出力されました。VBA版と違って、隣接条件や、下限歯数は条件に入っていません。
この結果から、ピニオン歯数Zpと計算されたリングギヤ歯数Zrから、サンギヤ歯数ZsをZr-2Zpとして求めます。

[(0, 15), (1, 25), (2, 35), (3, 45), (4, 55), (5, 65), (6, 75), (7, 85), (8, 95), (9, 105), (10, 115), (11, 125), (12, 135), (13, 145), (14, 155), (15, 165), (16, 175), (17, 185), (18, 195)]
print(solutions)
Copilotとのやり取り内容

Copilotとは次のような会話をしました。
「1次不定方程式の整数解を、指定の範囲ですべて羅列するようなプログラムを書けますか」
「はい、一次不定方程式の整数解を、指定の範囲ですべて羅列するプログラムを書くことができます。以下はPythonでの例です:
この関数は、一次不定方程式 ax + by = c の整数解を、指定された範囲内で全て求めます。a、b、c は整数で、x_min、x_max、y_min、y_max はそれぞれ x と y の範囲を指定します。この関数は、整数解のリストを返します。

例えば、2x + 3y = 7 の整数解を、0 <= x <= 5、0 <= y <= 5 の範囲で求めるには、以下のように呼び出します

solutions = solve_diophantine(2, 3, 7, 0, 5, 0, 5)
print(solutions)

この場合、出力は [(2, 1)] となります。つまり、x = 2、y = 1 のときに 2x + 3y = 7 が成り立ちます。

この関数は、指定された範囲が大きい場合には計算時間がかかることがあるため、注意してください。また、この関数は一次不定方程式の整数解を全て求めるため、解が存在しない場合には空のリストを返します。」

次回は「ユークリッドの互除法」を使用したパターンです。