Skip to content

Commit 3bb862e

Browse files
author
spupyrev
committed
initial
1 parent e0b4006 commit 3bb862e

14 files changed

+2595
-0
lines changed

Makefile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Variables
2+
CXX = g++
3+
CXXFLAGS = -Isrc -Wall -Wno-unknown-pragmas -O3 -std=c++11
4+
5+
HEADERS = $(wildcard **/*.h)
6+
7+
SOURCES = $(wildcard src/*.cpp)
8+
9+
# Targets
10+
TARGET = be
11+
12+
OBJECTS = $(SOURCES:src/%.cpp=build/%.o)
13+
14+
## Default rule executed
15+
all: $(TARGET)
16+
@true
17+
18+
## Clean Rule
19+
clean:
20+
$(RM) $(TARGET) $(OBJECTS)
21+
22+
noomp: $(TARGET)
23+
@true
24+
25+
## Rule for making the actual target
26+
$(TARGET): $(OBJECTS)
27+
@echo "Linking object files to target $@..."
28+
$(CXX) $(LDFLAGS) -o $@ $^
29+
@echo "-- Link finished --"
30+
31+
## Generic compilation rule for object files from cpp files
32+
build/%.o : src/%.cpp $(HEADERS) Makefile
33+
@mkdir -p $(dir $@)
34+
$(CXX) $(CXXFLAGS) -c $< -o $@

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Book Embedding
2+
================
3+
BE is a tool for constructing optimal linear layouts of graphs. With a modern SAT solver, it is capable to compute optimal layouts of graphs with hundreds of vertices within several minutes.
4+
5+
Visit http://be.cs.arizona.edu for an interactive demo.
6+
7+
Basic Setup
8+
--------
9+
10+
1. Compile the library by running:
11+
12+
make
13+
14+
2. Run the tool:
15+
16+
./be -i=graph.dot -o=graph.dimacs -type=stack -pages=2 -verbose=true
17+
18+
The tool accepts graphs in the [DOT](https://en.wikipedia.org/wiki/DOT_(graph_description_language)) and [GML](https://en.wikipedia.org/wiki/Graph_Modelling_Language) formats. The output is the [DIMACS](http://www.satcompetition.org/2009/format-benchmarks2009.html) format.
19+
For the list of supported options use:
20+
21+
./be -help
22+
23+
3. Download and setup a SAT solver such as [Lingeling](http://fmv.jku.at/lingeling) or [Glucose](http://www.labri.fr/perso/lsimon/glucose)
24+
25+
4. Use the SAT solver to test embeddability of the graph:
26+
27+
./treengeling graph.dimacs
28+
29+
License
30+
--------
31+
Code is released under the [MIT License](MIT-LICENSE.txt).

src/cmd_options.h

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#pragma once
2+
3+
#include "common.h"
4+
5+
#include <iostream>
6+
#include <string>
7+
#include <vector>
8+
#include <set>
9+
#include <map>
10+
#include <algorithm>
11+
#include <memory>
12+
#include <cassert>
13+
14+
class CMDOptions
15+
{
16+
private:
17+
std::string usageMessage;
18+
std::map<std::string, std::string> options;
19+
20+
std::map<std::string, std::string> allowedOptions;
21+
std::vector<std::string> allowedOptionsOrder;
22+
std::map<std::string, std::string> defaultValues;
23+
std::map<std::string, std::vector<std::string> > allowedValues;
24+
25+
CMDOptions(const CMDOptions&);
26+
CMDOptions& operator = (const CMDOptions&);
27+
CMDOptions() {}
28+
29+
public:
30+
static std::unique_ptr<CMDOptions> Create()
31+
{
32+
return std::unique_ptr<CMDOptions>(new CMDOptions());
33+
}
34+
35+
void Parse(int argc, char **argv)
36+
{
37+
for (int i = 1; i < argc; i++)
38+
{
39+
std::string s(argv[i]);
40+
if (s == "/?" || s == "-?" || s == "--help" || s == "-help")
41+
{
42+
Usage(argv[0]);
43+
throw 0;
44+
}
45+
46+
SetOption(s);
47+
}
48+
}
49+
50+
void SetUsageMessage(const std::string& msg)
51+
{
52+
usageMessage = msg;
53+
}
54+
55+
void SetOption(const std::string& s)
56+
{
57+
size_t equalIndex = s.find('=');
58+
std::string name = s.substr(0, equalIndex);
59+
if (!allowedOptions.count(name))
60+
{
61+
if (equalIndex == std::string::npos && allowedOptions.count(""))
62+
{
63+
options[""] = name;
64+
return;
65+
}
66+
67+
UnrecognizedOption(name);
68+
}
69+
70+
std::string value = (equalIndex == std::string::npos ? "" : s.substr(equalIndex + 1));
71+
72+
if (!options.count(name) || (defaultValues.count(name) && options[name] == defaultValues[name]))
73+
options[name] = value;
74+
75+
if (!allowedValues[name].empty() && !count(allowedValues[name].begin(), allowedValues[name].end(), value))
76+
InvalidOption(name);
77+
}
78+
79+
void AddAllowedOption(const std::string& optionName, const std::string& defaultValue, const std::string& description)
80+
{
81+
AddAllowedOption(optionName, description);
82+
options[optionName] = defaultValue;
83+
defaultValues[optionName] = defaultValue;
84+
}
85+
86+
void AddAllowedOption(const std::string& optionName, const std::string& description)
87+
{
88+
assert(!allowedOptions.count(optionName));
89+
allowedOptions[optionName] = description;
90+
allowedOptionsOrder.push_back(optionName);
91+
}
92+
93+
void AddAllowedValue(const std::string& optionName, const std::string& value)
94+
{
95+
assert(allowedOptions.count(optionName));
96+
allowedValues[optionName].push_back(value);
97+
}
98+
99+
std::string getOption(const std::string& optionName) const
100+
{
101+
if (!options.count(optionName)) {
102+
if (allowedOptions.count(optionName)) UnspecifiedOption(optionName);
103+
UnrecognizedOption(optionName);
104+
}
105+
106+
assert(options.count(optionName));
107+
return (*options.find(optionName)).second;
108+
}
109+
110+
void setOption(const std::string& optionName, const std::string& value)
111+
{
112+
options[optionName] = value;
113+
}
114+
115+
std::string getString(const std::string& optionName) const {
116+
return getOption(optionName);
117+
}
118+
119+
int getInt(const std::string& optionName) const {
120+
return to_int(getOption(optionName));
121+
}
122+
123+
bool getBool(const std::string& optionName) const {
124+
return getOption(optionName) != "false";
125+
}
126+
127+
void setBool(const std::string& optionName, bool value) {
128+
if (!options.count(optionName)) {
129+
UnrecognizedOption(optionName);
130+
}
131+
132+
assert(options.count(optionName));
133+
setOption(optionName, value ? "true" : "false");
134+
}
135+
136+
bool hasOption(const std::string& optionName) const
137+
{
138+
if (!allowedOptions.count(optionName)) {
139+
UnrecognizedOption(optionName);
140+
}
141+
142+
return options.count(optionName) > 0;
143+
}
144+
145+
void UnspecifiedOption(const std::string& optionName) const
146+
{
147+
std::cout << "required option \"" << optionName << "\" is not specified\n";
148+
throw 1;
149+
}
150+
151+
void UnrecognizedOption(const std::string& optionName) const
152+
{
153+
std::cout << "unrecognized option \"" << optionName << "\"\n";
154+
throw 1;
155+
}
156+
157+
void InvalidOption(const std::string& optionName) const
158+
{
159+
std::cout << "value \"" << getOption(optionName) << "\" is invalid for option \"" << optionName << "\"\n";
160+
throw 1;
161+
}
162+
163+
void Usage(const std::string& program) const
164+
{
165+
if (usageMessage != "")
166+
std::cout << usageMessage << "\n";
167+
else
168+
std::cout << "Usage: " << program << " [options]" << "\n";
169+
170+
std::cout << "Allowed options:";
171+
for (auto opt : allowedOptionsOrder)
172+
{
173+
std::string name = allowedOptions.find(opt)->first;
174+
if (name.length() == 0) continue;
175+
176+
std::cout << "\n";
177+
std::cout << " " << name;
178+
if (allowedValues.count(name))
179+
{
180+
auto av = allowedValues.find(name)->second;
181+
if (!av.empty())
182+
{
183+
std::cout << "=";
184+
bool first = true;
185+
for (std::string s: av)
186+
if (first)
187+
{ std::cout << "[" << s; first = false; }
188+
else
189+
std::cout << "|" << s;
190+
std::cout << "]";
191+
}
192+
}
193+
std::cout << "\n";
194+
195+
std::cout << " " << allowedOptions.find(opt)->second << "\n";
196+
}
197+
}
198+
};

src/common.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#include "common.h"
2+
3+
#include <algorithm>
4+
5+
vector<string> SplitNotNull(const string& ss, const string& c)
6+
{
7+
string s = ss + c;
8+
vector<string> result;
9+
string tec = "";
10+
for (int i = 0; i < (int)s.length(); i++)
11+
{
12+
if (c.find(s[i]) != string::npos)
13+
{
14+
if ((int)tec.length() > 0) result.push_back(tec);
15+
tec = "";
16+
}
17+
else tec += s[i];
18+
}
19+
20+
return result;
21+
}
22+
23+
vector<int> SplitNotNullInt(const string& ss, const string& c)
24+
{
25+
vector<string> tmp = SplitNotNull(ss, c);
26+
vector<int> res;
27+
for (size_t i = 0; i < tmp.size(); i++) {
28+
res.push_back(to_int(tmp[i]));
29+
}
30+
return res;
31+
}
32+
33+
double Sum(const vector<double>& v)
34+
{
35+
double sum = 0;
36+
for (int i = 0; i < (int)v.size(); i++)
37+
sum += v[i];
38+
return sum;
39+
}
40+
41+
double Average(const vector<double>& v)
42+
{
43+
double av = Sum(v);
44+
if (!v.empty())
45+
av /= (double)v.size();
46+
return av;
47+
}
48+
49+
double Median(const vector<double>& v)
50+
{
51+
if ( v.empty() ) return 0;
52+
if ( v.size() == 1 ) return v[0];
53+
54+
vector<double> tmp = v;
55+
sort(tmp.begin(), tmp.end());
56+
int sz = (int)tmp.size();
57+
58+
if ( sz % 2 == 0 )
59+
return (tmp[sz / 2 - 1] + tmp[sz / 2]) / 2.0;
60+
else
61+
return tmp[sz / 2];
62+
}
63+
64+
double Maximum(const vector<double>& v)
65+
{
66+
if ( v.empty() ) return 0;
67+
68+
double res = v[0];
69+
for (int i = 0; i < (int)v.size(); i++)
70+
res = max(res, v[i]);
71+
return res;
72+
}
73+
74+
double Minimum(const vector<double>& v)
75+
{
76+
if (v.empty()) return 0;
77+
78+
double res = v[0];
79+
for (int i = 0; i < (int)v.size(); i++)
80+
res = min(res, v[i]);
81+
return res;
82+
}
83+
84+
double Percentile(const vector<double>& v, int p)
85+
{
86+
if (v.empty()) return 0;
87+
88+
int n = (int)v.size();
89+
int pos = p * n / 100;
90+
if (pos >= n) pos = n - 1;
91+
return v[pos];
92+
}
93+
94+
int Compare(double numberA, double numberB)
95+
{
96+
double c = numberA - numberB;
97+
if (c <= -EPS)
98+
return -1;
99+
if (c >= EPS)
100+
return 1;
101+
return 0;
102+
}
103+
104+
bool Equal(double a, double b)
105+
{
106+
return Abs(a - b) <= EPS;
107+
}
108+
109+
bool Greater(double numberA, double numberB)
110+
{
111+
return Compare(numberA, numberB) > 0;
112+
}
113+
114+
bool GreaterOrEqual(double numberA, double numberB)
115+
{
116+
return Compare(numberA, numberB) >= 0;
117+
}
118+
119+
bool LessOrEqual(double numberA, double numberB)
120+
{
121+
return Compare(numberA, numberB) <= 0;
122+
}
123+
124+
bool Less(double numberA, double numberB)
125+
{
126+
return Compare(numberA, numberB) < 0;
127+
}

0 commit comments

Comments
 (0)