Mercurial > defical
comparison defical-c/src/graphmagic.cpp @ 0:ebed2bd0d300
Initial import from svn. History be damned.
author | Edho P. Arief <me@myconan.net> |
---|---|
date | Fri, 02 Apr 2010 23:11:57 +0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ebed2bd0d300 |
---|---|
1 #include "graphmagic.h" | |
2 | |
3 semtd::semtd(){} | |
4 | |
5 semtd::semtd(uint32_t graphType,uint32_t NumVer, uint32_t numDef) | |
6 { | |
7 if(NumVer>3){ | |
8 this->NumVer=NumVer; | |
9 this->numDef=numDef; | |
10 this->graphType=graphType; | |
11 this->TotalVer=NumVer+numDef; | |
12 this->numEdges=0; | |
13 this->isSureFail=false; | |
14 this->edgeLabelAbsoluteMax=this->TotalVer*2-1; | |
15 //initialize graph array | |
16 //this->theGraph.resize(this->NumVer+1,vector<bool>(this->NumVer+1,false)); | |
17 for (int i=0; i<1000;i++) | |
18 { | |
19 for (int j=0;j<1000;j++) | |
20 { | |
21 this->theGraph[i][j]=false; | |
22 } | |
23 } | |
24 draw(this->graphType,1,this->NumVer); | |
25 resetLabels(0); | |
26 } | |
27 } | |
28 | |
29 void semtd::draw(uint32_t drawType,uint32_t start,uint32_t end) | |
30 { | |
31 switch(drawType) | |
32 { | |
33 case 0: | |
34 { | |
35 for (uint32_t i=start;i<end;i++) | |
36 connectVertices(i,i+1); | |
37 break; | |
38 } | |
39 case 1: | |
40 { | |
41 draw(0,start,end); | |
42 connectVertices(start,end); | |
43 break; | |
44 } | |
45 case 3: | |
46 { | |
47 draw(1,start+1,end); | |
48 draw(2,start+1,end,start); | |
49 break; | |
50 } | |
51 case 4: | |
52 { | |
53 draw(0,start+1,end); | |
54 draw(2,start+1,end,start); | |
55 break; | |
56 } | |
57 case 5: | |
58 { | |
59 draw(4,start+1,end); | |
60 draw(2,start+2,end,start); | |
61 break; | |
62 } | |
63 } | |
64 } | |
65 | |
66 void semtd::draw(uint32_t drawType,uint32_t start,uint32_t end, uint32_t extra) | |
67 { | |
68 switch(drawType) | |
69 { | |
70 case 2: | |
71 { | |
72 for (uint32_t i=start;i<=end;i++) | |
73 connectVertices(i,extra); | |
74 break; | |
75 } | |
76 } | |
77 } | |
78 | |
79 inline void semtd::connectVertices(uint32_t a,uint32_t b) | |
80 { | |
81 if(!this->theGraph[a][b]) | |
82 { | |
83 this->theGraph[a][b]=this->theGraph[b][a]=true; | |
84 this->numEdges++; | |
85 } | |
86 } | |
87 | |
88 void semtd::resetLabels(uint32_t mode) | |
89 { | |
90 if(mode==0) | |
91 { | |
92 this->VerLabels.clear(); | |
93 this->VerLabels.resize(this->NumVer+1,0); | |
94 } | |
95 this->edgeLabels.clear(); | |
96 this->edgeLabels.resize(NumVer+1,vector<uint32_t>(NumVer+1,0)); | |
97 this->isQuickMode=false; | |
98 this->scoreCache=-1; | |
99 //uint32_t *edgeLabelsUsedPtr; | |
100 //edgeLabelsUsedPtr=(uint32_t*)malloc(this->edgeLabelAbsoluteMax+1*sizeof(uint32_t)); | |
101 this->edgeLabelsUsed.clear(); | |
102 this->edgeLabelsUsed.resize(this->edgeLabelAbsoluteMax+1,0); | |
103 this->edgeLabelMax=0;this->edgeLabelMin=this->edgeLabelAbsoluteMax; | |
104 refreshEdgeLabelsMinMax(); | |
105 } | |
106 | |
107 void semtd::refreshEdgeLabelsMinMax() | |
108 { | |
109 uint32_t i; | |
110 for (i = 1; i <= this->edgeLabelAbsoluteMax; i++) | |
111 { | |
112 if (this->edgeLabelsUsed[i] > 0) | |
113 { | |
114 this->edgeLabelMin = i; | |
115 break; | |
116 } | |
117 } | |
118 for (int32_t x = this->edgeLabelAbsoluteMax; x >= 0; x--) | |
119 { | |
120 if (this->edgeLabelsUsed[x] > 0) | |
121 { | |
122 this->edgeLabelMax = x; | |
123 break; | |
124 } | |
125 } | |
126 } | |
127 | |
128 inline uint32_t semtd::edgeLabelRange() | |
129 { | |
130 return this->edgeLabelMax-this->edgeLabelMin+1; | |
131 } | |
132 | |
133 void semtd::setEdgeLabels(uint32_t verPos) | |
134 { | |
135 uint32_t newLabel,i; | |
136 for (i = 1; i <= this->NumVer; i++) | |
137 { | |
138 if (this->VerLabels[i] > 0 && this->theGraph[verPos][i] && i != verPos) | |
139 { | |
140 newLabel = this->VerLabels[verPos] + this->VerLabels[i]; | |
141 this->edgeLabels[i][verPos] = this->edgeLabels[i][verPos] = newLabel; | |
142 this->edgeLabelsUsed[newLabel]++; | |
143 if (this->edgeLabelsUsed[newLabel] != 1) | |
144 this->isSureFail = true; | |
145 } | |
146 } | |
147 refreshEdgeLabelsMinMax(); | |
148 } | |
149 | |
150 void semtd::removeEdgeLabels(uint32_t verPos) | |
151 { | |
152 uint32_t i; | |
153 for (i = 1; i <= this->NumVer; i++) | |
154 { | |
155 if (this->VerLabels[i] > 0 && this->theGraph[verPos][i] && i != verPos) | |
156 { | |
157 int oldLabel = this->edgeLabels[i][verPos]; | |
158 this->edgeLabelsUsed[oldLabel]--; | |
159 this->edgeLabels[i][verPos] = this->edgeLabels[verPos][i] = 0; | |
160 } | |
161 } | |
162 refreshEdgeLabelsMinMax(); | |
163 } | |
164 | |
165 void semtd::SetVerLabel(uint32_t verPos,uint32_t verLabel) | |
166 { | |
167 if (this->VerLabels[verPos] > 0) { RemoveVerLabel(verPos); } | |
168 this->VerLabels[verPos] = verLabel; | |
169 setEdgeLabels(verPos); | |
170 } | |
171 | |
172 void semtd::RemoveVerLabel(uint32_t verPos) | |
173 { | |
174 if (this->VerLabels[verPos] > 0) | |
175 { | |
176 this->VerLabels[verPos] = 0; | |
177 removeEdgeLabels(verPos); | |
178 } | |
179 } | |
180 | |
181 | |
182 | |
183 bool semtd::IsValidToLabel(uint32_t verPos,uint32_t verLabel) | |
184 { | |
185 uint32_t i,tempLabel; | |
186 //uint32_t tempMax=this->edgeLabelMax; | |
187 //uint32_t tempMin=this->edgeLabelMin; | |
188 for (i = 1; i <= this->NumVer; i++) | |
189 { | |
190 tempLabel=this->VerLabels[i] + verLabel; | |
191 if (i != verPos && | |
192 this->theGraph[i][verPos] && | |
193 this->VerLabels[i] > 0 && | |
194 this->edgeLabelsUsed[tempLabel] == 1) | |
195 { | |
196 return false; | |
197 } | |
198 /*if(tempLabel>tempMax) | |
199 tempMax=tempLabel; | |
200 if(tempLabel<tempMin) | |
201 tempMin=tempLabel; | |
202 if(!isValidRange(tempMin,tempMax)) | |
203 return false;*/ | |
204 } | |
205 return true; | |
206 } | |
207 | |
208 bool semtd::isValidRange(uint32_t min,uint32_t max) | |
209 { | |
210 uint32_t delta=1+max-min; | |
211 if(delta<=this->numEdges) | |
212 return true; | |
213 return false; | |
214 } | |
215 | |
216 double semtd::SemtScore() | |
217 { | |
218 //TODO | |
219 return 0; | |
220 } | |
221 | |
222 void semtd::FixLabel() | |
223 { | |
224 //TODO | |
225 } | |
226 | |
227 void semtd::SwapLabel() | |
228 { | |
229 //TODO | |
230 } | |
231 | |
232 string semtd::Print(uint32_t withDual) | |
233 { | |
234 uint32_t i,j; | |
235 string ret = ""; | |
236 string n = "\n"; | |
237 bool dualRun=false; | |
238 bool keepPrinting=true; | |
239 while (keepPrinting) | |
240 { | |
241 ret+="graph: "; | |
242 switch(this->graphType) | |
243 { | |
244 case 3: | |
245 { | |
246 ret+="wheel"; | |
247 break; | |
248 } | |
249 case 4: | |
250 { | |
251 ret+="fan"; | |
252 break; | |
253 } | |
254 case 5: | |
255 { | |
256 ret+="doublefan"; | |
257 break; | |
258 } | |
259 default: | |
260 { | |
261 ret+="unknown"; | |
262 break; | |
263 } | |
264 } | |
265 ret+=" | edges: "+uint32_t_to_str(this->numEdges)+" | vertices: " + uint32_t_to_str(this->NumVer)+" | deficiencies: " + uint32_t_to_str(this->numDef) + " | "; | |
266 uint32_t edgeweight=0,k,edgelabel=0; | |
267 for (i=1;i<=this->edgeLabelAbsoluteMax;i++) | |
268 { | |
269 if(this->edgeLabelsUsed[i]) | |
270 { | |
271 edgeweight=i; | |
272 edgelabel=this->numEdges+this->TotalVer; | |
273 break; | |
274 } | |
275 } | |
276 if(dualRun) | |
277 { | |
278 edgeweight=2*(this->TotalVer)+2-edgeweight; | |
279 edgelabel=2*this->TotalVer+this->numEdges+1-edgelabel; | |
280 } | |
281 k=edgeweight+edgelabel; | |
282 ret+="mnum: "+uint32_t_to_str(k)+" | "; | |
283 for (i = 1; i <= this->NumVer; i++) | |
284 { | |
285 uint32_t theLabel; | |
286 if(dualRun) | |
287 theLabel=this->TotalVer+1-this->VerLabels[i]; | |
288 else | |
289 theLabel=this->VerLabels[i]; | |
290 if(i==1 && this->graphType==3) | |
291 ret+="c: " + uint32_t_to_str(theLabel) +" | l: "; | |
292 else if(i==1 && this->graphType==4) | |
293 ret+="c: " + uint32_t_to_str(theLabel) +" | p: "; | |
294 else if(i==1 && this->graphType==5) | |
295 ret+="c: " + uint32_t_to_str(theLabel) + ","; | |
296 else if(i==2 && this->graphType==5) | |
297 ret+=uint32_t_to_str(theLabel) + " | p: "; | |
298 else if(i==this->NumVer) | |
299 ret+=uint32_t_to_str(theLabel) + " | def: "; | |
300 else | |
301 ret+=uint32_t_to_str(theLabel)+","; | |
302 } | |
303 if(this->numDef>0) | |
304 { | |
305 vector<bool> usedLabels (this->TotalVer+1,false); | |
306 for(i=1;i<=this->NumVer;i++) | |
307 usedLabels[this->VerLabels[i]]=true; | |
308 j=0; | |
309 for(i=1;i<=this->TotalVer;i++) | |
310 { | |
311 uint32_t theLabel; | |
312 if(!usedLabels[i]) | |
313 { | |
314 if(dualRun) | |
315 theLabel=this->TotalVer+1-i; | |
316 else | |
317 theLabel=i; | |
318 if(j==this->numDef-1) | |
319 { | |
320 if(dualRun) | |
321 ret+=uint32_t_to_str(theLabel)+" (dual)"+n; | |
322 else | |
323 ret+=uint32_t_to_str(theLabel)+n; | |
324 j++; | |
325 } | |
326 else | |
327 { | |
328 ret+=uint32_t_to_str(theLabel)+","; | |
329 j++; | |
330 } | |
331 } | |
332 } | |
333 } | |
334 /* | |
335 ret += n+"Deficiency: " + uint32_t_to_str(this->numDef); | |
336 ret += n+"GraphViz code: " + n + "----------------------------------"; | |
337 //tempstr1<<this->graphType; //TODO: graphtype is now integer instead of string. create a convert method | |
338 ret += n+"graph " + uint32_t_to_str(this->graphType)+ "{"; | |
339 ret += n+"graph[bgcolor=\"transparent\"]"; | |
340 ret += n+"node [fontname=\"Bitstream Vera Sans\", fontsize=\"22.00\", shape=circle, style=\"bold,filled\" fillcolor=white];"; | |
341 ret += n+"edge [style=bold];"; | |
342 ret += n+" "; | |
343 for (i = 1; i <= this->TotalVer; i++) | |
344 { | |
345 ret += uint32_t_to_str(i) + ";"; | |
346 } | |
347 for (i = 1; i <= this->NumVer; i++) | |
348 { | |
349 for (j = i + 1; j <= this->NumVer; j++) | |
350 { | |
351 if (this->theGraph[i][j]) | |
352 { | |
353 uint32_t theLabel; | |
354 if(dualRun) | |
355 theLabel=this->TotalVer+1-this->VerLabels[i]; | |
356 else | |
357 theLabel=this->VerLabels[i]; | |
358 ret += n+uint32_t_to_str(this->VerLabels[i])+ " -- " + uint32_t_to_str(theLabel)+ ";"; | |
359 } | |
360 } | |
361 } | |
362 ret += n+"}"; | |
363 ret += n+"----------------------------------" + n + "End GraphViz code";*/ | |
364 if(withDual==1) | |
365 { | |
366 withDual=0; | |
367 dualRun=true; | |
368 }else | |
369 keepPrinting=false; | |
370 } | |
371 return ret; | |
372 } | |
373 | |
374 | |
375 | |
376 bool semtd::IsSemt() | |
377 { | |
378 uint32_t i; | |
379 if (this->isSureFail) { return false; } | |
380 else | |
381 { | |
382 if (edgeLabelRange() == numEdges) | |
383 { | |
384 uint32_t edgeLabelMin = this->edgeLabelMin; | |
385 uint32_t edgeLabelMax = this->edgeLabelMax; | |
386 for (i = edgeLabelMin; i <= edgeLabelMax; i++) | |
387 { | |
388 if (this->edgeLabelsUsed[i] != 1) | |
389 { | |
390 return false; | |
391 } | |
392 } | |
393 return true; | |
394 } | |
395 } | |
396 return false; | |
397 } | |
398 | |
399 uint32_t semtd::MinDef() | |
400 { | |
401 uint32_t ret=0; | |
402 switch(this->graphType) | |
403 { | |
404 case 3: | |
405 switch (this->NumVer) | |
406 { | |
407 case 3: | |
408 case 4: | |
409 case 6: | |
410 case 7: | |
411 { | |
412 ret = 1; | |
413 break; | |
414 } | |
415 default: | |
416 { | |
417 ret = 2; | |
418 break; | |
419 } | |
420 } | |
421 case 4: | |
422 { | |
423 ret=1; | |
424 break; | |
425 } | |
426 case 5: | |
427 { | |
428 ret = (this->NumVer - 3) / 2; | |
429 break; | |
430 } | |
431 } | |
432 return ret; | |
433 } |