Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit dd16692

Browse files
committed
Change algorithm to be iterative instead of recursive
1 parent 73de61e commit dd16692

File tree

6 files changed

+79
-67
lines changed

6 files changed

+79
-67
lines changed

LinkedList.c

+17-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Creates a new empty linked list.
77
* @return a pointer to the new list.
88
*/
9-
LinkedList *createLinkedList(){
9+
LinkedList *createLinkedList() {
1010
LinkedList *list = malloc(sizeof(LinkedList));
1111
assertMemoryAllocation(list);
1212
list->length = 0;
@@ -18,7 +18,7 @@ LinkedList *createLinkedList(){
1818
* Does NOT free the pointers nodes are pointing to.
1919
* @param list a linked list.
2020
*/
21-
void freeLinkedList(LinkedList *list){
21+
void freeLinkedList(LinkedList *list) {
2222
LinkedListNode *temp;
2323
LinkedListNode *node = list->first;
2424
if (node != NULL) {
@@ -36,11 +36,11 @@ void freeLinkedList(LinkedList *list){
3636
* It also destroys every group in the list.
3737
* @param list a linked list, containing pointers to VerticesGroups.
3838
*/
39-
void deepFreeGroupList(LinkedList *groupList){
39+
void deepFreeGroupList(LinkedList *groupList) {
4040
LinkedListNode *node = groupList->first;
4141
VerticesGroup *group;
4242
int i;
43-
for(i = 0; i < groupList->length; ++i){
43+
for (i = 0; i < groupList->length; ++i) {
4444
group = node->pointer;
4545
freeVerticesGroup(group);
4646
node = node->next;
@@ -78,18 +78,19 @@ void *insertItem(LinkedList *list, void *pointer) {
7878
* @param list a linked list
7979
* @param item a LinkedListNode pointer to some item in 'list'.
8080
*/
81-
void removeItem(LinkedList *list, LinkedListNode *item){
81+
void removeItem(LinkedList *list, LinkedListNode *item) {
8282
LinkedListNode *oldPrev = item->prev;
83-
LinkedListNode *oldNext = item->next;
84-
if(list->length > 1){
85-
oldPrev->next = oldNext;
86-
oldNext->prev = oldPrev;
87-
free(item);
88-
list->length--;
89-
}
90-
else if(list->length == 1){
91-
free(item);
92-
list->first = NULL;
93-
list->length = 0;
83+
LinkedListNode *oldNext = item->next;
84+
oldPrev->next = oldNext;
85+
oldNext->prev = oldPrev;
86+
87+
if (item == list->first) {
88+
if (list->length == 1) {
89+
list->first = NULL;
90+
} else {
91+
list->first = oldNext;
92+
}
9493
}
94+
free(item);
95+
list->length--;
9596
}

cluster.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
#define FILE_PATH_MAX_LENGTH 200
1313

14-
int cluster(int argc, char **argv) {
14+
int main(int argc, char **argv) {
1515
int i = 1, j;
1616
LinkedList *groupsLst;
1717
LinkedListNode *node;

division.c

+36-22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "defs.h"
77
#include "ErrorHandler.h"
88
#include "quicksort.h"
9+
#include "LinkedList.h"
910

1011
/**
1112
* Generate a random vector
@@ -120,19 +121,15 @@ double maximizeModularity(Graph *G, VerticesGroup *group, double *s, double init
120121
* @param vector an empty allocated array the size of the graph's vertices, used for power iteration
121122
* @param s an empty allocated array the size of the graph's vertices, used for storing an eigenvector
122123
*/
123-
void divisionAlgRec(Graph *G, VerticesGroup *group, LinkedList *groupsLst, double *vector, double *s) {
124-
VerticesGroup *newGroupA = NULL, *newGroupB = NULL;
124+
void divisionAlgorithm2(Graph *G, VerticesGroup *group, double *vector, double *s, VerticesGroup **newGroupA,
125+
VerticesGroup **newGroupB) {
125126
int i;
126127
double lambda, modularity, modularityAfterMax;
127-
if (group->size == 1) {
128-
insertItem(groupsLst, group);
129-
return;
130-
}
128+
131129
calculateModularitySubMatrix(G, group);
132130
randVector(vector, group->size);
133131
lambda = powerIteration(G, group, vector, s);
134132
if (!IS_POSITIVE(lambda)) {
135-
insertItem(groupsLst, group);
136133
return;
137134
}
138135
/* turn s eigenvector into +1 and -1 */
@@ -146,18 +143,11 @@ void divisionAlgRec(Graph *G, VerticesGroup *group, LinkedList *groupsLst, doubl
146143
modularityAfterMax = maximizeModularity(G, group, s, modularity);
147144
} while (modularityAfterMax > modularity);
148145

149-
if (!IS_POSITIVE(modularity)) {
150-
insertItem(groupsLst, group);
146+
if (!IS_POSITIVE(modularityAfterMax)) {
151147
return;
152148
}
153149

154-
divideGroupByEigenvector(group, s, &newGroupA, &newGroupB);
155-
if (newGroupA == NULL || newGroupB == NULL) {
156-
insertItem(groupsLst, group);
157-
} else {
158-
divisionAlgRec(G, newGroupA, groupsLst, vector, s);
159-
divisionAlgRec(G, newGroupB, groupsLst, vector, s);
160-
}
150+
divideGroupByEigenvector(group, s, newGroupA, newGroupB);
161151
}
162152

163153
/**
@@ -168,8 +158,10 @@ void divisionAlgRec(Graph *G, VerticesGroup *group, LinkedList *groupsLst, doubl
168158
LinkedList *divisionAlgorithm(Graph *G) {
169159
int i;
170160
double *vector, *s;
171-
LinkedList *groupsLst = createLinkedList();
172-
VerticesGroup *group;
161+
LinkedList *P, *O;
162+
VerticesGroup *group, *groupA, *groupB;
163+
P = createLinkedList();
164+
O = createLinkedList();
173165

174166
/* Notice that the formula for the expected number of edges
175167
* between two given vertices requires division by zero if
@@ -181,9 +173,9 @@ LinkedList *divisionAlgorithm(Graph *G) {
181173
for (i = 0; i < G->n; ++i) {
182174
group = createVerticesGroup();
183175
addVertexToGroup(group, i);
184-
insertItem(groupsLst, group);
176+
insertItem(P, group);
185177
}
186-
return groupsLst;
178+
return P;
187179
}
188180

189181
vector = malloc(G->n * sizeof(double));
@@ -194,10 +186,32 @@ LinkedList *divisionAlgorithm(Graph *G) {
194186
for (i = 0; i < G->n; i++) {
195187
addVertexToGroup(group, i);
196188
}
197-
divisionAlgRec(G, group, groupsLst, vector, s);
189+
insertItem(P, group);
190+
while (P->first != NULL) {
191+
groupA = NULL;
192+
groupB = NULL;
193+
group = P->first->pointer;
194+
removeItem(P, P->first);
195+
divisionAlgorithm2(G, group, vector, s, &groupA, &groupB);
196+
if (groupA == NULL || groupB == NULL) {
197+
insertItem(O, group);
198+
} else {
199+
if (groupA->size == 1) {
200+
insertItem(O, groupA);
201+
} else {
202+
insertItem(P, groupA);
203+
}
204+
if (groupB->size == 1) {
205+
insertItem(O, groupB);
206+
} else {
207+
insertItem(P, groupB);
208+
}
209+
}
210+
}
211+
198212
free(vector);
199213
free(s);
200-
return groupsLst;
214+
return O;
201215
}
202216

203217
void saveOutputToFile(LinkedList *groupLst, char *output_path) {

division.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ void divideGroupByEigenvector(VerticesGroup *group, double *s, VerticesGroup **s
1414

1515
double maximizeModularity(Graph *G, VerticesGroup *group, double *s, double initialModularity);
1616

17-
void divisionAlgRec(Graph *G, VerticesGroup *group, LinkedList *groupsLst, double *vector, double *s);
17+
void divisionAlgorithm2(Graph *G, VerticesGroup *group, double *vector, double *s, VerticesGroup **newGroupA,
18+
VerticesGroup **newGroupB);
1819

1920
void saveOutputToFile(LinkedList *groupLst, char *output_path);
2021

tests/neoTests/main.c

+22-25
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@
2121

2222
#include <stdlib.h>
2323
#include <stdio.h>
24-
#include <string.h>
2524
#include "../../cluster.h"
2625

27-
#define DIR "C:\\Users\\royar\\Source\\Workspaces\\Workspace\\C projects\\cproject-cluster\\tests\\neoTests\\"
28-
2926
/**
3027
void printA(int* a, int size){
3128
int i;
@@ -215,48 +212,48 @@ int main() {
215212

216213
argv[0] = "name";
217214

218-
argv[1] = DIR"3empty";
219-
argv[2] = DIR"3emptyOut";
215+
argv[1] = "3empty";
216+
argv[2] = "3emptyOut";
220217
cluster(argc, argv);
221218

222-
argv[1] = DIR"30empty";
223-
argv[2] = DIR"30emptyOut";
219+
argv[1] = "30empty";
220+
argv[2] = "30emptyOut";
224221
cluster(argc, argv);
225222

226-
argv[1] = DIR"3c";
227-
argv[2] = DIR"3cOut";
223+
argv[1] = "3c";
224+
argv[2] = "3cOut";
228225
cluster(argc, argv);
229226

230-
argv[1] = DIR"30c";
231-
argv[2] = DIR"30cOut";
227+
argv[1] = "30c";
228+
argv[2] = "30cOut";
232229
cluster(argc, argv);
233230

234-
argv[1] = DIR"30a";
235-
argv[2] = DIR"30aOut";
231+
argv[1] = "30a";
232+
argv[2] = "30aOut";
236233
cluster(argc, argv);
237234

238-
argv[1] = DIR"300c";
239-
argv[2] = DIR"300cOut";
235+
argv[1] = "300c";
236+
argv[2] = "300cOut";
240237
cluster(argc, argv);
241238

242-
argv[1] = DIR"300a";
243-
argv[2] = DIR"300aOut";
239+
argv[1] = "300a";
240+
argv[2] = "300aOut";
244241
cluster(argc, argv);
245242

246-
argv[1] = DIR"20-30c";
247-
argv[2] = DIR"20-30cOut";
243+
argv[1] = "20-30c";
244+
argv[2] = "20-30cOut";
248245
cluster(argc, argv);
249246

250-
argv[1] = DIR"20-30a";
251-
argv[2] = DIR"20-30aOut";
247+
argv[1] = "20-30a";
248+
argv[2] = "20-30aOut";
252249
cluster(argc, argv);
253250

254-
argv[1] = DIR"60-100c";
255-
argv[2] = DIR"60-100cOut";
251+
argv[1] = "60-100c";
252+
argv[2] = "60-100cOut";
256253
cluster(argc, argv);
257254

258-
argv[1] = DIR"60-100a";
259-
argv[2] = DIR"60-100aOut";
255+
argv[1] = "60-100a";
256+
argv[2] = "60-100aOut";
260257
cluster(argc, argv);
261258

262259

tests/tester.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
#include <time.h>
66
#include <stdio.h>
77

8-
#define GRAPHS_DIR "C:\\Users\\royar\\Source\\Workspaces\\Workspace\\C projects\\cproject-cluster\\tests\\graphs"
9-
/*#define GRAPHS_DIR "D:\\Users\\idodo\\OneDrive - mail.tau.ac.il\\Studies\\Tel Aviv University\\Semester 4\\Software Project\\Homework\\Project\\Project\\tests\\graphs"*/
8+
#define GRAPHS_DIR "tests\\graphs"
109

1110
void printColorings(int *coloring1, int *coloring2, int n);
1211

0 commit comments

Comments
 (0)