Помощь - Поиск - Пользователи - Календарь
Полная версия: [Java] среднее геометрическое
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Shashlyk
Добрый День!!! smile.gif
помогите Пожалуйста написать метод, который будет в целочисленной матрице заменять все элементы средним геометрическим абсолютных значений их соседей.
Мой код, с добавлением "единичной" границы к матрице:
int SrGeom; 
int Product;
for(int i = 1; i < n+1; i++){
for(int j = 1;j < m+1; j++){
Product = Math.abs(unitmatrix[i-1][j]) * Math.abs(unitmatrix[i+1][j]) *
Math.abs(unitmatrix[i][j-1]) * Math.abs(unitmatrix[i][j+1]);
SrGeom = (int)Math.pow(Product, 0.25);
}
}
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
array[i][j] = SrGeom;
}
}
Помогите Пожалуйста переделать код, с подсчётом среднего геометрического через логарифмы или экспоненты и с правильной заменой
IUnknown
Я бы не стал менять на экспоненту с логарифмом. Pow прекрасно справляется с задачей. Единственное, что я бы сделал - это убрал бы добавление
Цитата
"единичной" границы к матрице:
. Вот так:

        public static int Count;

int Counter() {
Count -= 1;
return 1;
}

void Action() {
int [][] ca = new int [n][m];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) ca[i][j] = a[i][j];

for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
Count = 4;
int Product = ((i > 0) ? Math.abs(ca[i-1][j]) : Counter()) *
((i < n - 1) ? Math.abs(ca[i+1][j]) : Counter()) *
((j > 0) ? Math.abs(ca[i][j-1]) : Counter()) *
((j < m - 1) ? Math.abs(ca[i][j+1]) : Counter());
int SrGeom = (int)Math.pow(Product, 1.0 / Count); // Вычисляем правильное значение
a[i][j] = SrGeom;
}
}
}
, у тебя среднее геометрическое вычисляется неверно. Если ты перемножал 2 элемента - то и корень должен быть квадратный, а не 4-ой степени. В твоем варианте значения на граничных элементах будут меньше, чем нужно.
Shashlyk
Цитата(IUnknown @ 3.06.2011 11:14) *

Я бы не стал менять на экспоненту с логарифмом. Pow прекрасно справляется с задачей. Единственное, что я бы сделал - это убрал бы добавление . Вот так:

        public static int Count;

int Counter() {
Count -= 1;
return 1;
}

void Action() {
int [][] ca = new int [n][m];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) ca[i][j] = a[i][j];

for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
Count = 4;
int Product = ((i > 0) ? Math.abs(ca[i-1][j]) : Counter()) *
((i < n - 1) ? Math.abs(ca[i+1][j]) : Counter()) *
((j > 0) ? Math.abs(ca[i][j-1]) : Counter()) *
((j < m - 1) ? Math.abs(ca[i][j+1]) : Counter());
int SrGeom = (int)Math.pow(Product, 1.0 / Count); // Вычисляем правильное значение
a[i][j] = SrGeom;
}
}
}
, у тебя среднее геометрическое вычисляется неверно. Если ты перемножал 2 элемента - то и корень должен быть квадратный, а не 4-ой степени. В твоем варианте значения на граничных элементах будут меньше, чем нужно.


А объясните Пожалуйста Ваш алгоритм! для чего нужен вот этот код:
int Counter() {
Count -= 1;
return 1;
}

Что происходит в :
 int [][] ca = new int [n][m];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) ca[i][j] = a[i][j];

Ну и остальное, если не трудно smile.gif
IUnknown
Цитата
Что происходит в :
Тут делается копия исходной матрицы. Если этого не сделать - то результаты исказятся, при вычислении последующих элементов будут браться не их соседи, а уже ранее вычисленные средние геометрические. Поэтому делаем копию, и берем "соседей" оттуда, а результатами заполняем исходную матрицу.

Цитата
для чего нужен вот этот код:
В самом хорошем случае у ячейки может быть 4 соседа. Я на каждой итерации цикла Count присваиваю четырем. Считаем, что этот "самый хороший случай" произошел. А потом начинаем отрабатывать не очень хорошие:

   // Первая строка выражения (остальные - аналогично, разберись сам)
// Ячейка НЕ самая крайняя слева? (i > 0) ?
// (до двоеточия) Да, это НЕ самая левая ячейка, домножаем произведение на модуль элемента слева
// (после двоеточия) Упс. Ячейка самая левая, брать левее нельзя, выбросится исключение
// из-за нарушения границ массива. Значит надо сделать 2 вещи:
// 1) принять во внимание, что сомножителей на 1 меньше, чем предполагалось
// 2) домножить Product все равно придется, но домножать его будем на 1-цу, чтоб ничего не изменилось

int Product = ((i > 0) ? Math.abs(ca[i-1][j]) : Counter()) *
((i < n - 1) ? Math.abs(ca[i+1][j]) : Counter()) *
((j > 0) ? Math.abs(ca[i][j-1]) : Counter()) *
((j < m - 1) ? Math.abs(ca[i][j+1]) : Counter());
Так вот, тот код, который ты процитировал, функция Counter, как раз и делает эти 2 вещи: уменьшает число сомножителей, и возвращает 1, на которую домножается произведение. В результате выполнения всей строки у нас без всяких дополнительных "единичных границ" правильно считается произведение соседних элементов. А потом остается в извлечь корень нужной степени (степени Count), чтобы получить среднее геометрическое.
Shashlyk
Цитата(IUnknown @ 3.06.2011 20:05) *

Тут делается копия исходной матрицы. Если этого не сделать - то результаты исказятся, при вычислении последующих элементов будут браться не их соседи, а уже ранее вычисленные средние геометрические. Поэтому делаем копию, и берем "соседей" оттуда, а результатами заполняем исходную матрицу.

В самом хорошем случае у ячейки может быть 4 соседа. Я на каждой итерации цикла Count присваиваю четырем. Считаем, что этот "самый хороший случай" произошел. А потом начинаем отрабатывать не очень хорошие:

   // Первая строка выражения (остальные - аналогично, разберись сам)
// Ячейка НЕ самая крайняя слева? (i > 0) ?
// (до двоеточия) Да, это НЕ самая левая ячейка, домножаем произведение на модуль элемента слева
// (после двоеточия) Упс. Ячейка самая левая, брать левее нельзя, выбросится исключение
// из-за нарушения границ массива. Значит надо сделать 2 вещи:
// 1) принять во внимание, что сомножителей на 1 меньше, чем предполагалось
// 2) домножить Product все равно придется, но домножать его будем на 1-цу, чтоб ничего не изменилось

int Product = ((i > 0) ? Math.abs(ca[i-1][j]) : Counter()) *
((i < n - 1) ? Math.abs(ca[i+1][j]) : Counter()) *
((j > 0) ? Math.abs(ca[i][j-1]) : Counter()) *
((j < m - 1) ? Math.abs(ca[i][j+1]) : Counter());
Так вот, тот код, который ты процитировал, функция Counter, как раз и делает эти 2 вещи: уменьшает число сомножителей, и возвращает 1, на которую домножается произведение. В результате выполнения всей строки у нас без всяких дополнительных "единичных границ" правильно считается произведение соседних элементов. А потом остается в извлечь корень нужной степени (степени Count), чтобы получить среднее геометрическое.


Спасибо Вам Большое за помощь give_rose.gif
Если Вам не трудно, объясните Пожалуйста, почему у нас не получится решить задачу с добавлением единичной границы? для крайних элементов соседи будут какие-то числа и две единицы, а так как мы умножаем, то по сути ничего не меняем и множителя будет 4...
IUnknown
Цитата
а так как мы умножаем, то по сути ничего не меняем и множителя будет 4...
А на самом деле их должно быть 2, а не 4 для угловых элементов, и 3 для тех, которые на границе. Понимаешь разницу? Смотри: вот тебе пример: матрица 5*5:
11 15 12 13 14
17 2 3 5 12
15 8 10 1 11
30 7 9 2 20
29 27 25 23 22

Меня интересуют, в частности, выделенные элементы. В твоем случае перемножили по 4 соседних, и произведение для элемента равного 11 получилось 1*1*15*17=255, а для второго, равного 15: 1*11*12*2=264. И у меня то же самое (15*17=255 и 11*12*2=264). Только в твоем случае и там и там 4 множителя, значит извлекать ты будешь корень четвертой степени, и получишь 3 и 4 соответственно, а я в первом случае извлеку квадратный корень из 255 (и получу 15), а во втором - кубический из 264 (и получу 6).

А поскольку изначально никакой "единичной границы" в матрице не было - то мой вариант ближе к истине: у 11 просто нет четырех соседей, есть всего 2. А у 15-ти есть только 3, а не 4 соседа...
Shashlyk
Цитата(IUnknown @ 3.06.2011 22:07) *

А на самом деле их должно быть 2, а не 4 для угловых элементов, и 3 для тех, которые на границе. Понимаешь разницу? Смотри: вот тебе пример: матрица 5*5:
11 15 12 13 14
17 2 3 5 12
15 8 10 1 11
30 7 9 2 20
29 27 25 23 22

Меня интересуют, в частности, выделенные элементы. В твоем случае перемножили по 4 соседних, и произведение для элемента равного 11 получилось 1*1*15*17=255, а для второго, равного 15: 1*11*12*2=264. И у меня то же самое (15*17=255 и 11*12*2=264). Только в твоем случае и там и там 4 множителя, значит извлекать ты будешь корень четвертой степени, и получишь 3 и 4 соответственно, а я в первом случае извлеку квадратный корень из 255 (и получу 15), а во втором - кубический из 264 (и получу 6).

А поскольку изначально никакой "единичной границы" в матрице не было - то мой вариант ближе к истине: у 11 просто нет четырех соседей, есть всего 2. А у 15-ти есть только 3, а не 4 соседа...

Спасибо Вам Большое!!! от души give_rose.gif
Shashlyk
Цитата(IUnknown @ 3.06.2011 22:07) *

А на самом деле их должно быть 2, а не 4 для угловых элементов, и 3 для тех, которые на границе. Понимаешь разницу? Смотри: вот тебе пример: матрица 5*5:
11 15 12 13 14
17 2 3 5 12
15 8 10 1 11
30 7 9 2 20
29 27 25 23 22

Меня интересуют, в частности, выделенные элементы. В твоем случае перемножили по 4 соседних, и произведение для элемента равного 11 получилось 1*1*15*17=255, а для второго, равного 15: 1*11*12*2=264. И у меня то же самое (15*17=255 и 11*12*2=264). Только в твоем случае и там и там 4 множителя, значит извлекать ты будешь корень четвертой степени, и получишь 3 и 4 соответственно, а я в первом случае извлеку квадратный корень из 255 (и получу 15), а во втором - кубический из 264 (и получу 6).

А поскольку изначально никакой "единичной границы" в матрице не было - то мой вариант ближе к истине: у 11 просто нет четырех соседей, есть всего 2. А у 15-ти есть только 3, а не 4 соседа...


Почему-то выдаёт ошибку:
xception in thread "main" java.util.IllegalFormatConversionException: f != java.lang.Integer
IUnknown
Цитата
Почему-то выдаёт ошибку:
Тебе что, опять скриншот с NetBeans показать? Пойми уже, я сначала проверяю, потом- выкладываю. Если не работает - я не пишу в тему, вот и все...
Shashlyk
Цитата(IUnknown @ 4.06.2011 0:12) *

Тебе что, опять скриншот с NetBeans показать? Пойми уже, я сначала проверяю, потом- выкладываю. Если не работает - я не пишу в тему, вот и все...

Извините, где-то я наверное ошибку допустил...
Если Вам не сложно, помогите Пожалуйста с предыдущим моим топиком в этом разделе (про игру в футбол). Не хочет контест почему-то воспринимать задачу как бы я ни старался(
Lapp
Цитата(Shashlyk @ 4.06.2011 7:36) *
Извините, где-то я наверное ошибку допустил...
Если Вам не сложно, помогите Пожалуйста с предыдущим моим топиком в этом разделе (про игру в футбол). Не хочет контест почему-то воспринимать задачу как бы я ни старался(

Ну и почему ты пишешь в ЭТОЙ теме?? blink.gif типа - та несчастливая? так, что ли?

Напиши, в ТУ тему и выложи там свой вариант. Тогда будет разговор..
Shashlyk
Цитата(IUnknown @ 3.06.2011 11:14) *

Я бы не стал менять на экспоненту с логарифмом. Pow прекрасно справляется с задачей. Единственное, что я бы сделал - это убрал бы добавление . Вот так:

        public static int Count;

int Counter() {
Count -= 1;
return 1;
}

void Action() {
int [][] ca = new int [n][m];
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) ca[i][j] = a[i][j];

for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
Count = 4;
int Product = ((i > 0) ? Math.abs(ca[i-1][j]) : Counter()) *
((i < n - 1) ? Math.abs(ca[i+1][j]) : Counter()) *
((j > 0) ? Math.abs(ca[i][j-1]) : Counter()) *
((j < m - 1) ? Math.abs(ca[i][j+1]) : Counter());
int SrGeom = (int)Math.pow(Product, 1.0 / Count); // Вычисляем правильное значение
a[i][j] = SrGeom;
}
}
}
, у тебя среднее геометрическое вычисляется неверно. Если ты перемножал 2 элемента - то и корень должен быть квадратный, а не 4-ой степени. В твоем варианте значения на граничных элементах будут меньше, чем нужно.



Скажите Пожалуйста, а как учесть ещё и "диагональные соседи" при подсчёте ?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.