PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/src/edu/psu/chemxseer/structure/setcover/maxCoverStatus/Decomp/CoverStatus_Decomp_Index.java

https://github.com/Santa827/Chemxseer_subSearch
Java | 374 lines | 284 code | 27 blank | 63 comment | 87 complexity | 8c85464691c4cd15621f537afdd2daee MD5 | raw file
  1. package edu.psu.chemxseer.structure.setcover.maxCoverStatus.Decomp;
  2. import java.util.Arrays;
  3. import edu.psu.chemxseer.structure.setcover.interfaces.IMaxCoverInvertedIndex;
  4. import edu.psu.chemxseer.structure.setcover.maxCoverStatus.ICoverStatusStream;
  5. import edu.psu.chemxseer.structure.setcover.sets.ICoverSet_FeatureWrapper;
  6. public abstract class CoverStatus_Decomp_Index implements ICoverStatusStream,
  7. IMaxCoverInvertedIndex{
  8. protected int classOneNumber;
  9. protected int classTwoNumber;
  10. protected ICoverSet_FeatureWrapper[] selectedFeatures;
  11. protected int[] featureGain; // the gain of each feature [# of items that f covers only]
  12. protected short numOfSets; // useful when the selecteFeatures are not full
  13. // The Index: given a query(database graph),
  14. // the value list contains all features contained in it
  15. protected short[][] qfIndex;
  16. protected short[] qfSize; // Denoting the size of the qfIndex
  17. protected short[][] gfIndex;
  18. protected short[] gfSize; // Denoting the size of the gfIndex
  19. protected int[] qCovered; // qCovered[i] records the number of pairs <qCovered>, covered...
  20. protected int qCoveredMinFeatureID;
  21. /**
  22. * Initialize both the qfIndex & gfIndex
  23. * @param K
  24. * @param type
  25. * @param classOneNumber
  26. * @param classTwoNumber
  27. */
  28. public CoverStatus_Decomp_Index(int K, int classOneNumber, int classTwoNumber){
  29. this.construct(K, classOneNumber, classTwoNumber);
  30. }
  31. protected void construct(int K, int classOneNumber, int classTwoNumber){
  32. this.classOneNumber = classOneNumber;
  33. this.classTwoNumber = classTwoNumber;
  34. this.selectedFeatures = new ICoverSet_FeatureWrapper[K];
  35. this.numOfSets = 0;
  36. // Construct the Inverted Index
  37. this.qfIndex = new short[classTwoNumber][];
  38. this.qfSize = new short[classTwoNumber];
  39. this.gfIndex = new short[classOneNumber][];
  40. this.gfSize = new short[classOneNumber];
  41. for(int i = 0; i< classTwoNumber; i++)
  42. qfSize[i] = 0;
  43. for(int i = 0; i< classOneNumber; i++)
  44. gfSize[i] = 0;
  45. this.featureGain = new int[K];
  46. for(int i = 0; i< K; i++)
  47. featureGain[i] = 0; // ass the 0 as the initial value
  48. }
  49. protected void saveSpace(){
  50. for(int i = 0; i< classTwoNumber; i++){
  51. if(qfIndex[i].length > qfSize[i]){
  52. short[] temp = new short[qfSize[i]];
  53. for(int w = 0; w < temp.length; w++){
  54. temp[w] = qfIndex[i][w];
  55. }
  56. this.qfIndex[i] = temp;
  57. }
  58. }
  59. for(int i = 0; i< classOneNumber; i++){
  60. if(gfIndex[i].length > gfSize[i]){
  61. short[] temp = new short[gfSize[i]];
  62. for(int w = 0; w < temp.length; w++){
  63. temp[w] = gfIndex[i][w];
  64. }
  65. this.gfIndex[i] = temp;
  66. }
  67. }
  68. }
  69. @Override
  70. public int[] getCoveredCountExceptMin(short minSetID, int[] yIDs) {
  71. if(this.qCoveredMinFeatureID == this.selectedFeatures[minSetID].getFetureID()){
  72. int[] result = new int[yIDs.length];
  73. for(int i = 0; i< yIDs.length; i++)
  74. result[i] = this.qCovered[yIDs[i]];
  75. return result;
  76. }
  77. else{
  78. System.out.println("The getCoveredCountExceptMin count can not be answered directly");
  79. return null;
  80. }
  81. }
  82. @Override
  83. public short leastCoverSet(int[] minSize) {
  84. //Sequential Scan of all the selected features, find the one with the minimum score
  85. // Other implementations: with priority queue, can be implemented, however we leave that in TODO:
  86. minSize[0] = Integer.MAX_VALUE;
  87. short minFeature = -1;
  88. for(short i = 0; i< this.selectedFeatures.length; i++){
  89. if(selectedFeatures[i] == null)
  90. continue;
  91. else if(this.featureGain[i] < minSize[0]){
  92. minSize[0] = featureGain[i];
  93. minFeature = i;
  94. }
  95. }
  96. return minFeature;
  97. }
  98. @Override
  99. public ICoverSet_FeatureWrapper[] getSelectedSets() {
  100. return this.selectedFeatures;
  101. }
  102. @Override
  103. public ICoverSet_FeatureWrapper getSelectedSet(short minSetID) {
  104. return this.selectedFeatures[minSetID];
  105. }
  106. /**
  107. * private "partial" operation for addNewSet
  108. * @param newSet
  109. * @return
  110. */
  111. protected boolean addNewSetPrivate(ICoverSet_FeatureWrapper newSet) {
  112. if(this.numOfSets < this.selectedFeatures.length){
  113. this.selectedFeatures[numOfSets] = newSet;
  114. // update the index
  115. for(int qID : newSet.containedQueryGraphs())
  116. this.insertValueToQindex(numOfSets, qID);
  117. for(int gID : newSet.containedDatabaseGraphs())
  118. this.insertValueToGindex(numOfSets, gID);
  119. numOfSets++;
  120. return true;
  121. }
  122. else{
  123. System.out.println("No Enough Space: try swap");
  124. return false;
  125. }
  126. }
  127. /**
  128. * private "partial" operation for set one set to position id
  129. * @param oneSet
  130. * @param sID
  131. * @return
  132. */
  133. protected boolean addFeaturePrivate(ICoverSet_FeatureWrapper oneSet, short sID) {
  134. if(this.selectedFeatures[sID] == null){
  135. this.selectedFeatures[sID] = oneSet;
  136. // update the index
  137. for(int qID : oneSet.containedQueryGraphs())
  138. this.insertValueToQindex(sID, qID);
  139. for(int gID : oneSet.containedDatabaseGraphs())
  140. this.insertValueToGindex(sID, gID);
  141. return true;
  142. }
  143. else return false;
  144. }
  145. /**
  146. * private "partial" operation for removing one set with sID
  147. * @param sID
  148. * @return
  149. */
  150. protected boolean removeFeaturePrivate(short sID) {
  151. if(this.selectedFeatures[sID] == null){
  152. return false;
  153. }
  154. else{
  155. ICoverSet_FeatureWrapper oneSet = selectedFeatures[sID];
  156. selectedFeatures[sID] = null;
  157. // update the index
  158. for(int qID : oneSet.containedQueryGraphs())
  159. this.removeValueFromQindex(sID, qID);
  160. for(int gID : oneSet.containedDatabaseGraphs())
  161. this.removeValueFromGindex(sID, gID);
  162. return true;
  163. }
  164. }
  165. /**
  166. * private "partial" operation for swap two sets
  167. * @param oldSetID
  168. * @param newSet
  169. * @return
  170. */
  171. protected boolean swapPrivate(short oldSetID, ICoverSet_FeatureWrapper newSet) {
  172. long start = System.currentTimeMillis();
  173. ICoverSet_FeatureWrapper oldSet = this.selectedFeatures[oldSetID];
  174. if(oldSet == null){
  175. System.out.println("Wrong input for Swap: invalide oldSetID");
  176. return false;
  177. }
  178. this.selectedFeatures[oldSetID] = newSet;
  179. // update the Qindex
  180. int[] oldQueries = oldSet.containedQueryGraphs();
  181. int[] newQueries = newSet.containedQueryGraphs();
  182. int i = 0, j = 0;
  183. for(; i< oldQueries.length && j<newQueries.length; ){
  184. if(oldQueries[i] == newQueries[j]){
  185. i++; j++;
  186. }
  187. else if(oldQueries[i] < newQueries[j]){
  188. this.removeValueFromQindex(oldSetID, oldQueries[i]);
  189. i++;
  190. }
  191. else{ // oldQueries[i] > newQueries[j]
  192. this.insertValueToQindex(oldSetID, newQueries[j]);
  193. j++;
  194. }
  195. }
  196. for(; i< oldQueries.length;i++)
  197. this.removeValueFromQindex(oldSetID, oldQueries[i]);
  198. for(; j < newQueries.length; j++)
  199. this.insertValueToQindex(oldSetID, newQueries[j]);
  200. // update the Gindex
  201. int[] oldGraphs = oldSet.containedDatabaseGraphs();
  202. int[] newGraphs = newSet.containedDatabaseGraphs();
  203. for(i = 0, j = 0; i< oldGraphs.length && j<newGraphs.length; ){
  204. if(oldGraphs[i] == newGraphs[j]){
  205. i++; j++;
  206. }
  207. else if(oldGraphs[i] < newGraphs[j]){
  208. this.removeValueFromGindex(oldSetID, oldGraphs[i]);
  209. i++;
  210. }
  211. else{ // oldQueries[i] > newQueries[j]
  212. this.insertValueToGindex(oldSetID, newGraphs[j]);
  213. j++;
  214. }
  215. }
  216. for(; i< oldGraphs.length; i++)
  217. this.removeValueFromGindex(oldSetID, oldGraphs[i]);
  218. for(; j < newGraphs.length; j++)
  219. this.removeValueFromGindex(oldSetID, newGraphs[j]);
  220. System.out.println("Swap Time: " + (System.currentTimeMillis()-start));
  221. return true;
  222. }
  223. /****************For Inverted Index Maintenance ***************/
  224. /**
  225. * add a value, maintain the order
  226. * @param value
  227. * @param qID
  228. */
  229. private void insertValueToQindex(short value, int qID){
  230. if(this.qfIndex[qID] == null){
  231. this.qfIndex[qID] = new short[4];
  232. qfIndex[qID][qfSize[qID]++] = value;
  233. }
  234. else if(this.qfSize[qID] == this.qfIndex[qID].length){
  235. short[] newEntry = new short[qfSize[qID] * 2];
  236. int i = 0;
  237. for(; i < qfSize[qID] && qfIndex[qID][i]<value; i++)
  238. newEntry[i] = qfIndex[qID][i];
  239. newEntry[i] = value;
  240. for(; i< qfSize[qID]; i++)
  241. newEntry[i+1] = qfIndex[qID][i];
  242. qfIndex[qID] = newEntry;
  243. qfSize[qID]++;
  244. }
  245. else{
  246. //1. Binary Search the position of "value"
  247. int pos = Arrays.binarySearch(qfIndex[qID], 0, qfSize[qID], value);
  248. pos = -pos-1;
  249. assert pos >=0;
  250. //2. Insert the new value
  251. for(int i = qfSize[qID]-1; i >=pos; i--)
  252. qfIndex[qID][i+1] = qfIndex[qID][i];
  253. qfIndex[qID][pos] = value;
  254. qfSize[qID]++;
  255. }
  256. }
  257. private void insertValueToGindex(short value, int gID){
  258. if(this.gfIndex[gID] == null){
  259. this.gfIndex[gID] = new short[4];
  260. gfIndex[gID][gfSize[gID]++] = value;
  261. }
  262. else if(this.gfSize[gID] == this.gfIndex[gID].length){
  263. short[] newEntry = new short[gfSize[gID] * 2];
  264. int i = 0;
  265. for(; i < gfSize[gID] && gfIndex[gID][i]<value; i++)
  266. newEntry[i] = gfIndex[gID][i];
  267. newEntry[i] = value;
  268. for(; i< gfSize[gID]; i++)
  269. newEntry[i+1] = gfIndex[gID][i];
  270. gfIndex[gID] = newEntry;
  271. gfSize[gID]++;
  272. }
  273. else{
  274. //1. Binary Search the position of "value"
  275. int pos = Arrays.binarySearch(gfIndex[gID], 0, gfSize[gID], value);
  276. pos = -pos-1;
  277. assert pos >=0;
  278. //2. Insert the new value
  279. for(int i = gfSize[gID]-1; i >=pos; i--)
  280. gfIndex[gID][i+1] = gfIndex[gID][i];
  281. gfIndex[gID][pos] = value;
  282. gfSize[gID]++;
  283. }
  284. }
  285. /**
  286. * remove the value, maintain the order
  287. * @param value
  288. * @param qID
  289. */
  290. private void removeValueFromQindex(short value, int qID){
  291. if(qfSize[qID] == 1)
  292. qfSize[qID] = 0;
  293. else if(2 * this.qfSize[qID] == this.qfIndex[qID].length){
  294. short[] newEntry = new short[qfSize[qID]];
  295. int iter = 0;
  296. for(int i = 0; i< qfSize[qID]; i++){
  297. if(qfIndex[qID][i] == value)
  298. continue;
  299. else newEntry[iter++] = qfIndex[qID][i];
  300. }
  301. qfIndex[qID] = newEntry;
  302. qfSize[qID]--;
  303. assert(iter == qfSize[qID]);
  304. }
  305. else{
  306. //1. Binary Search the position of "value"
  307. int pos = Arrays.binarySearch(qfIndex[qID], 0, qfSize[qID], value);
  308. assert (pos >= 0);
  309. //2. Remove the Value: maintain the order
  310. for(int i = pos+1; i < qfSize[qID]; i++){
  311. qfIndex[i-1] = qfIndex[i];
  312. }
  313. qfSize[qID]--;
  314. }
  315. }
  316. /**
  317. * Remove the value, maitain the order
  318. * @param value
  319. * @param gID
  320. */
  321. private void removeValueFromGindex(short value, int gID){
  322. if(this.gfSize[gID] == 1)
  323. gfSize[gID] = 0;
  324. else if(2 * this.gfSize[gID] == this.gfIndex[gID].length){
  325. short[] newEntry = new short[gfSize[gID]];
  326. int iter = 0;
  327. for(int i = 0; i< gfSize[gID]; i++){
  328. if(gfIndex[gID][i] == value)
  329. continue;
  330. else newEntry[iter++] = gfIndex[gID][i];
  331. }
  332. gfIndex[gID] = newEntry;
  333. gfSize[gID]--;
  334. assert(iter == gfSize[gID]);
  335. }
  336. else{
  337. //1. Binary Search the position of "value"
  338. int pos = Arrays.binarySearch(gfIndex[gID], 0, gfSize[gID], value);
  339. assert (pos >= 0);
  340. //2. Remove the Value: maintain the order
  341. for(int i = pos+1; i < gfSize[gID]; i++){
  342. gfIndex[i-1] = gfIndex[i];
  343. }
  344. gfSize[gID]--;
  345. }
  346. }
  347. }