00001 #ifndef VOTECOUNTER_H
00002 #define VOTECOUNTER_H
00003
00004 #include "DAGDatabase.h"
00005 #include <LEDA/p_queue.h>
00006
00007 typedef SmartArray<double> RealVector;
00008
00009 class QueryRange : public RealVector
00010 {
00011 double commonDelta;
00012
00013 public:
00014 QueryRange(double delta, int dim) : RealVector(dim)
00015 {
00016 Set(delta);
00017 commonDelta = delta;
00018 }
00019
00020 QueryRange(const RealVector& rangeVector) : RealVector(rangeVector)
00021 {
00022 commonDelta = 0;
00023 }
00024
00025 QueryRange(const QueryRange& range) : RealVector(range)
00026 {
00027 commonDelta = range.commonDelta;
00028 }
00029
00030 void operator=(const QueryRange& range)
00031 {
00032 RealVector::operator=(range);
00033 commonDelta = range.commonDelta;
00034 }
00035
00036 bool IsInBounds(const double& x, const double& min, const double& max) const
00037 {
00038 return (x >= min && x <= max);
00039 }
00040
00041 void GetDimBounds(const double& x, int dim, double& min, double& max) const
00042 {
00043 double delta = x * (*this)[dim];
00044 min = x - delta;
00045 max = x + delta;
00046 }
00047
00048 double GetDimDelta() const
00049 {
00050 return commonDelta;
00051 }
00052
00053 bool DoPtsOverlap(const TSV pt1, const TSV pt2) const;
00054 };
00055
00057
00058
00064 namespace MOOVC {
00065
00066 struct VOTE
00067 {
00068 leda_node queryNode;
00069 int nQueryGraph;
00070
00071 int nModelNode;
00072 int nModelGraph;
00073
00074 double dWeight;
00075
00076 VOTE()
00077 {
00078 dWeight = 0.0;
00079 }
00080
00081 void operator+=(const double& w)
00082 {
00083 dWeight += w;
00084 }
00085
00086 static int Compare(const void* elem1, const void* elem2)
00087 {
00088 double a = ((const VOTE*)elem1)->dWeight, b = ((const VOTE*)elem2)->dWeight;
00089 return a > b ? -1:(a < b ? 1:0);
00090 }
00091 };
00092
00093 class VoteBalance
00094 {
00095 TSV queryNodeTSV;
00096 int nQueryNodeLbl;
00097 double dQueryNodeRelMass;
00098 int nTSVDim;
00099 double dAlpha;
00100
00101 public:
00102
00103 VoteBalance(int nTSVDimension, double dConvexityParam = 0.5)
00104 {
00105 nTSVDim = nTSVDimension;
00106 dAlpha = dConvexityParam;
00107 }
00108
00109 void SetQueryNode(const DAGPtr ptrDag, leda_node v)
00110 {
00111 queryNodeTSV = ptrDag->GetNodeTSV(v, nTSVDim);
00112 nQueryNodeLbl = ptrDag->NodeType(v);
00113 dQueryNodeRelMass = (1 - dAlpha) * ptrDag->GetNodeTSVNorm(v) / ptrDag->GetTotalTSVSum();
00114 }
00115
00116 const TSV& GetQueryNodeTSV() const
00117 {
00118 return queryNodeTSV;
00119 }
00120
00121 double Weight(const DAGSearchRecordEx& modelNodeInfo)
00122 {
00123 if (modelNodeInfo.nodeLbl != nQueryNodeLbl)
00124 return 0;
00125
00126 double dModelNodeRelMass = dAlpha * modelNodeInfo.nodeTSV.Norm2() / modelNodeInfo.totalVote;
00127 double dNormDiff = Norm2(queryNodeTSV - modelNodeInfo.nodeTSV);
00128
00129 return (dQueryNodeRelMass + dModelNodeRelMass) / (1 + dNormDiff);
00130 }
00131 };
00132
00137 class BoundedBin : public leda_p_queue<double, int>
00138 {
00139 int nMaxSize;
00140 public:
00141 BoundedBin(int sz = 0) { SetMaxSize(sz); }
00142 void SetMaxSize(int sz) { nMaxSize = sz; }
00143 int GetMaxSize() const { return nMaxSize; }
00144
00145 void AddVote(VOTE v)
00146 {
00147 ASSERT(size() <= nMaxSize);
00148
00149
00150 if (size() == nMaxSize)
00151 {
00152 pq_item min = find_min();
00153
00154 if (prio(min) < v.dWeight)
00155 del_item(min);
00156 else
00157 return;
00158
00159 }
00160
00161 insert(v.dWeight, v.nModelNode);
00162 }
00163
00164 void Clear()
00165 {
00166 clear();
00167 }
00168 };
00169
00170 class PartitionBins
00171 {
00172 SmartArray<BoundedBin> bins;
00173 double dCumulativeVote;
00174
00175
00176
00177 static SmartArray<leda_node> modelNodeMap;
00178
00179 public:
00180 void AddVote(int idxElem, VOTE v)
00181 {
00182 bins[idxElem].AddVote(v);
00183 dCumulativeVote += v.dWeight;
00184 }
00185
00186 int GetNodeCount() const { return bins.GetSize(); }
00187 int GetBinBound(int idxBin) const { return bins[idxBin].GetMaxSize(); }
00188 double GetCumulativeVote() const { return dCumulativeVote; }
00189
00190 void SetPartitionSize(int nNodeCount)
00191 {
00192 bins.ReSize(nNodeCount, false);
00193 dCumulativeVote = 0;
00194
00195 for (int i = 0; i < nNodeCount; i++)
00196 {
00197 bins[i].Clear();
00198 bins[i].SetMaxSize(nNodeCount);
00199 }
00200 }
00201
00202 void CreateVoteGraph(LEDA_GRAPH<int, double>& g) const;
00203 double CompPartitionVote() const;
00204 };
00205
00206 class Partition : public SmartArray<leda_node>
00207 {
00208 public:
00209 int NodeCount() const { return GetSize(); }
00210 void AddElement(leda_node v) { AddTail(v); }
00211 };
00212
00213 class PartitionArray : public SmartArray<Partition>
00214 {
00215 const DAG* pDag;
00216
00217 public:
00218 PartitionArray(const DAG* pOverlapGraph)
00219 {
00220 pDag = pOverlapGraph;
00221 }
00222
00223 void SetSize(int sz)
00224 {
00225 ReSize(sz, false);
00226 }
00227
00228 void AddElement(int idxPart, leda_node v)
00229 {
00230 (*this)[idxPart].AddElement(v);
00231 }
00232 };
00233
00234 class ModelBins
00235 {
00236 SmartArray<double> modelVotes;
00237 SmartArray<PartitionBins> partBins;
00238 double dMinTotalModelVote;
00239 int nModelsAboveMinVote;
00240
00241 public:
00242 ModelBins(int nNumModels, double dMinModelVote)
00243 {
00244 modelVotes.ReSize(nNumModels, true);
00245 partBins.ReSize(nNumModels, false);
00246 dMinTotalModelVote = dMinModelVote;
00247 nModelsAboveMinVote = 0;
00248 }
00249
00250 void AddVote(int idxModel, const double& vote)
00251 {
00252 double& currModelWeight = modelVotes[idxModel];
00253 bool flag = currModelWeight < dMinTotalModelVote;
00254
00255 ASSERT(currModelWeight >= 0.0);
00256
00257 currModelWeight += vote;
00258
00259 if (flag && currModelWeight >= dMinTotalModelVote)
00260 nModelsAboveMinVote++;
00261
00262 ASSERT(currModelWeight <= 1.0);
00263 }
00264
00265 void AddPartitionVotes(Partition& part, const DAGPtr ptrQueryDag, DAGDatabase& modelDB,
00266 const QueryRange& range, double dQueryNodeRelMass);
00267
00268 SmartArray<VOTE> GetRankedVotes() const;
00269
00270 ModelBins& operator=(const ModelBins& rhs)
00271 {
00272 modelVotes = rhs.modelVotes;
00273 partBins = rhs.partBins;
00274
00275 return *this;
00276 }
00277 };
00278
00284 DAGPtr ComputeOverlappingNodeGraph(const DAGPtr ptrQueryDag, const QueryRange& r);
00285
00289 PartitionArray FindPartitions(const DAGPtr ptrOverlapDag);
00290
00291 }
00292
00293 typedef SmartArray<MOOVC::VOTE> NNVoteArray;
00294
00298 NNVoteArray ComputeVotesForModelGraphs(const DAGPtr ptrQueryDag,
00299 DAGDatabase& modelDB, const QueryRange& r, double dQueryNodeRelMass, double dMinSimilarity);
00300
00301 #endif