Почему эта программа не работает?
// это программа для поиска манипулятора в кинематике. мои сомнения не в кинезе:-). Моя программа выполняется, но всегда печатает "позиция недоступна", даже для известного значения, она делает то же самое. здесь я использовал радианы для углов, так как это то, что c понимает. Пожалуйста, скажите мне, как с этим сталкиваться или даже скажите мне лучший способ для реализации этого. Спасибо.// Теперь эта отредактированная программа работает, но она работает медленно... Может кто-нибудь PLZ предложить способ оптимизировать это?
#include<stdio.h>
#include<math.h>
#include<conio.h>
int main()
{
float a, b, c, d;
int a1, b1, c1, d1;
int x = 0, y = 0, z = 0;
int x1 = 0, y1 = 0, z1 = 0;
int i = 0, j = 0;
printf("Enter X value: \n");
scanf("%d", &x);
printf("Enter Y value: \n");
scanf("%d", &y);
printf("Enter Z value: \n");
scanf("%d", &z);
for (a1 = -100 ; a1 <= 100 ; a1++)
{
printf("%d \t", j++);
for (b1 = 0; b1 <= 180; b1++)
{
for (c1 = -100; c1 <= 100; c1++)
{
for (d1 = -45; d1 <= 45; d1++)
{
a = a1 * 0.0174532925;
b = b1 * 0.0174532925;
c = c1 * 0.0174532925;
d = d1 * 0.0174532925;
x1 = (11*cos(d+c+b+a)+11*cos(d+c+b-a)+12*cos(c+b+a)+12*cos(c+b-a)+9*cos(b+a)+9*cos(b-a))/2;
if(x1 == x)
{
y1 =(11*sin(d+c+b+a)-11*sin(d+c+b-a)+12*sin(c+b+a)-12*sin(c+b-a)+9*sin(b+a)-9*sin(b-a))/2;
if(y1 == y)
{
z1 = 11*sin(d+c+b) + 12*sin(c+b) + 9*sin(b);
if(z1 == z)
{
i = 1;
goto status;
}
}
}
}
}
}
}
status:
if(i == 0)
printf("*****Positon unacheivable*****");
else
printf(" The joint angles for the desired positon are \n %d \t %d \t %d \t %d \n", a1, b1, c1, d1);
getch();
}
3 ответа
Прочитайте это сначала или во-вторых, но прочитайте это: Что каждый ученый должен знать об арифметике с плавающей точкой
0,02 не представляется точно на большинстве компьютеров. Будет представлен примерно. В вашем цикле, каждый раз, когда вы добавляете приблизительно 0,02, ваша ошибка округления растет и растет.
Вы просили об оптимизации скорости:
у тебя есть
for (a...)
for (b..)
for (c...)
for (d...)
...
11*cos(d+c+b+a) + 9*cos(b+a) + 12*cos(c+b+a)
...
лучше бы
for (a...)
for (b..)
mybpa = 9*cos(b+a)
for (c...)
mycpbpa = 12*cos(c+b+a)
for (d...)
mydpcpbpa = 11*cos(d+c+b+a)
...
mydpcpbpa + mycpbpa + mybpa
...
поэтому вы делаете трудоемкие вычисления как можно раньше. Вы должны рассчитать все эти значения, когда они достигнут уровня, чтобы они не изменились больше в следующем цикле. Вы должны даже сделать промежуточные итоги 9*cos(b+a)+9*cos(b-a)
как только они не меняются
Вот простой алгоритм восхождения на холм. Он начинается с a=b=c=d=0, измеряет расстояние до требуемых x,y,z, а затем вносит небольшие случайные корректировки в a,b,c,d и сохраняет те, которые улучшают расстояние.
Он будет работать вечно, за исключением редких случаев, когда найдено точное совпадение; вам решать выбрать условие остановки. Кроме того, вы должны установить границы случайности, если это необходимо, чтобы предотвратить выбор значений a,b,c,d, выходящих за допустимый диапазон, так как мне было лень это вводить.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
static double getdist(double x, double y, double z,
double a, double b, double c, double d)
{
double x1, y1, z1;
x1 = (11*cos(d+c+b+a)+11*cos(d+c+b-a)+12*cos(c+b+a)+12*cos(c+b-a)+9*cos(b+a)+9*cos(b-a))/2;
y1 = (11*sin(d+c+b+a)-11*sin(d+c+b-a)+12*sin(c+b+a)-12*sin(c+b-a)+9*sin(b+a)-9*sin(b-a))/2;
z1 = 11*sin(d+c+b) + 12*sin(c+b) + 9*sin(b);
return (x1-x)*(x1-x) + (y1-y)*(y1-y) + (z1-z)*(z1-z);
}
int main(int argc, char **argv)
{
char *end;
double x, y, z, a, b, c, d, dist, best;
if(argc != 4) {
fprintf(stderr, "Usage: %s x y z\n", argv[0]);
return EXIT_FAILURE;
}
x = strtod(argv[1], &end);
if(*end || !*argv[1]) {
fprintf(stderr, "x value %s is not a number\n", argv[1]);
return EXIT_FAILURE;
}
y = strtod(argv[2], &end);
if(*end || !*argv[2]) {
fprintf(stderr, "y value %s is not a number\n", argv[2]);
return EXIT_FAILURE;
}
z = strtod(argv[3], &end);
if(*end || !*argv[3]) {
fprintf(stderr, "z value %s is not a number\n", argv[3]);
return EXIT_FAILURE;
}
a = b = c = d = 0;
best = getdist(x,y,z,a,b,c,d);
printf("a=%f b=%f c=%f d=%f (dist=%f)\n", a, b, c, d, sqrt(best));
srand(time(0));
while(best) {
double save_a, save_b, save_c, save_d;
save_a = a;
save_b = b;
save_c = c;
save_d = d;
a += rand()*1./RAND_MAX*.02 - .01;
b += rand()*1./RAND_MAX*.02 - .01;
c += rand()*1./RAND_MAX*.02 - .01;
d += rand()*1./RAND_MAX*.02 - .01;
dist = getdist(x,y,z,a,b,c,d);
if(dist < best) {
best = dist;
printf("a=%f b=%f c=%f d=%f (dist=%f)\n", a, b, c, d, sqrt(best));
} else {
a = save_a;
b = save_b;
c = save_c;
d = save_d;
}
}
return 0;
}