Как изменить значения матрицы на значения из другой матрицы - Wolfram
Я только начал свое путешествие с Wolfram Mathematica и хочу реализовать простой генетический алгоритм. Построение данных дано, и я должен начать с таких строк / столбцов.
Вот что у меня есть:
chromosome := RandomSample[CharacterRange["A", "G"], 7]
chromosomeList = Table[chromosome, 7] // MatrixForm
Это дает мне матрицу, где каждая строка представляет хромосому:
yPos = Flatten[Position[chromosomeList, #], 1] & /@ {"A", "B", "C",
"D", "E", "F", "G"};
yPos = yPos[[All, 3 ;; 21 ;; 3]] // Transpose
Теперь каждый столбец представляет букву (от A до G), а каждая строка - это индекс в каждой хромосоме:
Вот заданная матрица эффективности, где в самой строке представлены разные буквы (от A до G), а в каждом столбце указано значение, которое следует применить к конкретной позиции:
efficiencyMatrix = {
{34, 31, 20, 27, 24, 24, 18},
{14, 14, 22, 34, 26, 19, 22},
{22, 16, 21, 27, 35, 25, 30},
{17, 21, 24, 16, 31, 22, 20},
{17, 29, 22, 31, 18, 19, 26},
{26, 29, 37, 34, 37, 20, 21},
{30, 28, 37, 28, 29, 23, 19}}
Я хочу создать матрицу со значениями, которые соответствуют букве и ее позиции. Я сделал это так:
values = Transpose[{ efficiencyMatrix[[1, yPos[[1]]]],
efficiencyMatrix[[2, yPos[[2]]]],
efficiencyMatrix[[3, yPos[[3]]]],
efficiencyMatrix[[4, yPos[[4]]]],
efficiencyMatrix[[5, yPos[[5]]]],
efficiencyMatrix[[6, yPos[[6]]]],
efficiencyMatrix[[7, yPos[[7]]]]}]
Как я могу написать это более элегантно?
1 ответ
Вы можете применить список функций к некоторой переменной, используя функцию Through
, что полезно при применении Position
многократно. Так как Position[patt][expr] == Position[expr, patt]
, мы можем
Through[ (Position /@ CharacterRange["A","C"])[{"B", "C", "A"}] ]
получить {3, 1, 2}
,
Position
может также работать со списками, поэтому мы можем упростить поиск ypos
при выполнении
Transpose@Map[Last, Through[(Position /@ characters)[chromosomeList]], {2}]
где characters
это соответствующий результат CharacterRange
,
Мы также можем упростить работу с диапазонами целых чисел, сопоставляя Range
функция, так что в итоге мы в конечном итоге
characters = CharacterRange["A","G"]
efficiencies = ...
chromosomes = ...
ypos = Transpose@Map[Last, Through[(Position /@ characters)[chromosomes]], {2}];
efficiencies[[#, ypos[[#]]]]& /@ Range[Length[characters]] //Transpose ]