Создание случайных коэффициентов для линейных уравнений в математике - PullRequest
5 голосов
/ 16 сентября 2011

Есть ли способ присвоить случайное значение p1, p2, p3 и p4 для следующего уравнения?

p1 y1 + p2 y2 + p3 y3 = p4

учитывая, что y1, y2 и y3 являются переменными, которые необходимо решить.

Ответы [ 5 ]

9 голосов
/ 16 сентября 2011

Самый простой (?) Способ - это Thread список случайных значений над правилом замены:

Например:

p1 y1 + p2 y2 + p3 y3 == p4 /. Thread[{p1, p2, p3, p4} -> RandomReal[{0, 1}, 4]]

(* 0.345963 y1 + 0.333069 y2 + 0.565556 y3 == 0.643419 *)

Или, вдохновленный Леонидом, вы можетеиспользуйте Alternatives и сопоставление с образцом:

p1 y1 + p2 y2 + p3 y3 == p4 /. p1 | p2 | p3 | p4 :> RandomReal[]

Просто для удовольствия, вот еще одно подобное решение:

p1 y1 + p2 y2 + p3 y3 == p4 /. s_Symbol :> 
     RandomReal[]/;StringMatchQ[SymbolName[s], "p"~~DigitCharacter]

Где вы можете заменить DigitCharacter на NumberString если вы хотите, чтобы оно соответствовало больше, чем просто p0, p1, ..., p9.Конечно, для больших выражений вышеупомянутое не будет особенно эффективным ...

7 голосов
/ 16 сентября 2011

Другие ответы хороши, но если вы делаете много такого рода вещей, я рекомендую называть ваши переменные и коэффициенты более систематическим образом. Это не только позволит вам написать гораздо более простое правило, но и значительно упростит изменения, когда придет время перейти от 3 уравнений к 4. Например:

In[1]:= vars   = Array[y, 3] 
Out[1]= {y[1], y[2], y[3]}

In[2]:= coeffs = Array[p, 4]
Out[2]= {p[1], p[2], p[3], p[4]}

Вы можете быть немного прихотливы, когда составляете уравнение:

In[3]:= vars . Most[coeffs] == Last[coeffs]
Out[3]= p[1] y[1] + p[2] y[2] + p[3] y[3] == p[4]

Подстановка случайных чисел для коэффициентов теперь является одним из самых основных правил:

In[4]:= sub = eqn /. p[_] :> RandomReal[] 
Out[4]= 0.281517 y[1] + 0.089162 y[2] + 0.0860836 y[3] == 0.915208

Правило в конце также может быть написано _p :> RandomReal[], если вы предпочитаете. Вам также не нужно много печатать, чтобы решить эту проблему.

In[5]:= Reduce[sub]
Out[5]= y[1] == 3.25099 - 0.31672 y[2] - 0.305785 y[3]

Как сказал Эндрю Уокер , вы используете Reduce, чтобы найти все решения, а не только некоторые из них. Вы можете заключить это в функцию, которая параметризует количество переменных следующим образом:

In[6]:= reduceRandomEquation[n_Integer] := 
          With[{vars = Array[y, n], coeffs = Array[p, n+1]},
            Reduce[vars . Most[coeffs]]

In[7]:= reduceRandomEquation[4]
Out[7]= y[1] == 2.13547 - 0.532422 y[2] - 0.124029 y[3] - 2.48944 y[4]
4 голосов
/ 16 сентября 2011

Если вам нужны решения с подставленными значениями, один из возможных способов сделать это:

f[y1_, y2_, y3_] := p1 y1 + p2 y2 + p3 y3 - p4
g = f[y1, y2, y3] /. p1 -> RandomReal[] /. p2 -> RandomReal[] /. 
   p3 -> RandomReal[] /. p4 -> RandomReal[]
Reduce[g == 0, {y1}]
Reduce[g == 0, {y2}]
Reduce[g == 0, {y3}]

Если все, что вам нужно, это решение уравнений:

f[y1_, y2_, y3_] := p1 y1 + p2 y2 + p3 y3 - p4
g = f[y1, y2, y3]
Solve[g == 0, {y1}]
Solve[g == 0, {y2}]
Solve[g == 0, {y3}]
3 голосов
/ 16 сентября 2011

Если вы можете жить без имен символьных коэффициентов p1 и др., Вы можете сгенерировать, как показано ниже.Мы берем список переменных, число уравнений и диапазон для коэффициентов и вектора rhs.

In[80]:= randomLinearEquations[vars_, n_, crange_] := 
 Thread[RandomReal[crange, {n, Length[vars]}].vars == 
   RandomReal[crange, n]]

In[81]:= randomLinearEquations[{x, y, z}, 2, {-10, 10}]

Out[81]= {7.72377 x - 4.18397 y - 4.58168 z == -7.78991, -1.13697 x + 
   5.67126 y + 7.47534 z == -6.11561}

Получить варианты, такие как целочисленные коэффициенты, различные диапазоны для матрицы и rhs и т. Д., Несложно.

Даниэль Лихтблау

2 голосов
/ 16 сентября 2011

Другой способ:

dim = 3;
eq = Array[p, dim].Array[y, dim] == p[dim + 1];
Evaluate@Array[p, dim + 1] = RandomInteger[10, dim + 1]

Solve[eq, Array[y, dim]]
...