一次不定方程式 ax + by = c の係数を入力してください。下の数式は入力欄と連動していて、数字の部分を直接書き換えても計算できます。「求める解の範囲」を変えると、正の整数解だけを絞り込むこともできます。
このページでできること
- 整数の係数 \(a,\ b,\ c\) を入れるだけで、\(ax + by = c\) を満たす整数の組 \(x,\ y\)(整数解)を求められます
- \(c\) が \(a\) と \(b\) の最大公約数の倍数でないときは整数解が存在しません。その判定と、なぜ存在しないのかの理由も表示します
- ユークリッドの互除法の割り算の表と、余りを逆にたどって特殊解を作る表を、1行ずつそのまま見られます
- 答えは1組だけでなく、\(x = x_0 + \dfrac{b}{g}t,\ y = y_0 - \dfrac{a}{g}t\)(\(t\) は整数)の一般解と、\(t\) を動かした整数解の一覧表で表示します
- 「正の整数解だけ」「0 以上の整数解だけ」に絞り込めます。50円切手と80円切手で1000円ちょうどにする組み合わせを求める、といった問題がそのまま解けます
この計算は何の役に立つ?
50円切手と80円切手だけで1000円ちょうどにする、2種類の分銅だけである重さを量る、決まった長さの材料だけでちょうどの長さをつくる。こうした「決まった大きさのものを組み合わせて、目標にぴったり合わせる」問題は、そのまま \(ax + by = c\) の整数解を求める問題になります。
枚数や個数はマイナスにできないので、実際には正の整数解のしぼり込みまでやって初めて答えになります。
6個入りと10個入りの箱しかないとき、注文どおりの個数をぴったりそろえられるかどうかは、\(6x + 10y = c\) に 0 以上の整数解があるかどうかで決まります。6 と 10 の最大公約数は 2 なので、奇数個の注文はどう組み合わせても作れません。
食品や部品の箱詰めでは、この「作れる個数」の見極めが、注文を受けられるか・どの箱サイズをそろえるべきかの判断に直結します。
5Lと3Lの容器だけで4Lを量る、という有名な問題は \(5x + 3y = 4\) の整数解に対応します(\(x\)・\(y\) は、それぞれの容器で足した回数と減らした回数を符号付きで表したものです)。\(\gcd(5,\ 3) = 1\) なので、この2つの容器があれば1Lきざみでどんな量でも量れることが、式から先に判定できます。
実験や調理で「手元の器具だけで必要な量を作れるか」を考えるときの、そのままの数学です。
ネットバンキングやオンラインショッピングを支えているRSA暗号では、公開鍵の値 \(e\) から秘密鍵の値 \(d\) を作るときに \(e d + \varphi k = 1\) という一次不定方程式を解きます(\(\varphi\) は鍵ごとに決まる整数)。ここで使われているのが、このページと同じ拡張ユークリッドの互除法です。
何百桁もある数でもこの手順なら一瞬で解けることが、暗号を実用にしている土台の一つになっています。
1個あたり \(a\) g の材料を使う製品Aと、\(b\) g 使う製品Bを作って、用意した \(c\) g の材料をちょうど使い切りたい。この計画は \(ax + by = c\) の 0 以上の整数解を求める問題です。製品は0.5個だけ作るということができないので、答えは整数でなければなりません。
このように「答えが整数に限られる計画問題」を扱う分野は整数計画法と呼ばれ、生産計画・シフト作成・配送計画などで使われています。
式とグラフ
用語・記号の解説
記号
| \(a,\ b\) | エー・ビー | \(x\) と \(y\) に掛かっている係数。決まった数を表すときは、アルファベットの最初の方の文字 \(a,\ b,\ c\) を使う慣例があります。このページではどちらも整数です。 |
| \(c\) | シー | 方程式の右辺の定数。constant(定数)の頭文字です。「作りたい合計」にあたる数で、これが最大公約数の倍数かどうかで解の有無が決まります。 |
| \(x,\ y\) | エックス・ワイ | 求める未知数。未知の数はアルファベットの終わりの方の文字で表す、という書き方はデカルトが広めたといわれます。このページでは整数の値だけを答えとして扱います。 |
| \(\gcd(a,\ b)\) | ジー・シー・ディー、さいだいこうやくすう | \(a\) と \(b\) の最大公約数。greatest common divisor(最大の共通の約数)の頭文字です。日本の教科書では \((a,\ b)\) と略記することもあります。 |
| \(g\) | ジー | 最大公約数 \(\gcd(a,\ b)\) を短く書いた記号。greatest(最大)の頭文字です。一般解の \(\dfrac{b}{g}\)・\(\dfrac{a}{g}\) のように、式が長くなるのを防ぐために使います。 |
| \(x_0,\ y_0\) | エックス・ゼロ、ワイ・ゼロ | 特殊解、つまり最初に見つけた1組の整数解。「基準になる0番目の解」という意味で右下に 0 を添えます。ここを出発点にして、すべての整数解を表します。 |
| \(x_1,\ y_1\) | エックス・イチ、ワイ・イチ | 互除法を逆にたどると見つかる整数の組で、\(a x_1 + b y_1 = g\) を満たします。これを \(\dfrac{c}{g}\) 倍すると特殊解 \((x_0,\ y_0)\) になります。 |
| \(t\) | ティー | 整数なら何でもよい変数(媒介変数)。すべての整数解を一つの式でまとめて表すために使います。\(t\) に整数を入れるたびに、別の整数解が1組現れます。 |
| \(m\) | エム | 「\(c\) が \(g\) の何倍か」を表す整数。整数を表す文字には \(m\)・\(n\)・\(k\) がよく使われ、\(m\) は multiple(倍数)の頭文字に由来するといわれます。\(c = g \times m\) と書けるとき、そしてそのときだけ整数解があります。 |
| \(q\) | キュー | 割り算の商。quotient(商)の頭文字です。互除法の表では \(13 = 5 \times 2 + 3\) の \(2\) にあたります。 |
| \(r\) | アール | 割り算の余り。remainder(余り)の頭文字です。互除法の表では \(13 = 5 \times 2 + 3\) の \(3\) にあたります。この余りが 0 になったときが計算の終わりです。 |
| \(\geqq\) | だいなりイコール、いじょう | 「左辺が右辺以上」を表す不等号。\(x \geqq 1\) は「\(x\) は 1 以上」という意味です。日本の教科書では等号付きの不等号を \(\geqq\)・\(\leqq\) の形で書きます。 |
用語
| 一次不定方程式 | いちじふていほうていしき | \(ax + by = c\) のように、未知数が2つあるのに式が1つしかない一次方程式。「不定」は解が1つに定まらないという意味で、実数の範囲なら直線上のすべての点が解になります。整数解に限っても、普通は無数にあります。 |
| ディオファントス方程式 | ディオファントスほうていしき | 整数解だけを答えとする方程式をまとめた呼び名。古代ギリシャの数学者ディオファントスの名前に由来します。このページで扱う一次不定方程式は、その中で最も基本的なものです。 |
| 整数解 | せいすうかい | 方程式を満たす解のうち、\(x\) も \(y\) も整数になっているもの。枚数・個数・人数など「半端があり得ない量」を求める問題では、整数解だけが意味を持ちます。 |
| 特殊解 | とくしゅかい | 無数にある整数解のうち、最初に見つけた1組のこと。どの1組を選んでもかまいません。ここを出発点にして、一般解の形ですべての解を表します。 |
| 一般解 | いっぱんかい | すべての整数解を、整数 \(t\) を使って一つの式にまとめて表したもの。\(t\) に整数を入れると、そのつど別の解が1組取り出せます。 |
| 最大公約数 | さいだいこうやくすう | 2つ以上の整数のどれをも割り切れる正の整数のうち、一番大きいもの。一次不定方程式では、この値が「解があるかどうか」と「解と解の間隔」の両方を決めます。 |
| ユークリッドの互除法 | ユークリッドのごじょほう | 大きい方を小さい方で割り、割る数と余りの組に置き換える、という操作をくり返して最大公約数を求める方法。余りが 0 になったときの割る数が最大公約数です。紀元前3世紀ごろの著書「原論」に載っている、世界最古のアルゴリズムとも呼ばれる手順です。 |
| 拡張ユークリッドの互除法 | かくちょうユークリッドのごじょほう | 互除法の割り算の式を下から順に代入し直して、最大公約数を \(a x_1 + b y_1\) の形で表す方法。一次不定方程式の特殊解を作るのに使います。 |
| ベズーの等式 | ベズーのとうしき | \(a x_1 + b y_1 = \gcd(a,\ b)\) を満たす整数 \(x_1,\ y_1\) が必ず存在する、という定理。フランスの数学者ベズーの名前が付いています。一次不定方程式が解けることの根拠です。 |
| 互いに素 | たがいにそ | 2つの整数の最大公約数が 1 であること。例えば 3 と 4 は互いに素です。\(\dfrac{a}{g}\) と \(\dfrac{b}{g}\) は必ず互いに素になり、これが「解が等間隔に並ぶ」ことの決め手になります。 |
| 倍数 | ばいすう | ある整数を整数倍して作れる数。\(10\) の倍数は \(\dots,\ -20,\ -10,\ 0,\ 10,\ 20,\ \dots\) です。0 や負の数も倍数に含めます。 |
| 余り | あまり | 整数の割り算で割り切れずに残る数。\(13 \div 5\) は商が \(2\) で余りが \(3\) です。互除法はこの余りだけを使って進みます。 |
| 商 | しょう | 整数の割り算で「割る数が何回分とれるか」を表す整数。\(13 = 5 \times 2 + 3\) の \(2\) が商です。 |
| 格子点 | こうしてん | 座標平面上で、\(x\) 座標も \(y\) 座標も整数である点。方眼紙のマス目の交点にあたります。一次不定方程式の整数解は、直線 \(ax + by = c\) の上にある格子点そのものです。 |
| 媒介変数 | ばいかいへんすう | 解の集まり全体を一つの式で表すために置く、自由に動かせる変数。このページの \(t\) がそれです。パラメータとも呼びます。 |
| 係数 | けいすう | 文字の前に付いている数。\(3x\) の \(3\) が係数です。数が書かれていない \(x\) の係数は 1 と考えます。 |
| 不等式 | ふとうしき | \(t \geqq 0\) のように、2つの値の大小関係を表す式。正の整数解を絞り込むときに使います。 |
前提として理解しておくといいこと
このページの計算を「意味がわかって」使えるようになるために、前提として理解しておくといいことをまとめました。
つまずいたら、この表の内容に戻って復習するのが近道です。
| 整数の割り算と余り(小学4年〜中学1年) |
|
| 約数・倍数・最大公約数(小学5年〜中学3年) |
|
| 文字式と一次方程式(中学1年〜2年) |
|
| 二元一次方程式とそのグラフ(中学2年) |
|
| 不等式(中学1年〜高校 数学I) |
|
| 分数の計算(小学5年〜中学1年) |
|
Excelで計算する方法
| x の係数 a | 50 |
| y の係数 b | 80 |
| 右辺の定数 c | 1000 |
| 最大公約数 g | =GCD(B1,B2) |
| c を g で割った余り | =MOD(B3,B4) |
| 整数解があるか | =IF(B5=0,"整数解がある","整数解はない") |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 互除法で見つけた x1 | -3 |
| 互除法で見つけた y1 | 2 |
| a×x1 + b×y1 | =B1*B3+B2*B4 |
| 最大公約数 g | =GCD(B1,B2) |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 右辺の定数 c | 1000 |
| 最大公約数 g | =GCD(B1,B2) |
| 特殊解 x0 | 4 |
| 特殊解 y0 | 10 |
| 整数 t | 1 |
| x = x0 + (b/g)×t | =B5+(B2/B4)*B7 |
| y = y0 − (a/g)×t | =B6-(B1/B4)*B7 |
| 検算 a×x + b×y | =B1*B8+B2*B9 |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 最大公約数 g | =GCD(B1,B2) |
| 特殊解 x0 | 4 |
| 特殊解 y0 | 10 |
| t の下限(x ≧ 1 から) | =-INT((B4-1)/(B2/B3)) |
| t の上限(y ≧ 1 から) | =INT((B5-1)/(B1/B3)) |
| 正の整数解の個数 | =MAX(0,B7-B6+1) |
1つ目の表は 50x + 80y = 1000 の例で、最大公約数は 10、1000 を 10 で割った余りは 0 なので「整数解がある」と表示されます。ここを 1001 に変えると「整数解はない」に変わります。
2つ目の表は、互除法を逆にたどって得た x1 = −3、y1 = 2 が本当にベズーの等式を満たすかの確認用です。50×(−3) + 80×2 = 10 となり、最大公約数と一致します。
3つ目の表は一般解から解を1組取り出す表です。t に 1 を入れると x = 12、y = 5 になり、検算の行は 1000 に戻ります。t をいろいろな整数に変えて試してください。
4つ目の表は正の整数解を絞り込む表です。t の下限は 0、上限は 1 と出るので、正の整数解は 2 組(t = 0 と t = 1)とわかります。この2つの式は a も b も正の場合のものなので、負の係数を入れるときは不等号の向きが変わる点に注意してください。
Googleスプレッドシートで計算する方法
| x の係数 a | 50 |
| y の係数 b | 80 |
| 右辺の定数 c | 1000 |
| 最大公約数 g | =GCD(B1,B2) |
| c を g で割った余り | =MOD(B3,B4) |
| 整数解があるか | =IF(B5=0,"整数解がある","整数解はない") |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 互除法で見つけた x1 | -3 |
| 互除法で見つけた y1 | 2 |
| a×x1 + b×y1 | =B1*B3+B2*B4 |
| 最大公約数 g | =GCD(B1,B2) |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 右辺の定数 c | 1000 |
| 最大公約数 g | =GCD(B1,B2) |
| 特殊解 x0 | 4 |
| 特殊解 y0 | 10 |
| 整数 t | 1 |
| x = x0 + (b/g)×t | =B5+(B2/B4)*B7 |
| y = y0 − (a/g)×t | =B6-(B1/B4)*B7 |
| 検算 a×x + b×y | =B1*B8+B2*B9 |
| x の係数 a | 50 |
| y の係数 b | 80 |
| 最大公約数 g | =GCD(B1,B2) |
| 特殊解 x0 | 4 |
| 特殊解 y0 | 10 |
| t の下限(x ≧ 1 から) | =-INT((B4-1)/(B2/B3)) |
| t の上限(y ≧ 1 から) | =INT((B5-1)/(B1/B3)) |
| 正の整数解の個数 | =MAX(0,B7-B6+1) |
Pythonで計算する方法
from math import gcd
# ax + by = c の係数(整数)
a, b, c = 50, 80, 1000
def extended_gcd(x, y):
# 拡張ユークリッドの互除法:gcd と、x*s + y*t = gcd を満たす s, t を返す
if y == 0:
return x, 1, 0
g, s, t = extended_gcd(y, x % y)
return g, t, s - (x // y) * t
g = gcd(a, b)
if c % g != 0:
print(f"{c} は {g} の倍数ではないので、整数解はありません")
else:
_, s, t = extended_gcd(a, b)
x0, y0 = s * (c // g), t * (c // g) # 特殊解(1組の整数解)
step_x, step_y = b // g, a // g # x のずれ幅と y のずれ幅
# x が 0 以上で最小になるまでずらして、見やすい特殊解に直す
n = x0 // step_x
x0, y0 = x0 - n * step_x, y0 + n * step_y
print(f"特殊解: (x, y) = ({x0}, {y0})")
print(f"一般解: x = {x0} + {step_x}t, y = {y0} - {step_y}t (t は整数)")
for k in range(-2, 3):
print(f" t = {k:2}: (x, y) = ({x0 + step_x * k}, {y0 - step_y * k})")
# 正の整数解(x >= 1 かつ y >= 1)だけを取り出す
t_low = -((1 - x0) // -step_x)
t_high = (y0 - 1) // step_y
print("正の整数解:", [(x0 + step_x * k, y0 - step_y * k)
for k in range(t_low, t_high + 1)])
数式記述言語(LaTeX等)での書き方(コピペ可)
c = gcd(a, b) × m
c = \gcd(a, b) \times m
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>c</mi>
<mo>=</mo>
<mi>gcd</mi><mo>(</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>)</mo>
<mo>×</mo>
<mi>m</mi>
</mrow>
</math>
c = gcd(a, b) * m
Mod[c, GCD[a, b]] == 0
irem(c, igcd(a, b)) = 0;
mod(c, gcd(a, b)) == 0
c = gcd(a,b) × m
a·x₁ + b·y₁ = gcd(a, b)
a x_1 + b y_1 = \gcd(a, b)
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>a</mi><msub><mi>x</mi><mn>1</mn></msub>
<mo>+</mo>
<mi>b</mi><msub><mi>y</mi><mn>1</mn></msub>
<mo>=</mo>
<mi>gcd</mi><mo>(</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>)</mo>
</mrow>
</math>
a*x_1 + b*y_1 = gcd(a, b)
ExtendedGCD[a, b]
igcdex(a, b, x1, y1);
[g, x1, y1] = gcd(a, b);
a x_1 + b y_1 = gcd(a,b)
x = x₀ + (b/g)t, y = y₀ − (a/g)t
x = x_0 + \frac{b}{g} t, \quad y = y_0 - \frac{a}{g} t
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<mi>x</mi><mo>=</mo><msub><mi>x</mi><mn>0</mn></msub>
<mo>+</mo>
<mfrac><mi>b</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>,</mo><mspace width="1em"/>
<mi>y</mi><mo>=</mo><msub><mi>y</mi><mn>0</mn></msub>
<mo>−</mo>
<mfrac><mi>a</mi><mi>g</mi></mfrac><mi>t</mi>
</mrow>
</math>
x = x_0 + (b/g)t, y = y_0 - (a/g)t
Solve[a x + b y == c, {x, y}, Integers]
isolve(a*x + b*y = c);
S = solve(a*x + b*y == c, [x y], 'Integer', true);
x = x_0 + (b/g)t, y = y_0 - (a/g)t
x₀ + (b/g)t ≧ 1 かつ y₀ − (a/g)t ≧ 1
x_0 + \frac{b}{g} t \geqq 1, \quad y_0 - \frac{a}{g} t \geqq 1
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mrow>
<msub><mi>x</mi><mn>0</mn></msub>
<mo>+</mo>
<mfrac><mi>b</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>≧</mo><mn>1</mn>
<mo>,</mo><mspace width="1em"/>
<msub><mi>y</mi><mn>0</mn></msub>
<mo>−</mo>
<mfrac><mi>a</mi><mi>g</mi></mfrac><mi>t</mi>
<mo>≧</mo><mn>1</mn>
</mrow>
</math>
x_0 + (b/g)t >= 1 and y_0 - (a/g)t >= 1
Solve[a x + b y == c && x >= 1 && y >= 1, {x, y}, Integers]
isolve({a*x + b*y = c, x >= 1, y >= 1});
S = solve([a*x + b*y == c, x >= 1, y >= 1], [x y], 'Integer', true);
x_0 + (b/g)t ≧ 1, y_0 − (a/g)t ≧ 1
ChatGPT に聞いて計算してもらう方法
あなたは数学(整数の性質)の計算アシスタントです。次の計算を、必ずPythonコードを実際に実行して行い、実行結果の数値だけを根拠に回答してください(暗算や推測で答えないでください)。 一次不定方程式 50x + 80y = 1000 の整数解を求めてください。 次の内容をそれぞれ示してください。 1. 50 と 80 の最大公約数と、1000 がその倍数かどうか 2. ユークリッドの互除法の割り算の式(余りが0になるまで)と、それを逆にたどって得られる 50×x1 + 80×y1 = 最大公約数 の x1, y1 3. 特殊解 (x0, y0) と、一般解 x = x0 + (b/g)t, y = y0 − (a/g)t 4. x も y も1以上になる整数解をすべて Pythonでは math.gcd と拡張ユークリッドの互除法を使って厳密に計算し、計算に使った式と実行結果の数値を示してください。
計算ドリル(演習問題)
このページの式を、自分の手で計算できるようになるための演習問題です。
答えと解説は解答ページにあります。
使い方
-
1数値を入力計算したい数値を入力欄に入力します
-
2計算「計算する」ボタンを押します
-
3結果を確認計算結果がその場に表示されます。計算の考え方や式の解説も同じページで確認できます
DataChefの特徴
専門知識不要、直感的で簡単な操作
個人情報を登録することなく使用できます
「ダウンロード」押下でファイルを自動削除
クレジット表記不要
商用利用許諾の連絡も不要です
