-
Notifications
You must be signed in to change notification settings - Fork 1
/
item.c
146 lines (116 loc) · 2.97 KB
/
item.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
////////////////////////////////////////////
//Definition and methods related to items and their restrictions
//Restrictions are defined at compile time,
//ie. every item has all restrictions
#include <stdlib.h>
#include <math.h>
#include <tgmath.h>
#include "assert.h"
#include "const.h"
#include "item.h"
#include "util.h"
void Item_init(struct Item* item)
{
//An item initializes with all values as 0
(*item) = (struct Item){0};
//restrictions is an array and should be 0-initialized
item->restrictions = calloc(sizeof(*item->restrictions), NUM_RESTRICTIONS);
//Except for its pheromone
item->pheromone = PHE_INIT;
#ifdef THREADED
pthread_mutex_init(&item->itemLock, NULL);
#endif
}
void Item_fin(struct Item* item)
{
free(item->restrictions);
#ifdef THREADED
pthread_mutex_destroy(&item->itemLock);
#endif
}
/**
* Returns the desirability based on value and the restrictions
* value / prod(restriction/restricition_range)
*/
Desirability get_desirability(Cost value, Restr *rest)
{
Desirability d = (Desirability)value;
for(RestrId i = 0; i < NUM_RESTRICTIONS; i++)
{
d = d / (rest[i] / cap_init[i]);
}
return d;
}
void Item_updatePdValue(struct Item *i)
{
i->pdValue = (PherDes)(
(Desirability)pow(i->desirability, DES_WEIGHT) *
(Pher)pow(i->pheromone, PHE_WEIGHT)
);
}
/**
* Randomizes an item's attributes
*/
void Item_rand(struct Item* i)
{
//Assuming seed was already initialized
i->value = (Cost)rand_int(MIN_VALUE, MAX_VALUE);
for(RestrId j = 0; j < NUM_RESTRICTIONS; j++)
{
i->restrictions[j] = (Restr)rand_double(MIN_REST[j], MAX_REST[j]);
}
//calc desirability
i->desirability = get_desirability(i->value, i->restrictions);
Item_updatePdValue(i);
}
inline Pher phMin(Pher a, Pher b){
return (a > b? b : a);
}
void Item_addPheromone(struct Item *i, Pher delta)
{
#ifdef THREADED
pthread_mutex_lock(&i->itemLock);
#endif
i->pheromone = phMin(i->pheromone + delta, PHE_MAX);
#ifdef THREADED
pthread_mutex_unlock(&i->itemLock);
#endif
}
void evapPheromones()
{
for(ItemId i = 0; i < NUM_ITEMS; i++)
{
Item_evapPheromone(&universe[i]);
}
}
int desire_order(const void* a, const void* b)
{
const struct Item* iA = (struct Item*)a;
const struct Item* iB = (struct Item*)b;
Restr rA = 0.0, rB = 0.0;
for(RestrId c = 0; c < NUM_RESTRICTIONS; c++)
{
rA += iA->restrictions[c];
rB += iB->restrictions[c];
}
return rA - rB;
}
//universe is the set of all items in the system
void create_universe()
{
universe = (struct Item*)malloc(sizeof(*universe) * NUM_ITEMS);
for(ItemId i = 0; i < NUM_ITEMS; i++)
{
Item_init(&universe[i]);
Item_rand(&universe[i]);
}
qsort(universe, NUM_ITEMS, sizeof(struct Item), desire_order);
}
void delete_universe()
{
for(ItemId i = 0; i < NUM_ITEMS; i++)
{
Item_fin(&universe[i]);
}
free(universe);
}