genmodel 0.0.27 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/Genmodel/BitVector.cpp +725 -0
- data/ext/Genmodel/BitVector.h +172 -0
- data/ext/Genmodel/Genmodel.cpp +20266 -13263
- data/ext/Genmodel/GraphTools.cpp +211 -0
- data/ext/Genmodel/GraphTools.h +49 -0
- data/ext/Genmodel/extconf.rb +40 -7
- data/lib/Genmodel.rb +1 -1
- metadata +5 -1
@@ -0,0 +1,211 @@
|
|
1
|
+
//
|
2
|
+
// GraphTools.cpp
|
3
|
+
//
|
4
|
+
//
|
5
|
+
// Created by Mathieu Bouchard on 2014-03-21.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
#include <GraphTools.h>
|
10
|
+
#include <lemon/list_graph.h>
|
11
|
+
#include <stdlib.h>
|
12
|
+
#include <time.h>
|
13
|
+
|
14
|
+
# define n_id nodeFromId
|
15
|
+
# define e_id edgeFromId
|
16
|
+
|
17
|
+
vector<vector<size_t> > GmGraph::GetCliqueCover()
|
18
|
+
{
|
19
|
+
size_t n = countNodes(g);
|
20
|
+
size_t e = countEdges(g);
|
21
|
+
vector<vector<size_t> > out;
|
22
|
+
|
23
|
+
vector<bool> done(e,false);
|
24
|
+
size_t curr_e = 0;
|
25
|
+
size_t added = 0;
|
26
|
+
while(true)
|
27
|
+
{
|
28
|
+
while(curr_e < e && done[curr_e])
|
29
|
+
++curr_e;
|
30
|
+
|
31
|
+
if(curr_e == e)
|
32
|
+
break;
|
33
|
+
done[curr_e] = true;
|
34
|
+
added++;
|
35
|
+
//printf("curr_e = %ld (added = %ld)\n", curr_e, added);
|
36
|
+
|
37
|
+
vector<bool> node_in(n,false);
|
38
|
+
vector<size_t> node_depth(n,0);
|
39
|
+
|
40
|
+
vector<size_t> clique;
|
41
|
+
size_t curr_n = g.id(g.u(g.e_id(curr_e)));
|
42
|
+
size_t next_n = g.id(g.v(g.e_id(curr_e)));
|
43
|
+
|
44
|
+
//ve.push_back(e);
|
45
|
+
|
46
|
+
clique.push_back(curr_n);
|
47
|
+
node_in[curr_n] = true;
|
48
|
+
|
49
|
+
vector<size_t> dc = in(curr_n);
|
50
|
+
for(size_t i = 0; i < dc.size(); i++)
|
51
|
+
++(node_depth[dc[i]]);
|
52
|
+
size_t depth = 1;
|
53
|
+
|
54
|
+
while(next_n != -1 && depth < e*e)
|
55
|
+
{
|
56
|
+
//printf("1-Add %ld (depth %ld)\n", next_n, depth);
|
57
|
+
|
58
|
+
clique.push_back(next_n);
|
59
|
+
node_in[next_n] = true;
|
60
|
+
vector<size_t> de = ie(next_n);
|
61
|
+
depth++;
|
62
|
+
curr_n = next_n;
|
63
|
+
next_n = -1;
|
64
|
+
size_t next_nn = -1;
|
65
|
+
for(size_t i = 0; i < de.size(); i++)
|
66
|
+
{
|
67
|
+
size_t nn = (g.id(g.u(g.e_id(de[i]))) == curr_n ? g.id(g.v(g.e_id(de[i]))) : g.id(g.u(g.e_id(de[i]))));
|
68
|
+
size_t onn = (g.id(g.u(g.e_id(de[i]))) == curr_n ? g.id(g.u(g.e_id(de[i]))) : g.id(g.v(g.e_id(de[i]))));
|
69
|
+
++(node_depth[nn]);
|
70
|
+
if(node_in[nn] && !done[de[i]])
|
71
|
+
{
|
72
|
+
done[de[i]] = true;
|
73
|
+
added++;
|
74
|
+
//printf("\t2-From %ld : Add edge %ld (depth %ld) [added = %ld] d=%ld --> %ld (other = %ld)\n", curr_n, de[i], depth, added, de.size(), nn, onn);
|
75
|
+
}
|
76
|
+
if(node_depth[nn] == depth && next_n == -1 && !done[de[i]] && !node_in[nn])
|
77
|
+
{
|
78
|
+
next_n = nn;
|
79
|
+
done[de[i]] = true;
|
80
|
+
added++;
|
81
|
+
//printf("\t3-Add edge %ld (depth %ld) [added = %ld]\n", de[i], depth, added);
|
82
|
+
}
|
83
|
+
else if(node_depth[nn] == depth && next_n == -1 && !node_in[nn])
|
84
|
+
{
|
85
|
+
next_nn = nn;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
if (next_n == -1)
|
89
|
+
next_n = next_nn;
|
90
|
+
}
|
91
|
+
if (depth == e*e)
|
92
|
+
throw string("GmGraph::GetCliqueCover : Max depth reached");
|
93
|
+
out.push_back(clique);
|
94
|
+
if(added >= e)
|
95
|
+
break;
|
96
|
+
}
|
97
|
+
if(added < e)
|
98
|
+
throw string("GmGraph::GetCliqueCover : The graph was not covered by clique.");
|
99
|
+
//printf("Finish %ld!\n", added);
|
100
|
+
|
101
|
+
return out;
|
102
|
+
}
|
103
|
+
|
104
|
+
vector<size_t> GmGraph::ie(size_t i)
|
105
|
+
{
|
106
|
+
vector<size_t> out(di(i));
|
107
|
+
size_t ii = 0;
|
108
|
+
for (ListGraph::IncEdgeIt _e(g, g.n_id(i)); _e != INVALID; ++_e, ++ii)
|
109
|
+
out[ii] = (g.id(_e)-g.id(_e)%2)/2;
|
110
|
+
return out;
|
111
|
+
}
|
112
|
+
|
113
|
+
BitVector GmGraph::ie2bv(size_t i)
|
114
|
+
{
|
115
|
+
BitVector out(countEdges(g)*2);
|
116
|
+
for (ListGraph::IncEdgeIt _e(g, g.n_id(i)); _e != INVALID; ++_e)
|
117
|
+
out.set((g.id(_e)-g.id(_e)%2)/2, true);
|
118
|
+
return out;
|
119
|
+
}
|
120
|
+
|
121
|
+
vector<size_t> GmGraph::in(size_t i)
|
122
|
+
{
|
123
|
+
vector<size_t> out(di(i));
|
124
|
+
size_t ii = 0;
|
125
|
+
for (ListGraph::IncEdgeIt _e(g, g.n_id(i)); _e != INVALID; ++_e, ++ii)
|
126
|
+
out[ii] = (g.id(g.u(_e)) == i ? g.id(g.v(_e)) : g.id(g.u(_e)));
|
127
|
+
return out;
|
128
|
+
}
|
129
|
+
|
130
|
+
BitVector GmGraph::in2bv(size_t i)
|
131
|
+
{
|
132
|
+
BitVector out(countNodes(g));
|
133
|
+
for (ListGraph::IncEdgeIt _e(g, g.n_id(i)); _e != INVALID; ++_e)
|
134
|
+
(g.id(g.u(_e)) == i ? out.set(g.id(g.v(_e)),true) : out.set(g.id(g.u(_e)),true));
|
135
|
+
return out;
|
136
|
+
}
|
137
|
+
|
138
|
+
|
139
|
+
size_t GmGraph::n()
|
140
|
+
{
|
141
|
+
return countNodes(g);
|
142
|
+
}
|
143
|
+
|
144
|
+
size_t GmGraph::e()
|
145
|
+
{
|
146
|
+
return countEdges(g);
|
147
|
+
}
|
148
|
+
|
149
|
+
size_t GmGraph::di(size_t i)
|
150
|
+
{
|
151
|
+
return countIncEdges(g, g.n_id(i));
|
152
|
+
}
|
153
|
+
|
154
|
+
size_t GmGraph::AddNode()
|
155
|
+
{
|
156
|
+
return g.id(g.addNode());
|
157
|
+
}
|
158
|
+
|
159
|
+
size_t GmGraph::AddEdge(size_t i, size_t j)
|
160
|
+
{
|
161
|
+
return g.id(g.addEdge(g.n_id(i), g.n_id(j)));
|
162
|
+
}
|
163
|
+
|
164
|
+
size_t GmGraph::u(size_t i)
|
165
|
+
{
|
166
|
+
return g.id(g.u(g.e_id(i)));
|
167
|
+
}
|
168
|
+
size_t GmGraph::v(size_t i)
|
169
|
+
{
|
170
|
+
return g.id(g.v(g.e_id(i)));
|
171
|
+
}
|
172
|
+
|
173
|
+
void GmGraph::EraseNode(size_t i)
|
174
|
+
{
|
175
|
+
g.erase(g.n_id(i));
|
176
|
+
}
|
177
|
+
|
178
|
+
void GmGraph::EraseEdge(size_t i)
|
179
|
+
{
|
180
|
+
g.erase(g.e_id(i));
|
181
|
+
}
|
182
|
+
|
183
|
+
void GmGraph::ChangeU(size_t i, size_t j)
|
184
|
+
{
|
185
|
+
g.changeU(g.e_id(i),g.n_id(j));
|
186
|
+
}
|
187
|
+
|
188
|
+
void GmGraph::ChangeV(size_t i, size_t j)
|
189
|
+
{
|
190
|
+
g.changeV(g.e_id(i),g.n_id(j));
|
191
|
+
}
|
192
|
+
|
193
|
+
void GmGraph::Contract(size_t i, size_t j, bool r)
|
194
|
+
{
|
195
|
+
g.contract(g.n_id(i), g.n_id(j), r);
|
196
|
+
}
|
197
|
+
|
198
|
+
void GmGraph::Clear()
|
199
|
+
{
|
200
|
+
g.clear();
|
201
|
+
}
|
202
|
+
|
203
|
+
void GmGraph::ReserveNode(size_t n)
|
204
|
+
{
|
205
|
+
g.reserveNode(n);
|
206
|
+
}
|
207
|
+
|
208
|
+
void GmGraph::ReserveEdge(size_t m)
|
209
|
+
{
|
210
|
+
g.reserveEdge(2 * m);
|
211
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
//
|
2
|
+
// GraphTools.h
|
3
|
+
//
|
4
|
+
//
|
5
|
+
// Created by Mathieu Bouchard on 2014-03-21.
|
6
|
+
//
|
7
|
+
//
|
8
|
+
|
9
|
+
#ifndef _GraphTools_h
|
10
|
+
#define _GraphTools_h
|
11
|
+
|
12
|
+
#include <lemon/concepts/graph.h>
|
13
|
+
#include <lemon/list_graph.h>
|
14
|
+
#include "BitVector.h"
|
15
|
+
|
16
|
+
using namespace lemon;
|
17
|
+
using namespace std;
|
18
|
+
|
19
|
+
class GmGraph
|
20
|
+
{
|
21
|
+
public:
|
22
|
+
GmGraph() {}
|
23
|
+
~GmGraph() {}
|
24
|
+
size_t AddNode();
|
25
|
+
size_t AddEdge(size_t i, size_t j);
|
26
|
+
void EraseNode(size_t i);
|
27
|
+
void EraseEdge(size_t i);
|
28
|
+
void ChangeU(size_t i, size_t j);
|
29
|
+
void ChangeV(size_t i, size_t j);
|
30
|
+
size_t u(size_t i);
|
31
|
+
size_t v(size_t i);
|
32
|
+
void Contract(size_t i, size_t j, bool r = true);
|
33
|
+
void Clear();
|
34
|
+
void ReserveNode(size_t n);
|
35
|
+
void ReserveEdge(size_t m);
|
36
|
+
size_t n();
|
37
|
+
size_t e();
|
38
|
+
size_t di(size_t i);
|
39
|
+
vector<size_t> ie(size_t i);
|
40
|
+
vector<size_t> in(size_t i);
|
41
|
+
BitVector ie2bv(size_t i);
|
42
|
+
BitVector in2bv(size_t i);
|
43
|
+
|
44
|
+
vector<vector<size_t> > GetCliqueCover();
|
45
|
+
|
46
|
+
ListGraph g;
|
47
|
+
};
|
48
|
+
|
49
|
+
#endif
|
data/ext/Genmodel/extconf.rb
CHANGED
@@ -68,16 +68,16 @@ if is_darwin
|
|
68
68
|
end
|
69
69
|
|
70
70
|
#path = "/usr/local/Cellar/cbc/2.8.6/include/coin/"+sep+"/usr/local/Cellar/cgl/0.58.3/include/coin/"
|
71
|
-
|
72
|
-
|
73
|
-
puts "Looking for OsiClpSolverInterface.hpp in "+
|
71
|
+
search_path = "/usr/local/Cellar/cbc/"
|
72
|
+
search_file = "/include/coin/OsiClpSolverInterface.hpp"
|
73
|
+
puts "Looking for OsiClpSolverInterface.hpp in "+search_path+"/*"
|
74
74
|
file_exist = nil
|
75
|
-
Find.find(
|
75
|
+
Find.find(search_path) do |path|
|
76
76
|
if (FileTest.directory?(path))
|
77
|
-
puts path+
|
77
|
+
puts path+search_file
|
78
78
|
temp_name = (path).gsub(/\/usr\/local\/Cellar\/cbc\//,'')
|
79
79
|
count = temp_name.count('/')
|
80
|
-
if ((count == 0) && (File.exist?(path+
|
80
|
+
if ((count == 0) && (File.exist?(path+search_file)))
|
81
81
|
file_exist = "-I#{path}/include/coin"
|
82
82
|
break
|
83
83
|
end
|
@@ -91,6 +91,30 @@ if is_darwin
|
|
91
91
|
is_osi = false
|
92
92
|
end
|
93
93
|
|
94
|
+
search_path = "/usr/local/Cellar/lemon-graph/"
|
95
|
+
search_file = "/include/lemon/core.h"
|
96
|
+
puts "Looking for lemon/core.h in "+search_path+"/*"
|
97
|
+
file_exist = nil
|
98
|
+
Find.find(search_path) do |path|
|
99
|
+
if (FileTest.directory?(path))
|
100
|
+
puts path+search_file
|
101
|
+
temp_name = (path).gsub(/\/usr\/local\/Cellar\/lemon-graph\//,'')
|
102
|
+
count = temp_name.count('/')
|
103
|
+
if ((count == 0) && (File.exist?(path+search_file)))
|
104
|
+
file_exist = "-I#{path}/include"
|
105
|
+
break
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if(is_osi && file_exist != nil)
|
110
|
+
$INCFLAGS << " " << file_exist.quote
|
111
|
+
puts "found"
|
112
|
+
else
|
113
|
+
puts "not found"
|
114
|
+
is_osi = false
|
115
|
+
end
|
116
|
+
|
117
|
+
|
94
118
|
path = "/usr/lib:/usr/local/lib/"
|
95
119
|
puts "Looking for Clp (function main) in "+path
|
96
120
|
if(is_osi && find_library("Clp",nil,path))
|
@@ -145,6 +169,15 @@ if is_darwin
|
|
145
169
|
#is_osi = false
|
146
170
|
end
|
147
171
|
|
172
|
+
path = "/usr/lib:/usr/local/lib/"
|
173
|
+
puts "Looking for libemon.dylib (function main) in "+path
|
174
|
+
if(is_osi && find_library("emon",nil,path))
|
175
|
+
puts "found"
|
176
|
+
else
|
177
|
+
puts "not found"
|
178
|
+
is_osi = false
|
179
|
+
end
|
180
|
+
|
148
181
|
elsif is_linux
|
149
182
|
# path = Dir.home+"/ibm/ILOG/CPLEX_Studio126/cplex/include:/opt/ibm/ILOG/CPLEX_Studio126/cplex/include"
|
150
183
|
path = "/opt/ibm/ILOG/CPLEX_Studio126/cplex/include"
|
@@ -245,6 +278,6 @@ if(is_osi)
|
|
245
278
|
$defs.push("-DOSI_MODULE")
|
246
279
|
end
|
247
280
|
|
248
|
-
|
281
|
+
#swig -ruby -o ext/GenModelGem/Genmodel.cpp -c++ src/Genmodel.i
|
249
282
|
|
250
283
|
create_makefile (extension_name)
|
data/lib/Genmodel.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: genmodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathieu Bouchard
|
@@ -17,6 +17,8 @@ extensions:
|
|
17
17
|
- ext/Genmodel/extconf.rb
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- ext/Genmodel/BitVector.cpp
|
21
|
+
- ext/Genmodel/BitVector.h
|
20
22
|
- ext/Genmodel/GenModel.h
|
21
23
|
- ext/Genmodel/GenModelBase.cpp
|
22
24
|
- ext/Genmodel/GenModelCplex.cpp
|
@@ -26,6 +28,8 @@ files:
|
|
26
28
|
- ext/Genmodel/GenModelOsiInterface.cpp
|
27
29
|
- ext/Genmodel/GenModelOsiInterface.h
|
28
30
|
- ext/Genmodel/Genmodel.cpp
|
31
|
+
- ext/Genmodel/GraphTools.cpp
|
32
|
+
- ext/Genmodel/GraphTools.h
|
29
33
|
- ext/Genmodel/ProblemReaderOsi.cpp
|
30
34
|
- ext/Genmodel/ProblemReaderOsi.h
|
31
35
|
- ext/Genmodel/extconf.rb
|