Skip to content

Commit

Permalink
shuffleAllBut for graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
ifsmirnov committed Dec 24, 2017
1 parent 596b8d9 commit 3357d0a
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions doc/graph.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,12 @@ All options are unset by default. If the generator contradicts some option (like
* relabel vertices in random order;
* shuffle edges;
* randomly swap egdes' endpoints (for undirected graphs only).

#### Graph& shuffleAllBut(const Array& except)
#### Graph shuffledAllBut(const Array& except)
* Same as *shuffle*, but vertices from *except* do not change their numbers.
* Possible usecase: we may generate a graph where *s-t* path is supposed to be found. Then shuffle the graph in such a way that path endpoints are still *1* and *n*:
```cpp
g = Graph::random(n, m)...;
g.shuffleAllBut({0, n-1});
```
9 changes: 9 additions & 0 deletions doc/tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ Note that all generators return trees with sorted edges to make tests more human
* shuffle edges;
* randomly swap egdes' endpoints.

#### Tree& shuffleAllBut(const Array& except)
#### Tree shuffledAllBut(const Array& except)
* Same as *shuffle*, but vertices from *except* do not change their numbers.
* Possible usecase: we may generate a rooted tree and shuffle it in such a way that root still has number *1*.
```cpp
t = Tree::randomPrim(n, 1000);
t.shuffleAllBut({0});
```
#### Array parents(int root) const
* Returns: array of size *n*, where *i*-th element is a parent of vertex *i* if the tree is rooted at *root*. Parent of *root* is *-1*.
Expand Down
2 changes: 2 additions & 0 deletions generic_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class GenericGraph {
static WeightArray prepareWeightArray(WeightArray a, int requiredSize);

void doShuffle();
void doShuffleAllBut(const Array& except);
void doShuffleEdges();

void extend(size_t size);

Expand Down
12 changes: 12 additions & 0 deletions graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Graph : public ReprProxy<Graph>, public GenericGraph {

Graph& shuffle();
Graph shuffled() const;
Graph& shuffleAllBut(const Array& except);
Graph shuffledAllBut(const Array& except) const;

static BuilderProxy random(int n, int m);
static BuilderProxy complete(int n);
Expand All @@ -57,6 +59,16 @@ inline Graph Graph::shuffled() const {
return g.shuffle();
}

inline Graph& Graph::shuffleAllBut(const Array& except) {
doShuffleAllBut(except);
return *this;
}

inline Graph Graph::shuffledAllBut(const Array& except) const {
Graph g(*this);
return g.shuffleAllBut(except);
}

JNGEN_DECLARE_SIMPLE_PRINTER(Graph, 2) {
t.doPrintEdges(out, mod);
}
Expand Down
23 changes: 23 additions & 0 deletions impl/generic_graph_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,29 @@ void GenericGraph::doShuffle() {
vertexLabel_.shuffle();
vertexByLabel_ = vertexLabel_.inverse();

doShuffleEdges();
}

void GenericGraph::doShuffleAllBut(const Array& except) {
Array index = except.sorted();
Array needed = Array::id(n());
needed.erase(std::set_difference(
needed.begin(), needed.end(),
index.begin(), index.end(),
needed.begin()), needed.end());
Array neededShuffled = needed.shuffled();
Array perm = Array::id(n());
for (size_t i = 0; i < needed.size(); ++i) {
perm[needed[i]] = neededShuffled[i];
}

vertexLabel_ = vertexLabel_.subseq(perm);
vertexByLabel_ = vertexLabel_.inverse();

doShuffleEdges();
}

void GenericGraph::doShuffleEdges() {
if (!directed_) {
for (auto& edge: edges_) {
if (rnd.next(2)) {
Expand Down
10 changes: 10 additions & 0 deletions impl/tree_inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ Tree Tree::shuffled() const {
return t.shuffle();
}

inline Tree& Tree::shuffleAllBut(const Array& except) {
doShuffleAllBut(except);
return *this;
}

inline Tree Tree::shuffledAllBut(const Array& except) const {
Tree g(*this);
return g.shuffleAllBut(except);
}

Tree Tree::link(int vInThis, const Tree& other, int vInOther) {
ensure(vInThis < n(), "Cannot link a nonexistent vertex");
ensure(vInOther < other.n(), "Cannot link to a nonexistent vertex");
Expand Down
49 changes: 49 additions & 0 deletions jngen.h
Original file line number Diff line number Diff line change
Expand Up @@ -5492,6 +5492,8 @@ class GenericGraph {
static WeightArray prepareWeightArray(WeightArray a, int requiredSize);

void doShuffle();
void doShuffleAllBut(const Array& except);
void doShuffleEdges();

void extend(size_t size);

Expand Down Expand Up @@ -5643,6 +5645,29 @@ void GenericGraph::doShuffle() {
vertexLabel_.shuffle();
vertexByLabel_ = vertexLabel_.inverse();

doShuffleEdges();
}

void GenericGraph::doShuffleAllBut(const Array& except) {
Array index = except.sorted();
Array needed = Array::id(n());
needed.erase(std::set_difference(
needed.begin(), needed.end(),
index.begin(), index.end(),
needed.begin()), needed.end());
Array neededShuffled = needed.shuffled();
Array perm = Array::id(n());
for (size_t i = 0; i < needed.size(); ++i) {
perm[needed[i]] = neededShuffled[i];
}

vertexLabel_ = vertexLabel_.subseq(perm);
vertexByLabel_ = vertexLabel_.inverse();

doShuffleEdges();
}

void GenericGraph::doShuffleEdges() {
if (!directed_) {
for (auto& edge: edges_) {
if (rnd.next(2)) {
Expand Down Expand Up @@ -5864,6 +5889,8 @@ class Tree : public ReprProxy<Tree>, public GenericGraph {

Tree& shuffle();
Tree shuffled() const;
Tree& shuffleAllBut(const Array& except);
Tree shuffledAllBut(const Array& except) const;

Tree link(int vInThis, const Tree& other, int vInOther);
Tree glue(int vInThis, const Tree& other, int vInOther);
Expand Down Expand Up @@ -5969,6 +5996,16 @@ Tree Tree::shuffled() const {
return t.shuffle();
}

inline Tree& Tree::shuffleAllBut(const Array& except) {
doShuffleAllBut(except);
return *this;
}

inline Tree Tree::shuffledAllBut(const Array& except) const {
Tree g(*this);
return g.shuffleAllBut(except);
}

Tree Tree::link(int vInThis, const Tree& other, int vInOther) {
ensure(vInThis < n(), "Cannot link a nonexistent vertex");
ensure(vInOther < other.n(), "Cannot link to a nonexistent vertex");
Expand Down Expand Up @@ -6205,6 +6242,8 @@ class Graph : public ReprProxy<Graph>, public GenericGraph {

Graph& shuffle();
Graph shuffled() const;
Graph& shuffleAllBut(const Array& except);
Graph shuffledAllBut(const Array& except) const;

static BuilderProxy random(int n, int m);
static BuilderProxy complete(int n);
Expand All @@ -6229,6 +6268,16 @@ inline Graph Graph::shuffled() const {
return g.shuffle();
}

inline Graph& Graph::shuffleAllBut(const Array& except) {
doShuffleAllBut(except);
return *this;
}

inline Graph Graph::shuffledAllBut(const Array& except) const {
Graph g(*this);
return g.shuffleAllBut(except);
}

JNGEN_DECLARE_SIMPLE_PRINTER(Graph, 2) {
t.doPrintEdges(out, mod);
}
Expand Down
2 changes: 2 additions & 0 deletions tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Tree : public ReprProxy<Tree>, public GenericGraph {

Tree& shuffle();
Tree shuffled() const;
Tree& shuffleAllBut(const Array& except);
Tree shuffledAllBut(const Array& except) const;

Tree link(int vInThis, const Tree& other, int vInOther);
Tree glue(int vInThis, const Tree& other, int vInOther);
Expand Down

0 comments on commit 3357d0a

Please sign in to comment.