28 #include <sys/types.h>
35 for (
size_t var = 1; var < variableCount; ++var) {
48 if (mpz_class(rowCount) * mpz_class(columnCount) >
49 numeric_limits<size_t>::max())
50 reportError(
"Number of positions on requested chess board too large.");
54 for (
size_t row = 0; row < rowCount; ++row) {
55 for (
size_t column = 0; column < columnCount; ++column) {
57 name <<
'r' << (row + 1) <<
'c' << (column + 1);
65 for (
size_t row = 0; row < rowCount; ++row) {
66 for (
size_t column = 0; column < columnCount; ++column) {
67 for (
size_t delta = 0; delta < deltaCount; ++delta) {
70 if (deltaRow[delta] == numeric_limits<int>::min() ||
71 (deltaRow[delta] < 0 &&
72 row < (
size_t)-deltaRow[delta]) ||
73 (deltaRow[delta] > 0 &&
74 rowCount - row <= (
size_t)deltaRow[delta]))
77 if (deltaColumn[delta] == numeric_limits<int>::min() ||
78 (deltaColumn[delta] < 0 &&
79 column < (
size_t)-deltaColumn[delta]) ||
80 (deltaColumn[delta] > 0 &&
81 columnCount - column <= (
size_t)deltaColumn[delta]))
85 chessMove[row * columnCount + column] = 1;
87 size_t targetRow = row + deltaRow[delta];
88 size_t targetColumn = column + deltaColumn[delta];
89 ASSERT(targetRow < rowCount);
90 ASSERT(targetColumn < columnCount);
92 chessMove[targetRow * columnCount + targetColumn] = 1;
103 int deltaRow[] = {-1, 0, 1, 1};
104 int deltaColumn[] = { 1, 1, 1, 0};
105 ASSERT(
sizeof(deltaRow) ==
sizeof(deltaColumn));
107 size_t deltaCount =
sizeof(deltaRow) /
sizeof(
int);
110 deltaRow, deltaColumn, deltaCount);
114 int deltaRow[] = {-1, 1, 2, 2};
115 int deltaColumn[] = { 2, 2, 1, -1};
116 ASSERT(
sizeof(deltaRow) ==
sizeof(deltaColumn));
118 size_t deltaCount =
sizeof(deltaRow) /
sizeof(
int);
121 deltaRow, deltaColumn, deltaCount);
128 bool nextBitPattern(vector<char>& pattern) {
129 typedef vector<char>::iterator iterator;
130 for (iterator it = pattern.begin(); it != pattern.end(); ++it) {
135 ASSERT(pattern != vector<char>(pattern.size()));
140 ASSERT(pattern == vector<char>(pattern.size()));
156 vector<char> pattern(varCount);
157 while (nextBitPattern(pattern)) {
159 typedef vector<char>::iterator iterator;
160 for (iterator it = pattern.begin(); it != pattern.end(); ++it)
161 setSize += (size_t)*it;
163 exponent = varCount - setSize + 1;
165 for (
size_t var = 0; var < varCount; ++var)
172 if (n == 0 || k == 0)
173 reportError(
"One side of rook ideal has zero vertices.");
174 if (n > 1000 || k > 1000)
175 reportError(
"Number of variables in rook ideal too large.");
179 size_t varCount = n * k;
180 Ideal ideal(varCount);
183 vector<char> taken(k);
184 vector<size_t> choice(n);
187 if (choice[level] == k) {
191 ASSERT(
static_cast<bool>(taken[choice[level]]) ==
true);
192 ASSERT(term[level * k + choice[level]] == 1);
193 taken[choice[level]] =
false;
194 term[level * k + choice[level]] = 0;
198 if (taken[choice[level]]) {
202 taken[choice[level]] =
true;
203 ASSERT(term[level * k + choice[level]] == 0);
204 term[level * k + choice[level]] = 1;
211 ASSERT(
static_cast<bool>(taken[choice[level]]) ==
true);
212 ASSERT(term[level * k + choice[level]] == 1);
213 taken[choice[level]] =
false;
214 term[level * k + choice[level]] = 0;
226 reportError(
"Too few variables in matching ideal.");
227 if (n > 1000 || n > 1000)
228 reportError(
"Number of variables in matching ideal too large.");
232 State(
size_t nodeCount):
233 _notTaken(-1), _nodes(nodeCount), _isAnchor(nodeCount) {
234 std::fill(_nodes.begin(), _nodes.end(), _notTaken);
235 const size_t varCount = nodeCount * (nodeCount - 1) / 2;
236 _term.reset(varCount);
239 void takeEdge(
size_t anchor,
size_t other) {
240 ASSERT(anchor < _nodes.size());
241 ASSERT(other < _nodes.size());
244 _nodes[anchor] = other;
245 _nodes[other] = anchor;
246 _isAnchor[anchor] =
true;
248 const size_t var = edgeToVar(anchor, other);
253 void takeNode(
size_t node) {
254 ASSERT(node < getNodeCount());
260 void dropNode(
size_t node) {
261 ASSERT(node < getNodeCount());
264 ASSERT(_nodes[node] == node);
265 _nodes[node] = _notTaken;
268 void dropEdge(
size_t anchor) {
269 ASSERT(anchor < _nodes.size());
272 _isAnchor[anchor] =
false;
273 const size_t other = _nodes[anchor];
274 _nodes[other] = _notTaken;
275 _nodes[anchor] = _notTaken;
277 const size_t var = edgeToVar(anchor, other);
282 size_t getNeighbor(
size_t node)
const {
287 bool isAnchor(
size_t node)
const {
288 ASSERT(node < _nodes.size());
289 return _isAnchor[node];
292 bool isTaken(
size_t node)
const {
293 ASSERT(node < _nodes.size());
294 return _nodes[node] != _notTaken;
297 const Term& getTerm()
const {
return _term;}
298 size_t getNodeCount()
const {
return _nodes.size();}
302 size_t getAnchorLeft(
size_t node)
const {
303 ASSERT(node <= getNodeCount());
304 for (--node; node !=
static_cast<size_t>(-1); --node)
312 size_t getNotTakenRight(
size_t node)
const {
313 ASSERT(node < getNodeCount());
314 for (++node; node < getNodeCount(); ++node)
321 size_t edgeToVar(
size_t a,
size_t b)
const {
323 ASSERT(a < _nodes.size());
324 ASSERT(b < _nodes.size());
327 const size_t var = (a * (a - 1)) / 2 + b;
328 ASSERT(var < _term.getVarCount());
332 const size_t _notTaken;
333 std::vector<size_t> _nodes;
334 std::vector<size_t> _isAnchor;
339 Ideal ideal(state.getTerm().getVarCount());
343 size_t notUsed = state.getNodeCount();
344 if (state.getNodeCount() % 2 == 1) {
346 state.takeNode(notUsed);
350 if (node ==
static_cast<size_t>(-1)) {
351 if (notUsed < state.getNodeCount()) {
352 state.dropNode(notUsed);
355 if (notUsed == state.getNodeCount())
357 state.takeNode(notUsed);
360 ASSERT(node <= state.getNodeCount());
361 if (node == state.getNodeCount()) {
362 ideal.
insert(state.getTerm());
363 node = state.getAnchorLeft(node);
364 }
else if (!state.isTaken(node)) {
365 const size_t neighbor = state.getNotTakenRight(node);
366 if (neighbor == state.getNodeCount()) {
367 node = state.getAnchorLeft(node);
369 state.takeEdge(node, neighbor);
370 node = state.getNotTakenRight(neighbor);
373 ASSERT(state.isTaken(node));
374 ASSERT(state.isAnchor(node));
375 const size_t neighbor = state.getNeighbor(node);
376 const size_t nextNeighbor = state.getNotTakenRight(neighbor);
377 state.dropEdge(node);
378 if (nextNeighbor == state.getNodeCount()) {
379 node = state.getAnchorLeft(node);
381 state.takeEdge(node, nextNeighbor);
382 node = state.getNotTakenRight(node);
387 VarNames names(state.getTerm().getVarCount());
393 (
BigIdeal& bigIdeal,
size_t variableCount,
size_t generatorCount) {
394 Ideal ideal(variableCount);
395 Term term(variableCount);
397 size_t generatorsToGo = generatorCount;
398 size_t triesLeft = (size_t)4 * 1000 * 1000;
399 while (generatorsToGo > 0 && triesLeft > 0) {
402 size_t a = rand() % variableCount;
403 size_t b = rand() % variableCount;
425 return generatorsToGo == 0;
430 size_t exponentRange,
431 size_t variableCount,
432 size_t generatorCount) {
433 Ideal ideal(variableCount);
434 Term term(variableCount);
436 size_t generatorsToGo = generatorCount;
437 size_t triesLeft = (size_t)4 * 1000 * 1000;
438 while (generatorsToGo > 0 && triesLeft > 0) {
441 for (
size_t var = 0; var < variableCount; ++var) {
443 if (exponentRange != numeric_limits<size_t>::max())
444 term[var] %= exponentRange + 1;
457 return generatorsToGo == 0;
462 const mpz_class& maxEntry) {
466 gmp_randclass random(gmp_randinit_default);
469 random.seed((
unsigned long)time(0) +
471 (
unsigned long)getpid() +
473 (
unsigned long)clock());
475 instance.resize(entryCount);
478 for (
size_t i = 0; i < entryCount; ++i)
479 instance[i] = random.get_z_range(maxEntry) + 1;
482 mpz_class
gcd = instance[0];
483 for (
size_t i = 1; i < entryCount; ++i)
484 mpz_gcd(
gcd.get_mpz_t(),
gcd.get_mpz_t(), instance[i].get_mpz_t());
487 instance.front() /=
gcd;
489 sort(instance.begin(), instance.end());
void reserve(size_t capacity)
void clearAndSetNames(const VarNames &names)
mpz_class & getLastTermExponentRef(size_t var)
size_t getVarCount() const
void insert(const Ideal &ideal)
A replacement for stringstream.
Represents a monomial ideal with int exponents.
bool isIncomparable(const Exponent *term) const
void insert(const Exponent *term)
size_t getVarCount() const
Term represents a product of variables which does not include a coefficient.
Defines the variables of a polynomial ring and facilities IO involving them.
bool addVar(const string &name)
Adds the variable and returns true if name is not already a variable.
void reportError(const string &errorMsg)
void gcd(Word *res, const Word *resEnd, const Word *a, const Word *b)
void swap(hashtable< _Val, _Key, _HF, _Extract, _EqKey, _All > &__ht1, hashtable< _Val, _Key, _HF, _Extract, _EqKey, _All > &__ht2)
void generateRandomFrobeniusInstance(vector< mpz_class > &instance, size_t entryCount, const mpz_class &maxEntry)
Generate a random vector of numbers whose gcd is 1.
bool generateRandomIdeal(BigIdeal &bigIdeal, size_t exponentRange, size_t variableCount, size_t generatorCount)
Generate a random ideal with exponents in the range [0, exponentRange].
void generateKnightChessIdeal(BigIdeal &ideal, size_t rowsAndColumns)
Generate an ideal where is a generator when and indicate coordinates on a square chessboard where ...
void generateKingChessIdeal(BigIdeal &ideal, size_t rowsAndColumns)
Generate an ideal where is a generator when and indicate coordinates on a square chessboard where ...
void generateTreeIdeal(BigIdeal &ideal, size_t varCount)
Generate an ideal in varCount variables with minimal generators given by.
bool generateRandomEdgeIdeal(BigIdeal &bigIdeal, size_t variableCount, size_t generatorCount)
Generate a random ideal where every edge is a product of two different variables.
void generateMatchingIdeal(BigIdeal &bigIdeal, size_t n)
Generate an ideal whose facets are the maximum matchings in an n-clique.
void generateRookChessIdeal(BigIdeal &bigIdeal, size_t n, size_t k)
Generate an ideal in n*k variables.
void generateLinkedListIdeal(BigIdeal &ideal, size_t variableCount)
Generate an ideal of the form , and so on.
void generateChessIdeal(BigIdeal &bigIdeal, size_t rowCount, size_t columnCount, int deltaRow[], int deltaColumn[], size_t deltaCount)
This file contains functions that generate data.