-
Notifications
You must be signed in to change notification settings - Fork 0
/
hashsplitset.h
145 lines (122 loc) · 3.98 KB
/
hashsplitset.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/***************************************************************************
* Copyright (C) 2006 by BUI Quang Minh, Steffen Klaere, Arndt von Haeseler *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef HASHSPLITSET_H
#define HASHSPLITSET_H
#include "tools.h"
#include "split.h"
using namespace std;
class SplitGraph;
#ifdef USE_HASH_MAP
/*
Define the hash function of Split
*/
struct hashfunc_Split {
size_t operator()(const Split* sp) const {
size_t sum = 0;
for (Split::const_iterator it = sp->begin(); it != sp->end(); it++)
sum = (*it) + (sum << 6) + (sum << 16) - sum;
return sum;
}
};
#endif // USE_HASH_MAP
namespace std {
/**
Define equal_to of two splits, used for hash_set (or hash_map) template
*/
template<>
struct equal_to<Split*> {
/**
@return true if *s1 == *s2
@param s1 first split
@param s2 second split
*/
bool operator()(const Split* s1, const Split* s2) const{
return *s1 == *s2;
}
};
/**
Define less than relationship of two splits, used for set (or map) template
*/
template<>
struct less<Split*> {
/**
@return true if *s1 < *s2 alphabetically
@param s1 first split
@param s2 second split
*/
bool operator()(const Split *s1, const Split *s2) const {
assert(s1->size() == s2->size());
for (int i = 0; i < s1->size(); i++)
if ((*s1)[i] < (*s2)[i])
return true;
else if ((*s1)[i] > (*s2)[i]) return false;
return false;
}
};
} // namespace std
/**
SplitSet for quick search purpose
@author BUI Quang Minh, Steffen Klaere, Arndt von Haeseler
*/
#ifdef USE_HASH_MAP
class SplitIntMap : public unordered_map<Split*, int, hashfunc_Split>
#else
class SplitIntMap : map<Split*, int, std::less<Split*> >
#endif
{
public:
/**
find a split
@param sp target split
@return the split containing the same set of taxa with sp, NULL if not found
*/
Split *findSplit(Split *sp);
/**
find a split
@param sp target split
@param value (OUT) associated value
@return the split containing the same set of taxa with sp, NULL if not found
*/
Split *findSplit(Split *sp, int &value);
int getValue(Split *sp);
void setValue(Split *sp, int value);
void eraseSplit(Split *sp);
void insertSplit(Split *sp, int value);
/**
* build a map from the input split graph
* @param sg input split graph
* @param use_index TRUE to map to index of splits in sg, FALSE to map to split weights
*/
void buildMap(SplitGraph &sg, bool use_index = true);
int getNumTree() {
return numTree;
}
void setNumTree(int maxValue) {
this->numTree = maxValue;
}
private:
/**
* The maximum weight value. If the splits are generated from n trees and splits of every tree
* all have weight = 1, then maxValue = n
* This variable is used to determine whether a split appear on all input trees.
*/
int numTree;
};
#endif