📄 nn.c
字号:
i = 0;
while ((ch2 >= '0' && ch2 <='9') || ch2 == '+' || ch2 == '-' ||
ch2 == 'e' || ch2 == 'E' || ch2 == '.')
{
outstr[i] = ch2;
i = i+1;
ch2 = readch();
};
outstr[i] = 0;
bufferptr = bufferptr - 1;
numread = sscanf(outstr,"%lf",&number);
if (numread == 0)
{
pg("bad real value\n");
readerror = 1;
return(0.0);
};
number = sign * number;
if (op == GT && number > min) return(number);
else if (op == GE && number >= min) return(number);
else
{
sprintf(outstr,"erroneous value: %f",number); pg(outstr);
if (data == stdin) pg("\n");
else {sprintf(outstr," in %c command\n",command); pg(outstr);};
readerror = 1;
return(0.0);
};
}
REAL readchar() /* reads data in compressed format */
{
int ch2;
readerror = 0;
ch2 = readch();
do {
switch (ch2) {
case '\n':
case ' ': ch2 = readch();
break;
case '1': return(1.0);
case '0': return(0.0);
case '*': do ch2 = readch(); while(ch2 != '\n');
break;
case EOF: readerror = 2;
return(0.0);
default: texterror(566);
readerror = 1;
return(0.0);};
} while (0 == 0);
}
void clearalist(thelist)
NODE *thelist;
{
NODE *list, *lastnode;
REAL *vec;
list = thelist;
while (list != NULL)
{
vec = list->vector;
free(vec);
lastnode = list;
list = list->next;
free(lastnode);
};
thelist = NULL;
}
NODE *readpats(thefile,thelist)
char *thefile;
NODE *thelist;
{
NODE *list, *lastnode, *newnode;
REAL *vec, *newvector;
int j;
FILE *patterns;
if (!pushfile(thefile)) return(NULL);
/* dispose of the old list, if there is one */
if (thelist != NULL) clearalist(thelist);
/* set up an unused node at the beginning */
list = (NODE *) malloc(sizeof(NODE));
lastnode = list;
lastnode->next = NULL;
listcount = 0;
/* read in the patterns */
ch = readch();
while (ch != EOF)
{
if (ch != '*')
{
listcount = listcount + 1;
newnode = (NODE *) malloc(sizeof(NODE));
newvector = (REAL *) malloc(sizeof(REAL) * length);
newnode->vector = newvector;
newnode->next = NULL;
newnode->nn = 0;
lastnode->next = newnode;
bufferptr = bufferptr - 1;
for (j=1;j<=length;j++)
{
*newvector++ = readreal(GE,-MAXVAL,'r');
if (readerror)
{
sprintf(outstr,"read error, pattern %d\n",listcount);
pg(outstr);
goto endsbad;
};
};
newnode->class = readint(1,nclasses,'r');
if (readerror) goto endsbad;
lastnode = newnode;
};
do ch = readch(); while (ch != '\n');
ch = readch();
};
fclose(data);
popfile();
thelist = list->next;
free(list);
return(thelist);
endsbad:
fclose(data);
popfile();
if (list != NULL) clearalist(thelist);
return(NULL);
}
void saveweights(fn)
char *fn;
{
NODE *p;
REAL *vec;
int j;
FILE *f;
f = fopen(fn,"w");
if (f == NULL)
{
sprintf(outstr,"cannot open: %s\n",fn); pg(outstr);
return;
};
p = protolist;
while (p != NULL)
{
vec = p->vector;
for (j=1;j<=length;j++) fprintf(f," %f\n",*vec++);
fprintf(f," %d\n",p->class);
p = p->next;
};
fclose(f);
}
void knn(NODE *known, NODE *unknown) /* k nearest neighbor */
{
register REAL sum;
register REAL diff;
register REAL *uvec;
register REAL *pvec;
PAT *p, *dummy, *end, *c, *nextc;
int i, j, ipct, pointnumber;
short pattern,large,place,m,right,wrong,answer,rtanswer;
REAL pct;
INT32 *addr;
NODE *u, *protopoint, *pointptr;
right = 0;
wrong = 0;
addr = errmat;
for (i=0;i<=errmatsize-1;i++) *addr++ = 0;
/* free any nodes that have already been used */
c = closest;
while (c != NULL) {nextc = c->next; free(c); c = nextc;};
/* create the list that contains the closest values */
pg("working ...\n");
closest = (PAT *) malloc(sizeof(PAT));
closest->distsq = -1.0;
closest->point = NULL;
p = closest;
for (i=1;i<=k;i++)
{
c = (PAT *) malloc(sizeof(PAT));
p->next = c;
c->next = NULL;
p = c;
};
end = c;
/* find the k closest neighbors */
pointnumber = 0;
u = unknown;
while (u != NULL)
{
c = closest->next;
while (c != NULL)
{
c->distsq = MAXVAL;
c->point = NULL;
c = c->next;
};
protopoint = known;
while (protopoint != NULL)
{
pvec = protopoint->vector;
uvec = u->vector;
if (pvec != uvec)
{
sum = 0.0;
for (j=1;j<=length;j++)
{
diff = *uvec++ - *pvec++;
sum = sum + diff * diff;
};
/* if this point is closer than the farthest, move this pattern in */
/* sprintf(outstr,"%f %f\n",sum,end->distsq); pg(outstr); */
if (sum < end->distsq)
{
c = closest->next;
while (c != NULL && sum > c->distsq) c = c->next;
if (c == end)
{
c->distsq = sum;
c->point = protopoint;
}
else
{
end->point = c->point;
end->distsq = c->distsq;
end->next = c->next;
c->distsq = sum;
c->next = end;
c->point = protopoint;
c = end->next;
while (c->next != end) c = c->next;
c->next = NULL;
end = c;
};
}; /* end if sum < */
}; /* end if uvec != pvec */
protopoint = protopoint->next;
}; /* end while protopoint */
if (k == 1)
{
pointptr = end->point;
answer = pointptr->class;
/* sprintf(outstr,"%x %x %d\n",end,pointptr,answer); pg(outstr); */
}
else
{
addr = votes;
for (m=0;m<=nclasses;m++) *addr++ = 0;
c = closest->next;
while (c != NULL)
{
pointptr = c->point;
answer = pointptr->class;
*(votes + answer) = *(votes + answer) + 1;
c = c->next;
};
large = *(votes + 1);
place = 1;
for (m=2;m<=nclasses;m++)
if (*(votes + m) > large)
{
large = *(votes + m);
place = m;
};
answer = place;
}; /* end else */
rtanswer = u->class;
if (answer == rtanswer) right = right + 1; else wrong = wrong + 1;
addr = errmat + (answer - 1) * (nclasses + 1) + rtanswer;
*addr = *addr + 1;
if (summary == '-')
{
uvec = u->vector;
pointnumber = pointnumber + 1;
sprintf(outstr,"%5d",pointnumber);
pg(outstr);
for (j=1;j<=length;j++)
{
sprintf(outstr,"%7.3lf ",*uvec++);
pg(outstr);
};
sprintf(outstr,"%5d ",answer);
pg(outstr);
if (answer == rtanswer) j = pg("ok\n"); else j = pg("\n");
if (j) return;
};
#ifndef UNIX
if (kbhit() && getch() == 27) return;
#endif
u = u->next;
}; /* end while u */
stats:
if (unknown == blank)
{
sprintf(outstr,"answer = %d\n",answer); pg(outstr);
return;
};
addr = errtotal;
for (i=0;i<=nclasses;i++) *addr++ = 0;
for (i=1;i<=nclasses;i++)
{
sum = 0;
for (j=1;j<=nclasses;j++)
{
addr = errmat + (i - 1) * (nclasses + 1) + j;
sum = sum + *addr;
};
*(errtotal + i) = sum;
};
pg(" ");
for (i=1;i<=nclasses;i++) {sprintf(outstr,"%3d",i); pg(outstr);};
pg("\n");
for (i=1;i<=nclasses;i++)
{
sprintf(outstr,"%3d",i); pg(outstr);
for (j=1;j<=nclasses;j++)
{
addr = errmat + (i - 1) * (nclasses + 1) + j;
if (*(errtotal + i) == 0) pg(" *");
else
{
ipct = (*addr * 100.0) / *(errtotal + i) + 0.5;
sprintf(outstr,"%3d",ipct); pg(outstr);
};
};
pg("\n");
};
pg(" ");
for (i=1;i<=nclasses;i++) {sprintf(outstr,"%3d",i); pg(outstr);};
pg("\n\n");
pct = 100.0 * right / (right + wrong);
sprintf(outstr,"pct = %8.4f right = %d wrong = %d\n",pct,right,wrong);
pg(outstr);
}
void cluster(int class, NODE *list)
{
register REAL dist, sum, *cvec, *patvec;
register REAL min, old, maxdistsq;
register int i,j,classcount;
CPAT *cl, *prev, *new, *closest, *cluster, *dump;
NODE *pattern;
create = 0;
maxdistsq = maxdist * maxdist;
cl = clusterstart->next;
while (cl != NULL)
{
cl->count = 0;
cl = cl->next;
};
pattern = list;
classcount = 0;
while (pattern != NULL)
/* if (pattern->class != class || pattern->nn) */
if (pattern->class != class) pattern = pattern->next;
else
{
classcount = classcount + 1;
cluster = clusterstart->next;
min = MAXVAL;
while (cluster != NULL)
{
patvec = pattern->vector;
cvec = cluster->vector;
sum = 0.0;
for (i=1;i<=length;i++)
{
dist = *patvec++ - *cvec++;
sum = sum + dist * dist;
};
if (sum < min)
{
closest = cluster;
min = sum;
};
cluster = cluster->next;
};
if (min > maxdistsq)
{
create = create + 1;
count = count + 1;
cl = clusterstart->next;
new = (CPAT *) malloc(sizeof(CPAT));
clusterstart->next = new;
new->next = cl;
new->count = 1;
cvec = (REAL *) malloc(sizeof(REAL) * length);
new->vector = cvec;
patvec = pattern->vector;
for (i=1;i<=length;i++) *cvec++ = *patvec++;
}
else
{
closest->count = closest->count + 1;
cvec = closest->vector;
patvec = pattern->vector;
for (i=1;i<=length;i++)
{
old = *cvec;
*cvec = oneminus * old + lambda * *patvec++;
cvec++;
};
};
pattern = pattern->next;
};
destroy = 0;
prev = clusterstart;
cl = prev->next;
while (cl != NULL)
if (cl->count == 0 || cl->count < (fract * classcount))
{
destroy = destroy + 1;
count = count - 1;
dump = cl;
prev->next = cl->next;
cl = cl->next;
free(dump->vector);
free(dump);
}
else
{
prev = cl;
cl = cl->next;
};
}
void clusterall(NODE *list)
{
int class, pass, i;
NODE *p, *dummy, *oldprotolist;
CPAT *cl, *cnext;
REAL *cvec, *patvec;
nprotos = 0;
oldprotolist = protolist;
dummy = (NODE *) malloc(sizeof(NODE));
dummy->next = NULL;
if (clusterstart == NULL)
{
clusterstart = (CPAT *) malloc(sizeof(CPAT));
clusterstart->next = NULL;
cvec = (REAL *) malloc(sizeof(REAL) * length);
for (i=1;i<=length;i++) *cvec++ = MAXVAL;
};
for (class=1;class<=nclasses;class++)
{
/* printf("class %d\n",class); */
#ifndef UNIX
interrupt(814);
#endif
cl = clusterstart->next;
while (cl != NULL) {cnext = cl->next; free(cl); cl = cnext;};
clusterstart->next = NULL;
count = 0;
maxpasses = 10;
pass = 0;
create = 1;
destroy = 1;
unstable = 1;
lambda = initiallambda;
while (pass <= maxpasses && (unstable || pass < 3))
{
oneminus = 1.0 - lambda;
cluster(class,list);
/* printf("pass %d\n",pass); */
unstable = create + destroy;
pass = pass + 1;
lambda = lambda / 2.0;
#ifndef UNIX
interrupt(833);
#endif
};
nprotos = nprotos + count;
sprintf(outstr,"pattern %d has %d clusters\n",class,count);
pg(outstr);
/* at this point copy over to prototypes */
cl = clusterstart->next;
while (cl != NULL)
{
p = (NODE *) malloc(sizeof(NODE));
p->vector = cl->vector;
p->class = class;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -