00001
00035 #include "ViewSubsampler.h"
00036
00037 #include <fcntl.h>
00038 #include <cerrno>
00039 #include <cstdio>
00040
00041 #define RETRY_TIME_SECONDS 2
00042 #define MAX_GOOD_MATCH_POS 10
00043
00044 int VWCompare(const void* elem1, const void* elem2 )
00045 {
00046 const double& w1 = ((const VIEWWEIGHT*)elem1)->dVoteWeight;
00047 const double& w2 = ((const VIEWWEIGHT*)elem2)->dVoteWeight;
00048
00049 return w1 == w2 ? 0:(w1 < w2 ? 1:-1);
00050 }
00051
00052 bool LockFile::Lock(const char* szLockFileName, unsigned int nSleepTime)
00053 {
00054 while (true)
00055 {
00056 fd = open(szLockFileName, O_WRONLY | O_CREAT | O_EXCL);
00057
00058 if (fd < 0 && errno == EEXIST)
00059 sleep(nSleepTime);
00060 else if (fd < 0)
00061 {
00062 perror("locking failed for the following reason");
00063 return m_bLocked = false;
00064 }
00065 else
00066 break;
00067 }
00068
00069
00070 m_strFileName = szLockFileName;
00071 return m_bLocked = true;
00072 }
00073
00074 void LockFile::Unlock()
00075 {
00076 if (m_bLocked)
00077 {
00078 remove(m_strFileName);
00079 close(fd);
00080 m_bLocked = false;
00081 }
00082 }
00083
00084 void ViewSubsampler::AddViewWeights(int nViewsPerObject, const DAG* pQueryDag,
00085 const leda_array<MatchInfo>& matchList, const SmartArray<int>& neigViews, int kBest)
00086 {
00087 SmartArray<int> viewPos(nViewsPerObject);
00088 Record rec;
00089 VIEWWEIGHT vw;
00090 int i;
00091
00092 rec.nIndexedWithKBest = kBest;
00093 rec.strObjName = pQueryDag->GetObjName();
00094 viewPos.Set(kBest);
00095 const int nViewNum = pQueryDag->GetViewNumber();
00096
00097
00098 for (i = 0; i < matchList.size(); i++)
00099 {
00100 const DAGPtr ptrDag = matchList[i].ptrDAG;
00101
00102
00103 if (ptrDag.IsNull())
00104 break;
00105
00106
00107 if (rec.strObjName == ptrDag->GetObjName())
00108 {
00109 viewPos[ptrDag->GetViewNumber() - 1] = i;
00110
00111
00112 if (nViewNum != ptrDag->GetViewNumber() && i < MAX_GOOD_MATCH_POS)
00113 {
00114 vw.nViewNumber = ptrDag->GetViewNumber();
00115 vw.nViewRankPos = -i - 1;
00116 vw.dVoteWeight = CompVoteWeight(vw.nViewRankPos, kBest);
00117 rec.bmviews.AddTail(vw);
00118 }
00119 }
00120 }
00121
00122
00123
00124 for (i = 0; i < neigViews.GetSize(); i++)
00125 {
00126 vw.nViewNumber = neigViews[i];
00127 vw.nViewRankPos = viewPos[vw.nViewNumber - 1];
00128 vw.dVoteWeight = CompVoteWeight(vw.nViewRankPos, kBest);
00129 rec.bmviews.AddTail(vw);
00130 }
00131
00132 m_viewVotes.append(rec);
00133 }
00134
00135 void ViewSubsampler::SaveViewWeights(const char* szDataFileName)
00136 {
00137 LockFile lockfile;
00138
00139
00140 if (!lockfile.Lock("lockfile.lck", RETRY_TIME_SECONDS))
00141 {
00142 cerr << "\nCan't lock 'lockfile.lck'. Job is cancelled" << endl;
00143 exit(1);
00144 }
00145
00146 fstream outfile(szDataFileName, ios::out | ios::app);
00147 leda_list_item it;
00148
00149 forall_items(it, m_viewVotes)
00150 m_viewVotes[it].Write(outfile);
00151
00152 outfile.close();
00153
00154 lockfile.Unlock();
00155 }
00156
00157 bool ViewSubsampler::RetrieveViewWeights(const char* szDataFileName, int nViewsPerObject, bool bRankByObject)
00158 {
00159 ObjViewArray objs;
00160 Record rec;
00161 int i;
00162
00163 fstream infile(szDataFileName, ios::in);
00164
00165 if (infile.fail())
00166 return false;
00167
00168 cerr << "Retriving subsampling info from " << szDataFileName << endl;
00169
00170 while (!infile.eof())
00171 {
00172 rec.Read(infile);
00173
00174
00175 if (!objs.defined((const char*)rec.strObjName))
00176 {
00177 VWArray& cumVotes = objs[(const char*)rec.strObjName];
00178 cumVotes.ReSize(nViewsPerObject);
00179
00180 for (i = 0; i < nViewsPerObject; i++)
00181 cumVotes[i].nViewNumber = i + 1;
00182 }
00183
00184
00185 for (i = 0; i < rec.bmviews.GetSize(); i++)
00186 {
00187 VWArray& cumVotes = objs[(const char*)rec.strObjName];
00188 VIEWWEIGHT& vw = rec.bmviews[i];
00189 VIEWWEIGHT& cumVote = cumVotes[vw.nViewNumber - 1];
00190
00191 ASSERT(cumVote.nViewNumber == vw.nViewNumber);
00192 cumVote.dVoteWeight += CompVoteWeight(vw.nViewRankPos, rec.nIndexedWithKBest);
00193 }
00194 }
00195
00196 leda_string strKey;
00197
00198
00199 if (bRankByObject)
00200 {
00201 forall_defined(strKey, objs)
00202 {
00203 VWArray& cumVotes = objs[strKey];
00204 cumVotes.Sort(VWCompare);
00205
00206 VWArray& ranViews = m_rankedObjViews[strKey];
00207 ranViews.ReSize(nViewsPerObject);
00208
00209 for (i = 0; i < cumVotes.GetSize(); i++)
00210 {
00211 VIEWWEIGHT& vw = cumVotes[i];
00212
00213 ranViews[vw.nViewNumber - 1].nViewRankPos = i;
00214 ranViews[vw.nViewNumber - 1].dVoteWeight = vw.dVoteWeight;
00215 }
00216 }
00217 }
00218 else
00219 {
00220 SmartArray<OBJVIEWWEIGHT> ovws(objs.size() * nViewsPerObject);
00221 int j = 0;
00222
00223
00224
00225 forall_defined(strKey, objs)
00226 {
00227 m_rankedObjViews[strKey].ReSize(nViewsPerObject);
00228 VWArray& cumVotes = objs[strKey];
00229 String strObjName((const char*)strKey);
00230
00231 for (i = 0; i < cumVotes.GetSize(); i++, j++)
00232 ovws[j].Set(strObjName, cumVotes[i]);
00233 }
00234
00235 ovws.Sort(VWCompare);
00236
00237 for (i = 0; i < ovws.GetSize(); i++)
00238 {
00239 OBJVIEWWEIGHT& vw = ovws[i];
00240 VWArray& ranViews = m_rankedObjViews[(const char*)vw.strObjName];
00241
00242 ranViews[vw.nViewNumber - 1].nViewRankPos = i;
00243 ranViews[vw.nViewNumber - 1].dVoteWeight = vw.dVoteWeight;
00244 }
00245 }
00246
00247 return true;
00248 }
00249
00250 double ViewSubsampler::CompVoteWeight(int nPos, int kBest) const
00251 {
00252 double w;
00253
00254 if (nPos >= 0)
00255 {
00256 if (nPos < 9)
00257 w = 0.0;
00258
00259
00260
00261
00262
00263
00264 else
00265 w = 1 + double(nPos) / double(kBest);
00266 }
00267 else
00268 {
00269
00270 nPos = -nPos - 1;
00271
00272
00273 if (nPos < 4)
00274 w = -2 + (double(nPos) / double(3));
00275 else
00276 w = 0.0;
00277 }
00278
00279 return w;
00280 }
00281
00282 int RandInRange(int a, int b)
00283 {
00284 return (int)(a + (1 + b-a )*(double)rand()/(RAND_MAX+1.0));
00285 }
00286
00287 SmartArray<int> ViewSubsampler::RandomSubsampling(int nCurViewNum, int nNewViewNum)
00288 {
00289 SmartArray<int> viewToRem(nCurViewNum);
00290 leda_list<int> list;
00291 leda_list_item it;
00292
00293 ASSERT(nCurViewNum > nNewViewNum);
00294
00295 viewToRem.Set(0);
00296
00297 for (int i = 0; i < nCurViewNum; i++)
00298 list.push(i);
00299
00300 srand((unsigned) time(NULL));
00301
00302 while (list.size() != nNewViewNum)
00303 {
00304 it = list.get_item(RandInRange(0, list.size() - 1));
00305 viewToRem[list[it]] = 1;
00306 list.del_item(it);
00307 }
00308
00309 return viewToRem;
00310 }
00311
00312