Форум на Kuban.ru (http://forums.kuban.ru/)
-   Разработка программ (http://forums.kuban.ru/f1024/)
-   -   Помогите с СИ (http://forums.kuban.ru/f1024/pomogite_s_si-3302044.html)

DAVIDnovicheeeeek 13.11.2012 21:57

Помогите с СИ
 
Ребята, подскажите неопытному, почему криво выдает ответ?

[IMG]http://s42.radikal.ru/i098/1211/7d/7626c1ad50c2.png[/IMG]


Задача тривиальная. На вход подается матрица, методом Гауса она приводится к треугольному виду, а дальше вот чаво...

Вот код:
#include<stdio.h>

int main ()
**
int i,j,n,k;
float c;
float a[10][10];
printf("n= ");
scanf("%d \n", &n);
for (i=0; i<n; i++)
**
for (j=0; j<n; j++)
**
scanf("%f", &a[i][j]);
**
printf("\n");
**



for (i=0; i<n-1; i++)
**
for (j=i+1; j<n; j++)
**
c=- a[j][i]/a[i][i];
for (k=0; k<n; k++)
**
a[j][k]=a[j][k]+c*a[i][k];
**
**

**

for (i=0; i<n; i++)
**
for (j=0; j<n; j++)
**
printf("%-10f", a[i][j]);
**
printf("\n");
**



scanf("%d", &i);
**

TVV1 14.11.2012 04:07

[code]
#include <stdio.h>
#include <stdlib.h>

#define EPS 0.000001
#define MAX_SIZE 10

float mas[MAX_SIZE][MAX_SIZE] =
**{5,5,6,8,9**, {5,5,8,9,6**, {4,5,6,2,8**, {4,5,6,6,9**, {5,8,9,6,7****;
//**{25,24,23,22,21**, {34,43,4,33,33**, {34,43,33,54,15**, {16,17,18,19,20**, {21,22,23,24,28****;

void print_mas(int size, int mark_row)
**
int row,col;

for (row=0; row < size; row++)
**
printf("%c", (row != mark_row) ?' ':'*');
for (col=0; col<size; col++)
**
printf("%10.3f", mas[row][col]);
**
printf("\n");
**
printf("\n");
**

int main(void)
**

int size; // Размер матрицы
int row,s_row,col;
int max_val_row; // Номер строки с максимальным значением в колонке
float max_val; // Максимальное значение в колонке
float swap_val; // Переменная для хранения значения при перемещении строк матрицы
float k; // Множитель для строки

size=5;
// Тут можно накатать ввод значений матрицы, а так для удобства используем значения по умолчанию


printf("initial matrix\n");
print_mas(size, size);

for (row=1; row < size; row++)
**
printf("find max cell value for col %d\n", row-1);
max_val=mas[row-1][row-1];
max_val_row=row-1;
for (s_row=row; s_row < size; s_row++)
if (max_val < mas[s_row][row-1])
**
max_val=mas[s_row][row-1];
max_val_row=s_row;
**

if (max_val < EPS)
**
printf("error underflow");
return 1;
**

if (max_val_row != row-1)
**
printf("swap rows %d and %d\n", row-1, max_val_row);
for (col=0; col < size; col++)
**
swap_val=mas[row-1][col];
mas[row-1][col]=mas[max_val_row][col];
mas[max_val_row][col]=swap_val;
**
print_mas(size, size);
**
else
printf("skip swap rows\n");

for (s_row=row; s_row < size; s_row++)
**
k=mas[s_row][row-1]/max_val;
for (col=row-1; col < size; col++)
**
mas[s_row][col]-=k*mas[row-1][col];
**

printf("s_row=%d, k=%.3f\n", s_row, k);
print_mas(size, s_row);
**
**

printf("final matrix\n");
print_mas(size, size);


return 0;
**
[/code]

TVV1 14.11.2012 04:08

результат
[code]
initial matrix
5.000 5.000 6.000 8.000 9.000
5.000 5.000 8.000 9.000 6.000
4.000 5.000 6.000 2.000 8.000
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

find max cell value for col 0
skip swap rows
s_row=1, k=1.000
5.000 5.000 6.000 8.000 9.000
* 0.000 0.000 2.000 1.000 -3.000
4.000 5.000 6.000 2.000 8.000
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

s_row=2, k=0.800
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
* -0.000 1.000 1.200 -4.400 0.800
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

s_row=3, k=0.800
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
-0.000 1.000 1.200 -4.400 0.800
* -0.000 1.000 1.200 -0.400 1.800
5.000 8.000 9.000 6.000 7.000

s_row=4, k=1.000
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
-0.000 1.000 1.200 -4.400 0.800
-0.000 1.000 1.200 -0.400 1.800
* 0.000 3.000 3.000 -2.000 -2.000

find max cell value for col 1
swap rows 1 and 4
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 1.000 1.200 -4.400 0.800
-0.000 1.000 1.200 -0.400 1.800
0.000 0.000 2.000 1.000 -3.000

s_row=2, k=0.333
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
* -0.000 0.000 0.200 -3.733 1.467
-0.000 1.000 1.200 -0.400 1.800
0.000 0.000 2.000 1.000 -3.000

s_row=3, k=0.333
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 0.000 0.200 -3.733 1.467
* -0.000 0.000 0.200 0.267 2.467
0.000 0.000 2.000 1.000 -3.000

s_row=4, k=0.000
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 0.000 0.200 -3.733 1.467
-0.000 0.000 0.200 0.267 2.467
* 0.000 0.000 2.000 1.000 -3.000

find max cell value for col 2
swap rows 2 and 4
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.200 0.267 2.467
-0.000 0.000 0.200 -3.733 1.467

s_row=3, k=0.100
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
* -0.000 0.000 0.000 0.167 2.767
-0.000 0.000 0.200 -3.733 1.467

s_row=4, k=0.100
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 0.167 2.767
* -0.000 0.000 0.000 -3.833 1.767

find max cell value for col 3
skip swap rows
s_row=4, k=-23.000
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 0.167 2.767
* -0.000 0.000 0.000 0.000 65.400

final matrix
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 0.167 2.767
-0.000 0.000 0.000 0.000 65.400
[/code]

TVV1 14.11.2012 04:16

да это я еще при поиске максимального значения в колонке что то накосячил там нужно брать по модулю
[code]
#include <stdio.h>
#include <stdlib.h>

#define EPS 0.000001
#define MAX_SIZE 10

float mas[MAX_SIZE][MAX_SIZE] =
**{5,5,6,8,9**, {5,5,8,9,6**, {4,5,6,2,8**, {4,5,6,6,9**, {5,8,9,6,7****;
//**{25,24,23,22,21**, {34,43,4,33,33**, {34,43,33,54,15**, {16,17,18,19,20**, {21,22,23,24,28****;

void print_mas(int size, int mark_row)
**
int row,col;

for (row=0; row < size; row++)
**
printf("%c", (row != mark_row) ?' ':'*');
for (col=0; col<size; col++)
**
printf("%10.3f", mas[row][col]);
**
printf("\n");
**
printf("\n");
**

int main(void)
**

int size; // Размер матрицы
int row,s_row,col;
int max_val_row; // Номер строки с максимальным значением в колонке
float max_val; // Максимальное значение в колонке
float swap_val; // Переменная для хранения значения при перемещении строк матрицы
float k; // Множитель для строки

size=5;
// Тут можно накатать ввод значений матрицы, а так для удобства используем значения по умолчанию


printf("initial matrix\n");
print_mas(size, size);

for (row=1; row < size; row++)
**
printf("find max cell value for col %d\n", row-1);
max_val=abs(mas[row-1][row-1]);
max_val_row=row-1;
for (s_row=row; s_row < size; s_row++)
if (max_val < abs(mas[s_row][row-1]))
**
max_val=abs(mas[s_row][row-1]);
max_val_row=s_row;
**

if (max_val < EPS)
**
printf("error underflow");
return 1;
**

if (max_val_row != row-1)
**
printf("swap rows %d and %d\n", row-1, max_val_row);
for (col=0; col < size; col++)
**
swap_val=mas[row-1][col];
mas[row-1][col]=mas[max_val_row][col];
mas[max_val_row][col]=swap_val;
**
print_mas(size, size);
**
else
printf("skip swap rows\n");

for (s_row=row; s_row < size; s_row++)
**
k=mas[s_row][row-1]/mas[row-1][row-1];
for (col=row-1; col < size; col++)
**
mas[s_row][col]-=k*mas[row-1][col];
**

printf("s_row=%d, k=%.3f\n", s_row, k);
print_mas(size, s_row);
**
**

printf("final matrix\n");
print_mas(size, size);


return 0;
**





initial matrix
5.000 5.000 6.000 8.000 9.000
5.000 5.000 8.000 9.000 6.000
4.000 5.000 6.000 2.000 8.000
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

find max cell value for col 0
skip swap rows
s_row=1, k=1.000
5.000 5.000 6.000 8.000 9.000
* 0.000 0.000 2.000 1.000 -3.000
4.000 5.000 6.000 2.000 8.000
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

s_row=2, k=0.800
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
* -0.000 1.000 1.200 -4.400 0.800
4.000 5.000 6.000 6.000 9.000
5.000 8.000 9.000 6.000 7.000

s_row=3, k=0.800
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
-0.000 1.000 1.200 -4.400 0.800
* -0.000 1.000 1.200 -0.400 1.800
5.000 8.000 9.000 6.000 7.000

s_row=4, k=1.000
5.000 5.000 6.000 8.000 9.000
0.000 0.000 2.000 1.000 -3.000
-0.000 1.000 1.200 -4.400 0.800
-0.000 1.000 1.200 -0.400 1.800
* 0.000 3.000 3.000 -2.000 -2.000

find max cell value for col 1
swap rows 1 and 4
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 1.000 1.200 -4.400 0.800
-0.000 1.000 1.200 -0.400 1.800
0.000 0.000 2.000 1.000 -3.000

s_row=2, k=0.333
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
* -0.000 0.000 0.200 -3.733 1.467
-0.000 1.000 1.200 -0.400 1.800
0.000 0.000 2.000 1.000 -3.000

s_row=3, k=0.333
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 0.000 0.200 -3.733 1.467
* -0.000 0.000 0.200 0.267 2.467
0.000 0.000 2.000 1.000 -3.000

s_row=4, k=0.000
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
-0.000 0.000 0.200 -3.733 1.467
-0.000 0.000 0.200 0.267 2.467
* 0.000 0.000 2.000 1.000 -3.000

find max cell value for col 2
swap rows 2 and 4
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.200 0.267 2.467
-0.000 0.000 0.200 -3.733 1.467

s_row=3, k=0.100
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
* -0.000 0.000 0.000 0.167 2.767
-0.000 0.000 0.200 -3.733 1.467

s_row=4, k=0.100
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 0.167 2.767
* -0.000 0.000 0.000 -3.833 1.767

find max cell value for col 3
swap rows 3 and 4
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 -3.833 1.767
-0.000 0.000 0.000 0.167 2.767

s_row=4, k=-0.043
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 -3.833 1.767
* -0.000 0.000 0.000 0.000 2.843

final matrix
5.000 5.000 6.000 8.000 9.000
0.000 3.000 3.000 -2.000 -2.000
0.000 0.000 2.000 1.000 -3.000
-0.000 0.000 0.000 -3.833 1.767
-0.000 0.000 0.000 0.000 2.843


[/code]

DAVIDnovicheeeeek 14.11.2012 08:27

1-TVV1 >за алгоритсм спасибо конечно, но я хочу поправить свой.

Проблема в том, что я не могу понять из-за чего он выводить такие каракули:(

TVV1 14.11.2012 12:15

Какой алгоритм, там же решение и подробный вывод по ходу преобразований что бы было понятно ;)
А у тебя нет поиска ведущего элемента, нет проверки деления на ноль ...

TVV1 14.11.2012 12:33

вот здесь есть лекция на эту тему правда автор что то очень мачкадом злоупотребляет
[url]http://iproc.ru/parallel-programming/lection-4/[/url]

DAVIDnovicheeeeek 15.11.2012 01:37

5-TVV1 >
Спасибо что откликнулся!:)

Я кусочек кода выложил, задача стоит гораздо сложнее:( Просто никак не мог разобраться откуда такие данные появляются:(

Как я понимаю, кривые значения типа #INDOO появляются при делении на ноль:( Странно, я думал компилятор предупреждает о таких вещах, а вот нет:(

Надир 16.11.2012 01:57

Я уже подзабыл кое-что из языка С, но есть некоторое соображение по предложенной проблеме. Попробуйте сделать два изменения:
1. Объяыить массив float a[10][10] глобальным, т.е., описать его до main
2. Заменить команду scanf("%f", &a[i][j]);
двумя командами
scanf("%f", &c);
a[i][j]=c;
Я могу заблуждаться, но мне как-то помнится, что массив - это уже указатель, а с командой-вводом scanf были какие-то осбенности - для массива вроде бы не нужно ставить команду взятия адреса &, что-то такое припоминается. Чтобы от этого развязаться, вот те две команды и обеспечат заведомо правильный ввод. А описание массива глобальным опеспечит его инициализацию нулями, исключит всякий мусор в массиве, который может и не отражать никак правильный, нормализованный вид вещественных чисел.
Если ввод в Вашем начальном коде был неверным, не заполнял всего массива (а Вы не сделали распечатки массива после ввода, до его преобразования), то после преобразования что-то подобное и могло отображаться.
Не мешало бы сделать ещё одно изменение, касающееся вывода - хотя бы так, как предагает TVV1
3. printf("%10.3f", [i][j]);

Надир 16.11.2012 02:00

ох, вот так
3. printf("%10.3f", a[i][j]);

Дядя Миша 01.12.2012 11:38

Автор ты уверен, что n <= 10 ?
Ты может вообще лезешь за пределы массива.
[code]
c=-
[/code]
где начальная инициализация c?

Дядя Миша 01.12.2012 11:44

И эта. У тебя там идут в цикле операции сложения значений из массива с самим собой. Где гарантия, что примерно на середине итерации туда не запишется хрень?
Делай еще одну копию массива и сохраняй результат туда.
Ну и проверка на 0 тоже нужна.
[code]
a[j][i]/a[i][i];
[/code]
вот здесь.

05772 18.01.2013 01:03

Золотые правила:
1 в численных методах использовать двойную точность.
2 для теста брать матрицу, у которой можно точно получить треугольную. Берешь учебник по ЧМ и ищешь пример.

chignon 20.01.2013 19:58

Невооруженным глазом видно, что матрица кривая:
5 5 . .
5 5 . .
. . . .
И естественно после первого прохода будет пара нулей, а в третьем деление на ноль.
Какое еще может быть после этого обсуждение - непонятно.
Кошмар.

TVV1 20.01.2013 22:10

to13 А то что строки можно переставлять не слышали?
И то, что эта матрица приводится таки к треугольному виду не читали.


Текущее время: 06:46. Часовой пояс GMT +3.