#wolfram-mathematica #max
#wolfram-mathematica #max
Вопрос:
Я определил три переменные a,b,c
перед циклом while, а затем вычислил новую переменную d
.
Я хочу избавиться от самого большого значения в трех переменных a,b,c
, а затем заменить его d
значением; Поэтому я могу сохранить наименьшие значения в трех исходных переменных.
a = 1;
b = 2;
c = 10;
While[ condition,
compute d using values of a b and c
d = 4;
a = 1;
b = 2;
c = 4; (*c = d *)
]
для этого я подумал получить максимум из трех переменных, а затем обновить его в зависимости от того, какая из них имеет наибольшее значение..
a = 1;
b = 2;
c = 10;
d = 4;
temp = Max[a, b];
maxim = Max[c, temp];
a = a; (*did not change*)
b = b; (*did not change*)
c = d = 4 (*changed!!*)
Итак, после этого произойдет новая итерация и обновит три переменные…
Комментарии:
1. Итак, у вас есть список из трех переменных с числовыми значениями, и вы хотите заменить самый большой элемент в списке новым значением?
2. Кроме того, меня смущает «наиболее близкое к новому значению 5», которое, я полагаю, будет равно 1, а не 10.
3. да, позвольте мне объяснить это правильно, я хочу обновить три переменных и наибольшее значение, поэтому предположим, что у меня есть a = 1, b = 2, c = 40, затем четвертая переменная d = 5, так что у меня будет a = 1, b = 2, c =5, потому что a, b близки к новому значению d
4. Избавьтесь от самого большого значения, а переменная, которая является самой большой, заменяется значением
d
, поэтому я сохраняю три самых одинаковых значения5. @cMinor Я помню вас по тегу MATLAB, и я вижу сильное влияние этого на ваш код Mathematica. Хотя процедурный код может быть полезен при начале изучения Mathematica, я бы настоятельно рекомендовал попутно изучить более идиоматические способы выполнения задач в Mathematica (см. Наши ответы о некоторых подходах, которые вы не видели на других языках). Это, несомненно, очень поможет вам, если вы углубитесь в это. В то же время, я думаю, что все трое из нас, кто ответил, были бы признательны за обратную связь…
Ответ №1:
Другой вариант заключается в следующем:
Clear@updateList
SetAttributes[updateList, HoldFirst]
updateList[list_, value_] :=
Module[{listMax = Max@list},
list = (list /. listMax -> value);]
Теперь, если я определяю переменные, как в вашем случае, и использую функцию:
a = 1; b = 10; c = 0;
updateList[{a,b,c},5];
{a,b,c}
Out[1]= {1, 5, 0}
Вы можете видеть, что переменная b
, которая была самой большой, была заменена новым значением.
Комментарии:
1. @Mr.Wizard Вы правы, мне не нужно
ReleaseHold
.HoldFirst
является только атрибутомupdateList
и используется в первом экземпляреlist
. Во второй и третьей —list
аргументReplaceAll
иMax
соответственно, и, следовательно, этот атрибут не выполняется.2. Удалите свой комментарий, прежде чем Леонид его увидит. Он всем расскажет! :->
3. Это просто несправедливо. Теперь у вас более 50 голосов впереди меня. Возможно, мне придется обратиться к темной стороне, чтобы бороться с этим…
4. я оставил тебя в пыли, не так ли? : D На самом деле это первый раз, когда я когда-либо приближался к 100 голосам за 30 дней в mma и фактически близок к серебру. Когда я начинал, я думал, что к настоящему времени у меня будет золото в MATLAB, но, похоже, я потерял к нему интерес. Я серьезно не отвечал там с июня (так что больше времени для mma: D). Но если серьезно, я вижу, что в ближайшие пару месяцев я буду очень занят, так что запускайте tortise, запускайте!
5. К сожалению, я сам буду очень занят, поэтому поймать вас будет сложно, несмотря на ваши короткие ноги … 🙂 У меня также никогда не было 100 голосов за 30 дней, точка. Но я не участвовал почти так же, как вы.
Ответ №2:
Если вы можете принимать значения в списке (массиве), а не отдельные именованные символы, и если вы действительно имеете в виду «наиболее близкие», а не наибольшие, то вы можете сделать что-то вроде этого:
vars = {1, 10, 0};
vars = ReplacePart[vars, Position[vars, Nearest[vars, 5][[1]]] -> 5];
vars
(* Out= {5, 10, 0} *)
Это также предполагает, что значения уникальны или что вы хотите заменить все совпадающие значения (например, если в 1
этом примере в списке больше одного).
Если вы всегда хотите заменить наибольшее значение, то вы могли Max[vars]
бы, а не Nearest
.
В свете обновленного описания проблемы я предлагаю:
vars = {1, 10, 0};
d = 5;
vars = With[{m = Max[vars]}, If[d < m, vars /. m -> d, vars]]
Если вы хотите автоматизировать это, вы можете использовать:
SetAttributes[repmax, HoldFirst]
repmax[s_Symbol, n_?NumericQ] := If[n < #, s = s /. # -> n]amp; @ Max@s
Теперь:
vals = {1, 10, 0};
repmax[vals, 5];
vals
{1, 5, 0}
vals = {1, 10, 0};
repmax[vals, 12];
vals
{1, 10, 0}
Ответ №3:
Вероятно, это не лучший способ решения этой проблемы,
a = 1; b = 10; c = 0;
Position[#, Max@#] amp;@{a, b, c}
{a, b, c} = ReplacePart[{a, b, c}, % -> 5]
Вам было бы лучше определить свои исходные значения в виде списка abc = {1, 10, 0}
, а затем заменить элемент max списка. Как я заметил, мистер Мастер только что сделал в своем ответе.
Вы также можете сделать что-то вроде
SetAttributes[ReplaceMax, HoldFirst]
ReplaceMax[list : {__Symbol}, val_] := Module[{pos},
pos = Flatten@Position[#, Max@Select[#, N[#] [Element] Reals amp;]]amp;@list;
Do[Evaluate[(HoldPattern /@ Unevaluated@list)[[p]]] = val,
{p, pos}]]
Затем
In[15]:= {a, b, c, d, e} = {1, 15, 6, 17 I, x};
In[16]:= ReplaceMax[{a, b, c, d, e}, 5]
{a, b, c, d, e}
Out[17]= {1, 5, 6, 17 I, x}