英文:
Sort Structs by the value of an attribute in it
问题
我的问题是,当我尝试对一个名为ann的结构体列表进行排序时,如下所示:
typedef struct ann {
int inputs; /* 输入神经元数量 /
int hidden_layers; / 隐藏层数量 /
int hidden; / 隐藏神经元数量 /
int outputs; / 输出神经元数量 /
int weights; / 总权重(染色体)数量 /
int neurons; / 总神经元数量 */
double weight; / 权重(基因型) */
double output; / 输出 /
double fitness; / 网络的总适应度 */
double delta;
actfun activation_hidden; / 隐藏层激活函数 /
actfun activation_output; / 输出层激活函数 */
} ann;
qsort不改变顺序
这是我的实际代码
ann *population = malloc ( population_size * sizeof(ann));
for( i = 0; i < population_size; i++ ){
population[i] = create( trainset->num_inputs, 1 , hidden, trainset->num_outputs);
}
qsort( population, population_size, sizeof(ann), compareAnn);
int compareAnn(const void* a, const void* b)
{
const ann* pa = (const ann*)a;
const ann* pb = (const ann*)b;
return pa->fitness - pb->fitness;
}
此外,这是create()函数
ann *create ( int inputs, int hidden_layers, int hidden, int outputs ) {
const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0;
const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs;
const int total_weights = (hidden_weights + output_weights);
const int total_neurons = (inputs + hidden * hidden_layers + outputs);
/* 为权重、输出和delta分配额外空间。 */
const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
ann *ret = malloc(size);
if (!ret) return 0;
ret->inputs = inputs;
ret->hidden_layers = hidden_layers;
ret->hidden = hidden;
ret->outputs = outputs;
ret->weights = total_weights;
ret->neurons = total_neurons;
/* 设置指针。 */
ret->weight = (double*)((char*)ret + sizeof(ann));
ret->output = ret->weight + ret->weights;
ret->delta = ret->output + ret->neurons;
return ret;
}
我明白这可能是微不足道的,但我已经尝试了很多方法,似乎无法解决它,而且我已经花了很多小时尝试修复它,任何帮助都将是伟大的,提前感谢所有人。
英文:
i am trying to sort a struct by the value of a double attrib in it, kind of like this
#include <stdio.h>
#include <stdlib.h>
double arr[] = {1.023, 1.22, 1.56, 2, 5, 3.331};
int cmp(const void *x, const void *y)
{
double xx = *(double*)x, yy = *(double*)y;
if (xx < yy) return -1;
if (xx > yy) return 1;
return 0;
}
int main() {
qsort(arr, sizeof(arr)/sizeof(arr[0]), sizeof(arr[0]), cmp);
}
My issue is when i try to sort a list of struct named ann as shown below
typedef struct ann {
int inputs; /* Number of input neurones */
int hidden_layers; /* Number of hidden layers */
int hidden; /* Number of hidden neurones */
int outputs; /* Number of output neurons. */
int weights; /* Total nof weigths(chromosomes)*/
int neurons; /* Total Number of neurones */
double *weight; /* The weights(genotype) */
double *output; /* Output */
double fitness; /* Total fitness of the network */
double *delta;
actfun activation_hidden; /* Hidden layer activation func */
actfun activation_output; /* Output layer activation func */
} ann;
qsort does not alter the order
here is my actual code
ann **population = malloc ( population_size * sizeof(ann*));
for( i = 0; i < population_size; i++ ){
population[i] = create( trainset->num_inputs, 1 , hidden, trainset->num_outputs);
}
qsort( population, population_size, sizeof(ann), compareAnn);
int compareAnn(const void* a, const void* b)
{
const ann* pa = (const ann*)a;
const ann* pb = (const ann*)b;
return pa->fitness - pb->fitness;
}
Also here is the create() function
ann *create ( int inputs, int hidden_layers, int hidden, int outputs ) {
const int hidden_weights = hidden_layers ? (inputs+1) * hidden + (hidden_layers-1) * (hidden+1) * hidden : 0;
const int output_weights = (hidden_layers ? (hidden+1) : (inputs+1)) * outputs;
const int total_weights = (hidden_weights + output_weights);
const int total_neurons = (inputs + hidden * hidden_layers + outputs);
/* Allocate extra size for weights, outputs, and deltas. */
const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
ann *ret = malloc(size);
if (!ret) return 0;
ret->inputs = inputs;
ret->hidden_layers = hidden_layers;
ret->hidden = hidden;
ret->outputs = outputs;
ret->weights = total_weights;
ret->neurons = total_neurons;
/* Set pointers. */
ret->weight = (double*)((char*)ret + sizeof(ann));
ret->output = ret->weight + ret->weights;
ret->delta = ret->output + ret->neurons;
return ret;
}
I understand this may be trivial, but i have tried to do this in so many ways and i cant seem to figure it out, and i have spend many many hours trying to fix it already, and any help will be great, thanks to all in advance.
答案1
得分: 3
变量population
的类型是ann **
。分配的数组中的每个元素的类型是ann *
。因此,应该像这样调用函数qsort
:
qsort(population, population_size, sizeof(ann *), compareAnn);
在比较函数中,您应该写如下代码:
int compareAnn(const void* a, const void* b)
{
const ann* pa = *(const ann **)a;
const ann* pb = *(const ann **)b;
return (pb->fitness < pa->fitness) - (pa->fitness - pb->fitness);
}
请注意返回语句。否则,将double
类型的差异转换为int
类型的返回语句可能会产生意外的结果:
return pa->fitness - pb->fitness;
此外,这个内存分配代码:
const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
ann *ret = malloc(size);
是没有意义的。要么分配与sizeof(ann)
相等大小的内存,要么使用另一个封装ann
结构的结构。
以下是一个演示性程序:
#include <stdio.h>
#include <stdlib.h>
struct A
{
double x;
};
int cmp(const void *a, const void *b)
{
const struct A *left = *(const struct A **)a;
const struct A *right = *(const struct A **)b;
return (right->x < left->x) - (left->x < right->x);
}
int main(void)
{
size_t n = 10;
struct A **a = malloc(n * sizeof(struct A *));
for (size_t i = 0; i < n; i++)
{
a[i] = malloc(sizeof(struct A));
a[i]->x = (double)(n - i) / n;
}
for (size_t i = 0; i < n; i++)
printf("%.1f ", a[i]->x);
putchar('\n');
qsort(a, n, sizeof(struct A *), cmp);
for (size_t i = 0; i < n; i++)
printf("%.1f ", a[i]->x);
putchar('\n');
for (size_t i = 0; i < n; i++)
free(a[i]);
free(a);
return 0;
}
其输出是:
1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
英文:
The variable population
has the type ann **
. Each element of the allocated array has the type ann *
.So the function qsort
should be called like
qsort( population, population_size, sizeof( ann * ), compareAnn );
Within the comparison function you should write
int compareAnn(const void* a, const void* b)
{
const ann* pa = *( const ann ** )a;
const ann* pb = *( const ann ** )b;
return ( pb->fitness < pa->fitness ) - ( pa->fitness - pb->fitness );
}
Pay attention to the return statement. Otherwise the difference of doubles in the return statement converted to the type int
can produce an unexpected result.
return pa->fitness - pb->fitness;
Also this memory allocation
const int size = sizeof(ann) + sizeof(double) * (total_weights + total_neurons + (total_neurons - inputs));
ann *ret = malloc(size);
does not make sense. Either allocate a memory of the size equal to sizeof( ann )
or use another structure that encloses the structure ann.
Here is a demonstrative program.
#include <stdio.h>
#include <stdlib.h>
struct A
{
double x;
};
int cmp( const void *a, const void *b )
{
const struct A *left = *( const struct A ** )a;
const struct A *right = *( const struct A ** )b;
return ( right->x < left->x ) - ( left->x < right->x );
}
int main(void)
{
size_t n = 10;
struct A **a = malloc( n * sizeof( struct A * ) );
for ( size_t i = 0; i < n; i++ )
{
a[i] = malloc( sizeof( struct A ) );
a[i]->x = ( double )( n - i ) / n;
}
for ( size_t i = 0; i < n; i++ ) printf( "%.1f ", a[i]->x );
putchar( '\n' );
qsort( a, n, sizeof( struct A * ), cmp );
for ( size_t i = 0; i < n; i++ ) printf( "%.1f ", a[i]->x );
putchar( '\n' );
for ( size_t i = 0; i < n; i++ ) free( a[i] );
free( a );
return 0;
}
Its output is
1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1
0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论