me ayudais a entender que pone aqui por favor?
Publicado por Nelek (816 intervenciones) el 17/08/2006 11:16:49
Hola, esta va a ser una de las ultimas veces que postee pidiendo ayuda para mi proyecto. Solo me falta presentar los datos en la pantalla de salida y ya lo he acabado. La cosa está en que no tengo claro como hacerlo porque en la teoría sobre "lógica fuzzy" (en concreto el método "Center of Gravity"), hay diferentes metódicas según autores. El problema es que casi siempre usan integrales y funciones pero... como que eso no concuerda con los ejemplos prácticos que he visto. Voy a comentar un poco el funcionamiento de mi programa y a poner un ejemplo que me han dado en la empresa de un simulador similar hecho en C pero que no acabo de entender y es dónde pido la ayuda. (Lo siento por la longitud del mensaje).
El funcionamiento de mi simulador de sistemas es relativamente simple.
Una pantalla donde se pueden establecer varias entradas, reguladores y salidas. Las entradas se pueden conectar a varios reguladores y varios reguladores pueden tener multiples entradas conectadas. Entre regulador y salida la relación es ÚNICA (un reg una salida, una salida un reg). Cada Salida tiene ciertos Atributos, funciones de Y = X (lineas verticales) y un "punto de trabajo" en dichos attributos que depende de las entradas y reguladores, ademas de UN Valor de Salida que depende de dichos puntos de trabajo en los atributos (el valor de salida se calcula con el "center of gravity" aplicado a los puntos de trabajo de los atributos).
En las Entradas se tienen dos tipos (Y = X o Y = MX+N) de atributos, pero esto no es relevante para mi pregunta, lo unico que aquí interesa es el valor de la Y segun el punto de trabajo de la entrada está en un sitio u otro.
La cosa está en que... según las relaciones que se especifican en el regulador. Los puntos de trabajo en los atributos de salida toman el VALOR MAXIMO DE TODOS LOS VALORES MINIMOS que afectan al funcionamiento de dicho atributo en la salida. Hasta aqui lo tengo todo claro, ya programado y funciona.
El problema viene ahora, una vez tengo los Atributos en las rectas Y=X y un punto de trabajo concreto en Y1 = MAX (MIN1, MIN2, ... MINn). Como diantres saco el valor de la salida?
El ejemplo en C que me han pasado en la empresa es el siguiente. Me interesa entender sobretodo el CENTER OF GRAVITIY (y lo que pueda ser relevante para su funcionamiento). Alguien me explicar que se está haciendo? he intentado descifrarlo pero me hago un lio. Más o menos me hago una idea, pero me gustaría que alguien con más nivel que yo me contestara. Gracias por adelantado, sé que no es algo sencillo lo que pido.
/*
* psim.c
* Frank Neubauer, 1994
*
* This module contains the Fuzzy-Simulationloop
*/
#include <stdio.h>
#include <string.h>
#include "psim.h"
#define HEADER_SIZE (9*4)
typedef struct {
VALUE x,y;
double d,s;
} Point;
typedef enum {
OP_END = 0x00,
OP_CLEAR = 0x01,
OP_FUZZYFYINT = 0x10,
OP_DEFUZZYINT_COG = 0x20,
OP_WEIGHT = 0x30,
OP_MIN = 0x31,
OP_MAX = 0x32
} OPCODE;
typedef BYTE* (*CODEPROC)(BYTE*);
static BYTE* OP_Clear( BYTE * pMem );
static BYTE* OP_FuzzifyInt( BYTE * pMem );
static BYTE* OP_Weight( BYTE * pMem );
static BYTE* OP_Min( BYTE * pMem );
static BYTE* OP_Max( BYTE * pMem );
static BYTE* OP_DefuzzyIntCOG( BYTE * pMem );
typedef struct {
OPCODE Opcode;
CODEPROC CodeProc;
} CODEENTRY;
static CODEENTRY OpcodeTab[] = {
{ OP_CLEAR, OP_Clear },
{ OP_FUZZYFYINT, OP_FuzzifyInt },
{ OP_DEFUZZYINT_COG, OP_DefuzzyIntCOG },
{ OP_WEIGHT, OP_Weight },
{ OP_MIN, OP_Min },
{ OP_MAX, OP_Max },
{ OP_END, NULL }
};
static unsigned yResolution;
static BYTE *pCode, *pCodeStart;
static BYTE *pData, *pDataStart;
static BYTE *pVariables;
static VALUE AccuVal;
static size_t InVarCount, OutVarCount;
static VALUE
fi( register VALUE x, register const BYTE * p )
{
if( x < p[1] ) {
if( x <= p[0] ) return 0;
if( p[5] == 0 ) return (x - p[0]) * p[4];
return (VALUE) (((((x - p[0]) * (unsigned) p[4]) >> (p[5] - 1)) + 1) >> 1);
}
if( x <= p[2] ) return (yResolution-1);
if( x >= p[3] ) return 0;
if( p[7] == 0 ) return (p[3] - x) * p[6];
return (VALUE) (((((p[3] - x) * (unsigned) p[6]) >> (p[7] - 1)) + 1) >> 1);
}
/*
* OP_Clear
*/
static BYTE* OP_Clear( BYTE * pMem )
{
int index;
index = (int) *pMem++;
pVariables[index] = 0;
return pMem;
}
/*
* OP_FuzzifyInt
*/
static BYTE* OP_FuzzifyInt( BYTE * pMem )
{
int varindex, memberindex;
varindex = (int) *pMem++;
memberindex = (int) *pMem++;
pVariables[memberindex] = fi( pVariables[varindex], pData );
pData += 8;
return pMem;
}
/*
* OP_Weight
*/
static BYTE* OP_Weight( BYTE * pMem )
{
AccuVal = (VALUE) (((int) AccuVal * *pData++) / 256);
return pMem;
}
/*
* OP_Min
*/
static BYTE* OP_Min( BYTE * pMem )
{
int index, number;
VALUE Value;
number = (int) *pMem++;
AccuVal = yResolution - 1;
while( number-- > 0 ) {
index = (int) *pMem++;
Value = pVariables[index];
if( Value < AccuVal ) AccuVal = Value;
}
return pMem;
}
/*
* OP_Max
*/
static BYTE* OP_Max( BYTE * pMem )
{
int index, number;
index = (int) *pMem++;
if( pVariables[index] < AccuVal ) pVariables[index] = AccuVal;
return pMem;
}
/*
* OP_DefuzzyIntCOG
*/
static BYTE* OP_DefuzzyIntCOG( BYTE * pMem )
{
int varindex, memberindex, number;
unsigned long Numerator = 0, Denominator = 0, Value;
varindex = (int) *pMem++;
number = (int) *pMem++;
while( number-- > 0 ) {
memberindex = (int) *pMem++;
Value = pVariables[memberindex];
Numerator += Value * *pData++;
Denominator += Value;
}
if( Denominator != 0 ) pVariables[varindex] = Numerator / Denominator;
return pMem;
}
/*
* FuzzyEvaluate
*/
BOOL FuzzyEvaluate( VALUE * InVars, VALUE * OutVars)
{
OPCODE Opcode;
CODEENTRY *CodeEntry;
pCode = pCodeStart;
pData = pDataStart;
memcpy( &pVariables[0], InVars, InVarCount );
while( (Opcode = (OPCODE) *pCode++) != OP_END ) {
for( CodeEntry = OpcodeTab; CodeEntry->Opcode != OP_END; CodeEntry++ )
if( CodeEntry->Opcode == Opcode )
break;
if( CodeEntry->CodeProc == NULL ) {
printf( "Unbekannter Operator %02X\n", Opcode );
return FALSE;
}
if( (pCode = CodeEntry->CodeProc( pCode )) == NULL )
return FALSE;
}
#if 0
printf( "%3d %3d %3d\t%3d %3d %3d %3d\t",
pVariables[4], pVariables[5], pVariables[6], pVariables[7],
pVariables[8], pVariables[9], pVariables[10] );
// printf( "%3d %3d %3d %3d\t", pVariables[11], pVariables[12], pVariables[13], pVariables[14
] );
#endif
memcpy( OutVars, &pVariables[InVarCount], OutVarCount );
return TRUE;
}
/*
* ReadLong
*/
static BYTE *ReadLong( BYTE * pMem, unsigned long * pLong )
{
*pLong = (unsigned long) *pMem++;
*pLong += ((unsigned long) *pMem++) << 8;
*pLong += ((unsigned long) *pMem++) << 16;
*pLong += ((unsigned long) *pMem++) << 24;
return pMem;
}
/*
* FuzzyInit
*/
BOOL FuzzyInit( BYTE * pMem, size_t MemLen )
{
BYTE *pMemStart = pMem;
unsigned long Magic, Version;
unsigned long CodeLen, DataLen, VarLen, PrivateLen;
unsigned long nInVars, nOutVars, yRes;
pMem = ReadLong( pMem, &Magic );
pMem = ReadLong( pMem, &Version );
pMem = ReadLong( pMem, &CodeLen );
pMem = ReadLong( pMem, &DataLen );
pMem = ReadLong( pMem, &VarLen );
pMem = ReadLong( pMem, &PrivateLen );
pMem = ReadLong( pMem, &nInVars );
pMem = ReadLong( pMem, &nOutVars );
pMem = ReadLong( pMem, &yRes );
pCodeStart = pMem;
pDataStart = pCodeStart + CodeLen;
pVariables = pDataStart + DataLen;
if( HEADER_SIZE + CodeLen + DataLen + VarLen > MemLen ) {
printf( "Der Speicher reicht nicht aus\n" );
return FALSE;
}
InVarCount = (size_t) nInVars;
OutVarCount = (size_t) nOutVars;
yResolution = (unsigned) yRes;
memset( pVariables, 0, (size_t) VarLen );
return TRUE;
}
/*
* FuzzyTerminate
*/
void FuzzyTerminate()
{}
El funcionamiento de mi simulador de sistemas es relativamente simple.
Una pantalla donde se pueden establecer varias entradas, reguladores y salidas. Las entradas se pueden conectar a varios reguladores y varios reguladores pueden tener multiples entradas conectadas. Entre regulador y salida la relación es ÚNICA (un reg una salida, una salida un reg). Cada Salida tiene ciertos Atributos, funciones de Y = X (lineas verticales) y un "punto de trabajo" en dichos attributos que depende de las entradas y reguladores, ademas de UN Valor de Salida que depende de dichos puntos de trabajo en los atributos (el valor de salida se calcula con el "center of gravity" aplicado a los puntos de trabajo de los atributos).
En las Entradas se tienen dos tipos (Y = X o Y = MX+N) de atributos, pero esto no es relevante para mi pregunta, lo unico que aquí interesa es el valor de la Y segun el punto de trabajo de la entrada está en un sitio u otro.
La cosa está en que... según las relaciones que se especifican en el regulador. Los puntos de trabajo en los atributos de salida toman el VALOR MAXIMO DE TODOS LOS VALORES MINIMOS que afectan al funcionamiento de dicho atributo en la salida. Hasta aqui lo tengo todo claro, ya programado y funciona.
El problema viene ahora, una vez tengo los Atributos en las rectas Y=X y un punto de trabajo concreto en Y1 = MAX (MIN1, MIN2, ... MINn). Como diantres saco el valor de la salida?
El ejemplo en C que me han pasado en la empresa es el siguiente. Me interesa entender sobretodo el CENTER OF GRAVITIY (y lo que pueda ser relevante para su funcionamiento). Alguien me explicar que se está haciendo? he intentado descifrarlo pero me hago un lio. Más o menos me hago una idea, pero me gustaría que alguien con más nivel que yo me contestara. Gracias por adelantado, sé que no es algo sencillo lo que pido.
/*
* psim.c
* Frank Neubauer, 1994
*
* This module contains the Fuzzy-Simulationloop
*/
#include <stdio.h>
#include <string.h>
#include "psim.h"
#define HEADER_SIZE (9*4)
typedef struct {
VALUE x,y;
double d,s;
} Point;
typedef enum {
OP_END = 0x00,
OP_CLEAR = 0x01,
OP_FUZZYFYINT = 0x10,
OP_DEFUZZYINT_COG = 0x20,
OP_WEIGHT = 0x30,
OP_MIN = 0x31,
OP_MAX = 0x32
} OPCODE;
typedef BYTE* (*CODEPROC)(BYTE*);
static BYTE* OP_Clear( BYTE * pMem );
static BYTE* OP_FuzzifyInt( BYTE * pMem );
static BYTE* OP_Weight( BYTE * pMem );
static BYTE* OP_Min( BYTE * pMem );
static BYTE* OP_Max( BYTE * pMem );
static BYTE* OP_DefuzzyIntCOG( BYTE * pMem );
typedef struct {
OPCODE Opcode;
CODEPROC CodeProc;
} CODEENTRY;
static CODEENTRY OpcodeTab[] = {
{ OP_CLEAR, OP_Clear },
{ OP_FUZZYFYINT, OP_FuzzifyInt },
{ OP_DEFUZZYINT_COG, OP_DefuzzyIntCOG },
{ OP_WEIGHT, OP_Weight },
{ OP_MIN, OP_Min },
{ OP_MAX, OP_Max },
{ OP_END, NULL }
};
static unsigned yResolution;
static BYTE *pCode, *pCodeStart;
static BYTE *pData, *pDataStart;
static BYTE *pVariables;
static VALUE AccuVal;
static size_t InVarCount, OutVarCount;
static VALUE
fi( register VALUE x, register const BYTE * p )
{
if( x < p[1] ) {
if( x <= p[0] ) return 0;
if( p[5] == 0 ) return (x - p[0]) * p[4];
return (VALUE) (((((x - p[0]) * (unsigned) p[4]) >> (p[5] - 1)) + 1) >> 1);
}
if( x <= p[2] ) return (yResolution-1);
if( x >= p[3] ) return 0;
if( p[7] == 0 ) return (p[3] - x) * p[6];
return (VALUE) (((((p[3] - x) * (unsigned) p[6]) >> (p[7] - 1)) + 1) >> 1);
}
/*
* OP_Clear
*/
static BYTE* OP_Clear( BYTE * pMem )
{
int index;
index = (int) *pMem++;
pVariables[index] = 0;
return pMem;
}
/*
* OP_FuzzifyInt
*/
static BYTE* OP_FuzzifyInt( BYTE * pMem )
{
int varindex, memberindex;
varindex = (int) *pMem++;
memberindex = (int) *pMem++;
pVariables[memberindex] = fi( pVariables[varindex], pData );
pData += 8;
return pMem;
}
/*
* OP_Weight
*/
static BYTE* OP_Weight( BYTE * pMem )
{
AccuVal = (VALUE) (((int) AccuVal * *pData++) / 256);
return pMem;
}
/*
* OP_Min
*/
static BYTE* OP_Min( BYTE * pMem )
{
int index, number;
VALUE Value;
number = (int) *pMem++;
AccuVal = yResolution - 1;
while( number-- > 0 ) {
index = (int) *pMem++;
Value = pVariables[index];
if( Value < AccuVal ) AccuVal = Value;
}
return pMem;
}
/*
* OP_Max
*/
static BYTE* OP_Max( BYTE * pMem )
{
int index, number;
index = (int) *pMem++;
if( pVariables[index] < AccuVal ) pVariables[index] = AccuVal;
return pMem;
}
/*
* OP_DefuzzyIntCOG
*/
static BYTE* OP_DefuzzyIntCOG( BYTE * pMem )
{
int varindex, memberindex, number;
unsigned long Numerator = 0, Denominator = 0, Value;
varindex = (int) *pMem++;
number = (int) *pMem++;
while( number-- > 0 ) {
memberindex = (int) *pMem++;
Value = pVariables[memberindex];
Numerator += Value * *pData++;
Denominator += Value;
}
if( Denominator != 0 ) pVariables[varindex] = Numerator / Denominator;
return pMem;
}
/*
* FuzzyEvaluate
*/
BOOL FuzzyEvaluate( VALUE * InVars, VALUE * OutVars)
{
OPCODE Opcode;
CODEENTRY *CodeEntry;
pCode = pCodeStart;
pData = pDataStart;
memcpy( &pVariables[0], InVars, InVarCount );
while( (Opcode = (OPCODE) *pCode++) != OP_END ) {
for( CodeEntry = OpcodeTab; CodeEntry->Opcode != OP_END; CodeEntry++ )
if( CodeEntry->Opcode == Opcode )
break;
if( CodeEntry->CodeProc == NULL ) {
printf( "Unbekannter Operator %02X\n", Opcode );
return FALSE;
}
if( (pCode = CodeEntry->CodeProc( pCode )) == NULL )
return FALSE;
}
#if 0
printf( "%3d %3d %3d\t%3d %3d %3d %3d\t",
pVariables[4], pVariables[5], pVariables[6], pVariables[7],
pVariables[8], pVariables[9], pVariables[10] );
// printf( "%3d %3d %3d %3d\t", pVariables[11], pVariables[12], pVariables[13], pVariables[14
] );
#endif
memcpy( OutVars, &pVariables[InVarCount], OutVarCount );
return TRUE;
}
/*
* ReadLong
*/
static BYTE *ReadLong( BYTE * pMem, unsigned long * pLong )
{
*pLong = (unsigned long) *pMem++;
*pLong += ((unsigned long) *pMem++) << 8;
*pLong += ((unsigned long) *pMem++) << 16;
*pLong += ((unsigned long) *pMem++) << 24;
return pMem;
}
/*
* FuzzyInit
*/
BOOL FuzzyInit( BYTE * pMem, size_t MemLen )
{
BYTE *pMemStart = pMem;
unsigned long Magic, Version;
unsigned long CodeLen, DataLen, VarLen, PrivateLen;
unsigned long nInVars, nOutVars, yRes;
pMem = ReadLong( pMem, &Magic );
pMem = ReadLong( pMem, &Version );
pMem = ReadLong( pMem, &CodeLen );
pMem = ReadLong( pMem, &DataLen );
pMem = ReadLong( pMem, &VarLen );
pMem = ReadLong( pMem, &PrivateLen );
pMem = ReadLong( pMem, &nInVars );
pMem = ReadLong( pMem, &nOutVars );
pMem = ReadLong( pMem, &yRes );
pCodeStart = pMem;
pDataStart = pCodeStart + CodeLen;
pVariables = pDataStart + DataLen;
if( HEADER_SIZE + CodeLen + DataLen + VarLen > MemLen ) {
printf( "Der Speicher reicht nicht aus\n" );
return FALSE;
}
InVarCount = (size_t) nInVars;
OutVarCount = (size_t) nOutVars;
yResolution = (unsigned) yRes;
memset( pVariables, 0, (size_t) VarLen );
return TRUE;
}
/*
* FuzzyTerminate
*/
void FuzzyTerminate()
{}
Valora esta pregunta


0