Skip to content

Commit 5b321aa

Browse files
authored
Merge pull request #19 from firefly-cpp/new-version
New version, fixed bugs, added PSO solver
2 parents 5042d7d + e9b337e commit 5b321aa

22 files changed

+790
-137
lines changed

makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ ifeq ($(DEBUG), 1)
55
CXXFLAGS := $(CXXFLAGS) -O0 -g3 -Wall -fmessage-length=0
66
endif
77

8-
SRCS = ./sources/Archive.cpp ./sources/Attribute.cpp ./sources/DESolver.cpp ./sources/Evaluate.cpp ./sources/Feature.cpp ./sources/Problem.cpp ./sources/Rule.cpp ./sources/Setup.cpp ./sources/Squash.cpp ./sources/uARMSolver.cpp
8+
SRCS = ./sources/Archive.cpp ./sources/Attribute.cpp ./sources/DESolver.cpp ./sources/Evaluate.cpp ./sources/Feature.cpp ./sources/Problem.cpp ./sources/Particle.h ./sources/PSOSolver.h ./sources/Rule.cpp ./sources/Setup.cpp ./sources/stat.cpp ./sources/Squash.cpp ./sources/uARMSolver.cpp
99

10-
DEPS = ./Archive.d ./Attribute.d ./DESolver.d ./Evaluate.d ./Feature.d ./Problem.d ./Rule.d ./Setup.d ./Squash.d ./uARMSolver.d
10+
DEPS = ./Archive.d ./Attribute.d ./DESolver.d ./Evaluate.d ./Feature.d ./Problem.d ./Particle.d ./PSOSolver.d ./Rule.d ./Setup.d ./stat.d ./Squash.d ./uARMSolver.d
1111

12-
OBJS = ./Archive.o ./Attribute.o ./DESolver.o ./Evaluate.o ./Feature.o ./Problem.o ./Rule.o ./Setup.o ./Squash.o ./uARMSolver.o
12+
OBJS = ./Archive.o ./Attribute.o ./DESolver.o ./Evaluate.o ./Feature.o ./Problem.o ./Particle.o ./PSOSolver.o ./Rule.o ./Setup.o ./stat.o ./Squash.o ./uARMSolver.o
1313

1414
all: bin/uARMSolver
1515

sources/Archive.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef ARCHIVE_H_
2-
#define ARCHIVE_H_
1+
#ifndef SOURCES_ARCHIVE_H_
2+
#define SOURCES_ARCHIVE_H_
33

44
#include <stdio.h>
55
#include <math.h>
@@ -52,4 +52,4 @@ class Archive {
5252

5353
bool compare(Rule one, Rule two);
5454

55-
#endif /* ARCHIVE_H_ */
55+
#endif /* SOURCES_ARCHIVE_H_ */

sources/Attribute.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ void Attribute::enter(int item)
3030
*/
3131
void Attribute::enter(double item)
3232
{
33+
present = true;
34+
if(type == ATTR_NUMERICAL) {
35+
present = false;
36+
cout << "Exception: Type= " << type << " must be changed to " << ATTR_REAL_VALUED << endl;
37+
}
3338
type = ATTR_REAL_VALUED;
3439
f_val = item;
35-
present = true;
3640
}
3741

3842
/**

sources/Attribute.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef ATTRIBUTE_H_
2-
#define ATTRIBUTE_H_
1+
#ifndef SOURCES_ATTRIBUTE_H_
2+
#define SOURCES_ATTRIBUTE_H_
33

44
#include <iostream>
55
#include <algorithm>
@@ -41,4 +41,4 @@ class Attribute {
4141
string s_val;
4242
};
4343

44-
#endif /* ATTRIBUTE_H_ */
44+
#endif /* SOURCES_ATTRIBUTE_H_ */

sources/DESolver.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ DESolver::~DESolver(void)
6262
* @param DE mutation strategy, scale factor, and crossover probability algorithm's parameters.
6363
* @return no return code.
6464
*/
65-
void DESolver::Setup(int deStrategy, double diffScale, double crossoverProb)
65+
void DESolver::Setup(int deStrategy, double diffScale, double crossoverProb, int n_intervals)
6666
{
6767
int i;
6868

6969
strategy = deStrategy;
7070
scale = diffScale;
7171
probability = crossoverProb;
72+
intervals = n_intervals;
7273
cout << "Initialisation of population..." << endl;
7374
for (i=0; i < nPop; i++)
7475
{
@@ -148,7 +149,7 @@ cout << "generation= " << generation << endl;
148149
{
149150
Rule rule;
150151
(this->*calcTrialSolution)(candidate);
151-
trialEnergy = eval.EnergyFunction(trialSolution, prob, rule);
152+
trialEnergy = eval.EnergyFunction(trialSolution, prob, rule, intervals);
152153
if (trialEnergy > popEnergy[candidate])
153154
{
154155
// New low for this candidate

sources/DESolver.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class DESolver
5555

5656
// Setup() must be called before solve to set min, max, strategy etc.
5757
// void Setup(double min[],double max[],int deStrategy, double diffScale,double crossoverProb);
58-
void Setup(int strategy, double scale, double xover);
58+
void Setup(int strategy, double scale, double xover, int n_intervals);
5959
// Solve() returns true if EnergyFunction() returns true.
6060
// Otherwise it runs maxGenerations generations and returns false.
6161
void Evolve(int run, int maxFEs, Archive &rules);
@@ -66,6 +66,7 @@ class DESolver
6666
int Dimension(void) { return(nDim); }
6767
int Population(void) { return(nPop); }
6868
int Generations(void) { return(generations); }
69+
double GetBestEnergy() { return bestEnergy; }
6970

7071
protected:
7172
void SelectSamples(int candidate,int *r1,int *r2=0,int *r3=0, int *r4=0,int *r5=0);
@@ -76,6 +77,7 @@ class DESolver
7677
int nPop;
7778
int generations;
7879
int strategy;
80+
int intervals;
7981

8082
double scale;
8183
double probability;

sources/Evaluate.cpp

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ Evaluate::~Evaluate()
2626
* @param the trial vector, the problem definition, and the mined association rule.
2727
* @return double return code: the calculated fitness value.
2828
*/
29-
double Evaluate::EnergyFunction(vector<double> x, Problem prob, Rule &rule)
29+
double Evaluate::EnergyFunction(vector<double> x, Problem prob, Rule &rule, int intervals)
3030
{
3131
double result = 0;
3232

33-
decode(x, prob.feat, rule);
33+
decode(x, prob.feat, rule, intervals);
3434

3535
if(rule.isValid()) {
3636
rule.set_support(prob.calc_support(rule));
@@ -72,7 +72,7 @@ int Evaluate::encode(int D, Problem prob)
7272
* @param the real-valued vector, the list of features, and the mined association rule.
7373
* @return no return code.
7474
*/
75-
void Evaluate::decode(vector<double> x, vector<Feature> feat, Rule &rule)
75+
void Evaluate::decode(vector<double> x, vector<Feature> feat, Rule &rule, int intervals)
7676
{
7777
for(uint i=0;i<pointers.size();i++) {
7878
rule.init(i, x[pointers[i]]);
@@ -89,7 +89,9 @@ void Evaluate::decode(vector<double> x, vector<Feature> feat, Rule &rule)
8989
bool taken = false;
9090
int ptr = pointers[rule.perm[i]];
9191
string pair = feat[rule.perm[i]].f_name+"_";
92+
//cout << pair << ": Type= ";
9293
if(feat[rule.perm[i]].type == ATTR_CATEGORICAL) { // categorical attribute
94+
//cout << "CATEGORICAL" << endl;
9395
if(random01() < x[ptr+2]) {
9496
uint val = x[ptr+1]*feat[rule.perm[i]].hash.size();
9597
if(val == feat[rule.perm[i]].hash.size()) // fixed at 2.10.2020 by Fister Iztok
@@ -98,36 +100,71 @@ void Evaluate::decode(vector<double> x, vector<Feature> feat, Rule &rule)
98100
taken = true;
99101
}
100102
} else if(feat[rule.perm[i]].type == ATTR_NUMERICAL) { // numerical attribute
103+
//cout << "NUMERICAL" << endl;
101104
if (random01() < x[ptr + 3]) {
102105
int a, b;
106+
int Delta = feat[rule.perm[i]].i_num.upper - feat[rule.perm[i]].i_num.lower;
107+
// cout << "Delta= " << Delta << ", intervals= " << intervals;
108+
int delta = 0;
109+
if(intervals > 1)
110+
delta = Delta/intervals;
111+
// cout << ", delta= " << delta << endl;
112+
// decoding
103113
if (x[ptr + 1] > x[ptr + 2]) {
104-
a = (feat[rule.perm[i]].i_num.upper - feat[rule.perm[i]].i_num.lower) * x[ptr + 2] + feat[rule.perm[i]].i_num.lower;
105-
b = (feat[rule.perm[i]].i_num.upper - feat[rule.perm[i]].i_num.lower) * x[ptr + 1] + feat[rule.perm[i]].i_num.lower;
114+
a = Delta * x[ptr + 2] + feat[rule.perm[i]].i_num.lower;
115+
b = Delta * x[ptr + 1] + feat[rule.perm[i]].i_num.lower;
106116
} else {
107-
a = (feat[rule.perm[i]].i_num.upper - feat[rule.perm[i]].i_num.lower) * x[ptr + 1] + feat[rule.perm[i]].i_num.lower;
108-
b = (feat[rule.perm[i]].i_num.upper - feat[rule.perm[i]].i_num.lower) * x[ptr + 2] + feat[rule.perm[i]].i_num.lower;
117+
a = Delta * x[ptr + 1] + feat[rule.perm[i]].i_num.lower;
118+
b = Delta * x[ptr + 2] + feat[rule.perm[i]].i_num.lower;
109119
}
120+
// repairing
121+
if((delta >= 0) && ((b-a) > delta)) {
122+
// cout << "Repairing NUMERICAL: [" << a << "," << b << "] ==> ";
123+
b = a + delta;
124+
// cout << "[" << a << "," << b << "]." << endl;
125+
} else {
126+
// cout << "NO repairing NUMERICAL: [" << a << "," << b << "]." << endl;
127+
}
128+
// proceed
110129
char str_pom[256];
111130
sprintf(str_pom, "%d_%d", a, b);
112131
string attr(str_pom);
113132
pair.append(attr);
114133
taken = true;
115134
}
116135
} else {
136+
//cout << "FLOATING-POINT" << endl;
117137
if (random01() < x[ptr + 3]) {
118138
double a, b;
139+
double Delta = feat[rule.perm[i]].f_num.upper - feat[rule.perm[i]].f_num.lower;
140+
// cout << "Delta= " << Delta << ", intervals= " << intervals;
141+
double delta = 0;
142+
if(intervals > 1)
143+
delta = Delta/(double) intervals;
144+
// cout << ", delta= " << delta << endl;
145+
// decoding
119146
if (x[ptr + 1] > x[ptr + 2]) {
120-
a = (feat[rule.perm[i]].f_num.upper - feat[rule.perm[i]].f_num.lower) * x[ptr + 2] + feat[rule.perm[i]].f_num.lower;
121-
b = (feat[rule.perm[i]].f_num.upper - feat[rule.perm[i]].f_num.lower) * x[ptr + 1] + feat[rule.perm[i]].f_num.lower;
147+
a = Delta * x[ptr + 2] + feat[rule.perm[i]].f_num.lower;
148+
b = Delta * x[ptr + 1] + feat[rule.perm[i]].f_num.lower;
149+
} else {
150+
a = Delta * x[ptr + 1] + feat[rule.perm[i]].f_num.lower;
151+
b = Delta * x[ptr + 2] + feat[rule.perm[i]].f_num.lower;
152+
}
153+
// repairing
154+
if((delta >= 0) && ((b-a) > delta)) {
155+
// cout << "Repairing REAL: [" << a << "," << b << "] ==> ";
156+
b = a + delta;
157+
// cout << "[" << a << "," << b << "]." << endl;
122158
} else {
123-
a = (feat[rule.perm[i]].f_num.upper - feat[rule.perm[i]].f_num.lower) * x[ptr + 1] + feat[rule.perm[i]].f_num.lower;
124-
b = (feat[rule.perm[i]].f_num.upper - feat[rule.perm[i]].f_num.lower) * x[ptr + 2] + feat[rule.perm[i]].f_num.lower;
159+
// cout << "NO repairing REAL: [" << a << "," << b << "]." << endl;
125160
}
161+
// proceed
126162
char str_pom[256];
127163
sprintf(str_pom, "%.4f_%.4f", a, b);
128164
string attr(str_pom);
129165
pair.append(attr);
130166
taken = true;
167+
// cout << "Feature= " << pair << endl;
131168
}
132169
}
133170
if (taken) {
@@ -140,6 +177,7 @@ void Evaluate::decode(vector<double> x, vector<Feature> feat, Rule &rule)
140177
}
141178
}
142179
}
180+
// exit(-1);
143181
}
144182

145183
void Evaluate::print_vec(string str, vector<int>vec)

sources/Evaluate.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef EVALUATE_H_
2-
#define EVALUATE_H_
1+
#ifndef SOURCES_EVALUATE_H_
2+
#define SOURCES_EVALUATE_H_
33

44
#include <vector>
55

@@ -27,9 +27,9 @@ class Evaluate {
2727
Evaluate();
2828
~Evaluate();
2929

30-
double EnergyFunction(vector<double> x, Problem prob, Rule &rule);
30+
double EnergyFunction(vector<double> x, Problem prob, Rule &rule, int intervals);
3131
int encode(int D, Problem prob);
32-
void decode(vector<double> x, vector<Feature> feat, Rule &rule);
32+
void decode(vector<double> x, vector<Feature> feat, Rule &rule, int intervals);
3333
void sort(vector<int>&index, vector<double>&val);
3434

3535
void print_vec(string str, vector<int>vec);
@@ -40,4 +40,4 @@ class Evaluate {
4040
};
4141

4242

43-
#endif /* EVALUATE_H_ */
43+
#endif /* SOURCES_EVALUATE_H_ */

sources/Feature.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
#include "Attribute.h"
77

8-
#define uint unsigned int
9-
108
using namespace std;
119

1210
typedef struct {

sources/PSOSolver.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Swarm.cpp
3+
*
4+
* Created on: Jul 2, 2025
5+
* Author: iztok
6+
*/
7+
8+
9+
#include <algorithm>
10+
#include "PSOSolver.h"
11+
12+
13+
PSOSolver::PSOSolver(int dim, int popSize, Problem problem) : gBestFitness(0.0), nDim(dim), numParticles(popSize), inertia(0.9), social(0.1), cognitive(0.1) {
14+
prob = problem;
15+
dimension = eval.encode(dim, prob);
16+
particles.reserve(numParticles);
17+
}
18+
19+
PSOSolver::~PSOSolver(void) {
20+
particles.clear();
21+
gBestPosition.clear();
22+
}
23+
24+
void PSOSolver::Setup(double w, double c1, double c2, int n_intervals) {
25+
inertia = w;
26+
cognitive = c1;
27+
social = c2;
28+
intervals = n_intervals;
29+
for (int i = 0; i < numParticles; i++) {
30+
Particle row(dimension, inertia, cognitive, social);
31+
particles.push_back(row);
32+
gBestPosition.push_back(0.0);
33+
}
34+
}
35+
36+
void PSOSolver::optimize(int run, int maxFEs, Archive &rules) {
37+
int maxGenerations = maxFEs/numParticles; // determine maximum number of evaluation
38+
if((maxGenerations%numParticles) > 0)
39+
maxGenerations++;
40+
41+
gBestFitness = 0.0;
42+
// int i = 0;
43+
44+
for (int iter = 0; iter < maxGenerations; iter++) {
45+
cout << "generation= " << iter << endl;
46+
for (auto& particle : particles) {
47+
Rule rule;
48+
particle.fitness = eval.EnergyFunction(particle.position, prob, rule, intervals);
49+
//cout << "trial= " << ++i << " trialEnergy= " << particle.fitness << " vs. globalBestFitness" << gBestFitness << " ===> " << endl;
50+
51+
// determining the personal best solution
52+
if (particle.fitness > particle.pBestFitness) {
53+
particle.pBestFitness = particle.fitness;
54+
particle.pBestPosition = particle.position;
55+
rules.add(rule);
56+
57+
// determining the global best solotion
58+
if (particle.fitness > gBestFitness) {
59+
gBestFitness = particle.fitness;
60+
gBestPosition = particle.position;
61+
cout << "bestFitness= " << gBestFitness << " at " << iter << " generation." << endl;
62+
if(gBestFitness == 1.0)
63+
return;
64+
}
65+
}
66+
}
67+
// print_swarm();
68+
//exit(-1);
69+
for (auto& particle : particles) {
70+
particle.updateVelocity(gBestPosition);
71+
particle.updatePosition();
72+
}
73+
}
74+
}
75+
76+
void PSOSolver::print_swarm() {
77+
cout << "Print swarm:" << endl;
78+
for (int i = 0; i < numParticles; i++) {
79+
cout << "[" << i << "] : (";
80+
for(int j=0;j<dimension;j++) {
81+
cout << particles[i].position[j] << ",";
82+
}
83+
cout << ") --> fit= " << particles[i].fitness << endl;
84+
}
85+
}
86+

0 commit comments

Comments
 (0)