Mercurial > defical
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/defical-c/src/graphmagic.cpp Fri Apr 02 23:11:57 2010 +0700 @@ -0,0 +1,433 @@ +#include "graphmagic.h" + +semtd::semtd(){} + +semtd::semtd(uint32_t graphType,uint32_t NumVer, uint32_t numDef) +{ + if(NumVer>3){ + this->NumVer=NumVer; + this->numDef=numDef; + this->graphType=graphType; + this->TotalVer=NumVer+numDef; + this->numEdges=0; + this->isSureFail=false; + this->edgeLabelAbsoluteMax=this->TotalVer*2-1; + //initialize graph array + //this->theGraph.resize(this->NumVer+1,vector<bool>(this->NumVer+1,false)); + for (int i=0; i<1000;i++) + { + for (int j=0;j<1000;j++) + { + this->theGraph[i][j]=false; + } + } + draw(this->graphType,1,this->NumVer); + resetLabels(0); + } +} + +void semtd::draw(uint32_t drawType,uint32_t start,uint32_t end) +{ + switch(drawType) + { + case 0: + { + for (uint32_t i=start;i<end;i++) + connectVertices(i,i+1); + break; + } + case 1: + { + draw(0,start,end); + connectVertices(start,end); + break; + } + case 3: + { + draw(1,start+1,end); + draw(2,start+1,end,start); + break; + } + case 4: + { + draw(0,start+1,end); + draw(2,start+1,end,start); + break; + } + case 5: + { + draw(4,start+1,end); + draw(2,start+2,end,start); + break; + } + } +} + +void semtd::draw(uint32_t drawType,uint32_t start,uint32_t end, uint32_t extra) +{ + switch(drawType) + { + case 2: + { + for (uint32_t i=start;i<=end;i++) + connectVertices(i,extra); + break; + } + } +} + +inline void semtd::connectVertices(uint32_t a,uint32_t b) +{ + if(!this->theGraph[a][b]) + { + this->theGraph[a][b]=this->theGraph[b][a]=true; + this->numEdges++; + } +} + +void semtd::resetLabels(uint32_t mode) +{ + if(mode==0) + { + this->VerLabels.clear(); + this->VerLabels.resize(this->NumVer+1,0); + } + this->edgeLabels.clear(); + this->edgeLabels.resize(NumVer+1,vector<uint32_t>(NumVer+1,0)); + this->isQuickMode=false; + this->scoreCache=-1; + //uint32_t *edgeLabelsUsedPtr; + //edgeLabelsUsedPtr=(uint32_t*)malloc(this->edgeLabelAbsoluteMax+1*sizeof(uint32_t)); + this->edgeLabelsUsed.clear(); + this->edgeLabelsUsed.resize(this->edgeLabelAbsoluteMax+1,0); + this->edgeLabelMax=0;this->edgeLabelMin=this->edgeLabelAbsoluteMax; + refreshEdgeLabelsMinMax(); +} + +void semtd::refreshEdgeLabelsMinMax() +{ + uint32_t i; + for (i = 1; i <= this->edgeLabelAbsoluteMax; i++) + { + if (this->edgeLabelsUsed[i] > 0) + { + this->edgeLabelMin = i; + break; + } + } + for (int32_t x = this->edgeLabelAbsoluteMax; x >= 0; x--) + { + if (this->edgeLabelsUsed[x] > 0) + { + this->edgeLabelMax = x; + break; + } + } +} + +inline uint32_t semtd::edgeLabelRange() +{ + return this->edgeLabelMax-this->edgeLabelMin+1; +} + +void semtd::setEdgeLabels(uint32_t verPos) +{ + uint32_t newLabel,i; + for (i = 1; i <= this->NumVer; i++) + { + if (this->VerLabels[i] > 0 && this->theGraph[verPos][i] && i != verPos) + { + newLabel = this->VerLabels[verPos] + this->VerLabels[i]; + this->edgeLabels[i][verPos] = this->edgeLabels[i][verPos] = newLabel; + this->edgeLabelsUsed[newLabel]++; + if (this->edgeLabelsUsed[newLabel] != 1) + this->isSureFail = true; + } + } + refreshEdgeLabelsMinMax(); +} + +void semtd::removeEdgeLabels(uint32_t verPos) +{ + uint32_t i; + for (i = 1; i <= this->NumVer; i++) + { + if (this->VerLabels[i] > 0 && this->theGraph[verPos][i] && i != verPos) + { + int oldLabel = this->edgeLabels[i][verPos]; + this->edgeLabelsUsed[oldLabel]--; + this->edgeLabels[i][verPos] = this->edgeLabels[verPos][i] = 0; + } + } + refreshEdgeLabelsMinMax(); +} + +void semtd::SetVerLabel(uint32_t verPos,uint32_t verLabel) +{ + if (this->VerLabels[verPos] > 0) { RemoveVerLabel(verPos); } + this->VerLabels[verPos] = verLabel; + setEdgeLabels(verPos); +} + +void semtd::RemoveVerLabel(uint32_t verPos) +{ + if (this->VerLabels[verPos] > 0) + { + this->VerLabels[verPos] = 0; + removeEdgeLabels(verPos); + } +} + + + +bool semtd::IsValidToLabel(uint32_t verPos,uint32_t verLabel) +{ + uint32_t i,tempLabel; + //uint32_t tempMax=this->edgeLabelMax; + //uint32_t tempMin=this->edgeLabelMin; + for (i = 1; i <= this->NumVer; i++) + { + tempLabel=this->VerLabels[i] + verLabel; + if (i != verPos && + this->theGraph[i][verPos] && + this->VerLabels[i] > 0 && + this->edgeLabelsUsed[tempLabel] == 1) + { + return false; + } + /*if(tempLabel>tempMax) + tempMax=tempLabel; + if(tempLabel<tempMin) + tempMin=tempLabel; + if(!isValidRange(tempMin,tempMax)) + return false;*/ + } + return true; +} + +bool semtd::isValidRange(uint32_t min,uint32_t max) +{ + uint32_t delta=1+max-min; + if(delta<=this->numEdges) + return true; + return false; +} + +double semtd::SemtScore() +{ + //TODO + return 0; +} + +void semtd::FixLabel() +{ + //TODO +} + +void semtd::SwapLabel() +{ + //TODO +} + +string semtd::Print(uint32_t withDual) +{ + uint32_t i,j; + string ret = ""; + string n = "\n"; + bool dualRun=false; + bool keepPrinting=true; + while (keepPrinting) + { + ret+="graph: "; + switch(this->graphType) + { + case 3: + { + ret+="wheel"; + break; + } + case 4: + { + ret+="fan"; + break; + } + case 5: + { + ret+="doublefan"; + break; + } + default: + { + ret+="unknown"; + break; + } + } + ret+=" | edges: "+uint32_t_to_str(this->numEdges)+" | vertices: " + uint32_t_to_str(this->NumVer)+" | deficiencies: " + uint32_t_to_str(this->numDef) + " | "; + uint32_t edgeweight=0,k,edgelabel=0; + for (i=1;i<=this->edgeLabelAbsoluteMax;i++) + { + if(this->edgeLabelsUsed[i]) + { + edgeweight=i; + edgelabel=this->numEdges+this->TotalVer; + break; + } + } + if(dualRun) + { + edgeweight=2*(this->TotalVer)+2-edgeweight; + edgelabel=2*this->TotalVer+this->numEdges+1-edgelabel; + } + k=edgeweight+edgelabel; + ret+="mnum: "+uint32_t_to_str(k)+" | "; + for (i = 1; i <= this->NumVer; i++) + { + uint32_t theLabel; + if(dualRun) + theLabel=this->TotalVer+1-this->VerLabels[i]; + else + theLabel=this->VerLabels[i]; + if(i==1 && this->graphType==3) + ret+="c: " + uint32_t_to_str(theLabel) +" | l: "; + else if(i==1 && this->graphType==4) + ret+="c: " + uint32_t_to_str(theLabel) +" | p: "; + else if(i==1 && this->graphType==5) + ret+="c: " + uint32_t_to_str(theLabel) + ","; + else if(i==2 && this->graphType==5) + ret+=uint32_t_to_str(theLabel) + " | p: "; + else if(i==this->NumVer) + ret+=uint32_t_to_str(theLabel) + " | def: "; + else + ret+=uint32_t_to_str(theLabel)+","; + } + if(this->numDef>0) + { + vector<bool> usedLabels (this->TotalVer+1,false); + for(i=1;i<=this->NumVer;i++) + usedLabels[this->VerLabels[i]]=true; + j=0; + for(i=1;i<=this->TotalVer;i++) + { + uint32_t theLabel; + if(!usedLabels[i]) + { + if(dualRun) + theLabel=this->TotalVer+1-i; + else + theLabel=i; + if(j==this->numDef-1) + { + if(dualRun) + ret+=uint32_t_to_str(theLabel)+" (dual)"+n; + else + ret+=uint32_t_to_str(theLabel)+n; + j++; + } + else + { + ret+=uint32_t_to_str(theLabel)+","; + j++; + } + } + } + } + /* + ret += n+"Deficiency: " + uint32_t_to_str(this->numDef); + ret += n+"GraphViz code: " + n + "----------------------------------"; + //tempstr1<<this->graphType; //TODO: graphtype is now integer instead of string. create a convert method + ret += n+"graph " + uint32_t_to_str(this->graphType)+ "{"; + ret += n+"graph[bgcolor=\"transparent\"]"; + ret += n+"node [fontname=\"Bitstream Vera Sans\", fontsize=\"22.00\", shape=circle, style=\"bold,filled\" fillcolor=white];"; + ret += n+"edge [style=bold];"; + ret += n+" "; + for (i = 1; i <= this->TotalVer; i++) + { + ret += uint32_t_to_str(i) + ";"; + } + for (i = 1; i <= this->NumVer; i++) + { + for (j = i + 1; j <= this->NumVer; j++) + { + if (this->theGraph[i][j]) + { + uint32_t theLabel; + if(dualRun) + theLabel=this->TotalVer+1-this->VerLabels[i]; + else + theLabel=this->VerLabels[i]; + ret += n+uint32_t_to_str(this->VerLabels[i])+ " -- " + uint32_t_to_str(theLabel)+ ";"; + } + } + } + ret += n+"}"; + ret += n+"----------------------------------" + n + "End GraphViz code";*/ + if(withDual==1) + { + withDual=0; + dualRun=true; + }else + keepPrinting=false; + } + return ret; +} + + + +bool semtd::IsSemt() +{ + uint32_t i; + if (this->isSureFail) { return false; } + else + { + if (edgeLabelRange() == numEdges) + { + uint32_t edgeLabelMin = this->edgeLabelMin; + uint32_t edgeLabelMax = this->edgeLabelMax; + for (i = edgeLabelMin; i <= edgeLabelMax; i++) + { + if (this->edgeLabelsUsed[i] != 1) + { + return false; + } + } + return true; + } + } + return false; +} + +uint32_t semtd::MinDef() +{ + uint32_t ret=0; + switch(this->graphType) + { + case 3: + switch (this->NumVer) + { + case 3: + case 4: + case 6: + case 7: + { + ret = 1; + break; + } + default: + { + ret = 2; + break; + } + } + case 4: + { + ret=1; + break; + } + case 5: + { + ret = (this->NumVer - 3) / 2; + break; + } + } + return ret; +}