Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some problems that arise when modeling megaminx. #5

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
211a05d
Fix delete to be delete[] when we new[].
rokicki Aug 16, 2016
b909dda
Fix iter++ that should obviously be iter2++.
rokicki Aug 16, 2016
16daadb
Fix two issues in indexing. First, a bunch of ints should be long longs
rokicki Aug 16, 2016
07b2bbf
Allow ! to generate God's number information, as the docs say.
rokicki Aug 17, 2016
d197eb6
Move the ksolve shell script to have a .sh extension so we can
rokicki Jul 9, 2018
d639fa7
Added missing flushes.
rokicki Jul 9, 2018
00dc9ad
Slight bump in max memory we try to allocate (from 2G to 16G).
rokicki Jul 27, 2018
260e58f
Added some additional information to the puzzle def.
rokicki Jul 27, 2018
ca7a17d
Redid the large puzzle packing code completely. It's now much faster,
rokicki Jul 27, 2018
f87da8c
Added -g to build command.
rokicki Jul 27, 2018
0d23dcb
Now about 2X faster when puzzle fits in memory.
rokicki Jul 27, 2018
e2c1aea
Slight speed bump for large puzzles with centers.
rokicki Jul 28, 2018
74b2d99
Don't leak memory so crazily on God's number explorations. Also
rokicki Jul 29, 2018
b3e49fe
Removed string indexes from main datastructures and replaced them with
rokicki Jul 29, 2018
19ee5f7
Eliminate some unneeded arguments.
rokicki Jul 29, 2018
1e7a465
Big change; changing Position from a map to a vector. Almost certainly
rokicki Jul 29, 2018
2fb72c5
Fixed some bugs introduced with that big rewrite.
rokicki Jul 29, 2018
ee2460d
Fixed some bugs from my big changes.
rokicki Jul 31, 2018
7e23d01
A bug fix that only shows up on linux at the moment.
rokicki Jul 31, 2018
6531090
Fix another problem with the change from map to vector.
rokicki Aug 3, 2018
e838632
Added a max memory option so we can run big things on big machines and
rokicki Aug 3, 2018
b73343a
Added verbosity option. Added computation of permutation parity.
rokicki Aug 3, 2018
68af894
Made God's number calculations use permutation parity optimization.
rokicki Aug 3, 2018
3388a4a
Oops; fixed a bug in table size calc.
rokicki Aug 3, 2018
a3368ea
Another fix?
rokicki Aug 3, 2018
86251dc
Allowed counts > 2^31.
rokicki Aug 3, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
4 changes: 4 additions & 0 deletions makefile-tgr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ksolve: source/blocks.h source/checks.h source/data.h source/god.h \
source/indexing.h source/main.cpp source/move.h source/pruning.h \
source/readdef.h source/readscramble.h source/search.h
g++ -O3 -std=c++11 -g -o ksolve -march=native -Isource source/main.cpp
13 changes: 6 additions & 7 deletions source/blocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@

static bool blockLegal(Position& state, std::vector<Block>& blocks, Position& move){
Block changed;
Position::iterator iter;
for (iter = move.begin(); iter != move.end(); iter++){
int setsize = iter->second.size;
for (int iter=0; iter<move.size(); iter++) {
int setsize = move[iter].size;
for (int i = 0; i < setsize; i++){
if (iter->second.permutation[i] != i+1)
changed[iter->first].insert(state[iter->first].permutation[i]);
else if (iter->second.orientation[i] != 0)
changed[iter->first].insert(state[iter->first].permutation[i]);
if (move[iter].permutation[i] != i+1)
changed[iter].insert(state[iter].permutation[i]);
else if (move[iter].orientation[i] != 0)
changed[iter].insert(state[iter].permutation[i]);
}
}

Expand Down
11 changes: 7 additions & 4 deletions source/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ struct dataset{
int type;
int size;
int omod; // Orientations are calculated mod this value
int maxInSolved; // maximum value in solved perm; assumes 1-base
int permbits, oribits ; // bits for perm and ori
int ptabletype;
int otabletype;
bool uniqueperm; // Perm of unique numbers (1,2,3,...), or repeated (1,3,1,2)
bool oparity; // Does orientation have a parity constraint? (If so, last orientation is unnecessary)
bool pparity; // Does permutation have a parity constraint?
};

// part of a state, including orientation and permutation
Expand All @@ -68,11 +71,11 @@ struct subprune{

// some typedefs to make things easier
typedef std::string string;
typedef std::map<string, substate> Position;
typedef std::map<string, std::set<int> > Block;
typedef std::vector<substate> Position;
typedef std::map<int, std::set<int> > Block;
typedef std::pair<int, int> MovePair;
typedef std::map<string, subprune> PruneTable;
typedef std::map<string, dataset> PieceTypes;
typedef std::map<int, subprune> PruneTable;
typedef std::map<int, dataset> PieceTypes;

// all the information needed to describe a possible move
struct fullmove {
Expand Down
259 changes: 136 additions & 123 deletions source/god.h

Large diffs are not rendered by default.

135 changes: 98 additions & 37 deletions source/indexing.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,30 @@
#define INDEXING_H

// Convert vector of orientations into an index
static int oVector2Index(std::vector<int> orientations, int omod) {
static long long oVector2Index(std::vector<int> orientations, int omod) {
return oVector2Index(orientations.data(), orientations.size(), omod);
}

// Convert array of orientations into an index
static int oVector2Index(int orientations[], int size, int omod) {
int tmp = 0;
static long long oVector2Index(int orientations[], int size, int omod) {
long long tmp = 0;
for (int i = 0; i < size; i++){
tmp = tmp*omod + orientations[i];
}
return tmp;
}

// Convert array of orientations (with parity constraint) into an index
static int oparVector2Index(int orientations[], int size, int omod) {
int tmp = 0;
static long long oparVector2Index(int orientations[], int size, int omod) {
long long tmp = 0;
for (int i = 0; i < size - 1; i++){
tmp = tmp*omod + orientations[i];
}
return tmp;
}

// Convert orientation index into a vector
static std::vector<int> oIndex2Vector(int index, int size, int omod) {
static std::vector<int> oIndex2Vector(long long index, int size, int omod) {
std::vector<int> orientations;
orientations.resize(size);
for (int i = size - 1; i >= 0; i--){
Expand All @@ -57,8 +57,9 @@ static std::vector<int> oIndex2Vector(int index, int size, int omod) {
}

// Convert orientation index into an array
static int* oIndex2Array(int index, int size, int omod) {
int* orientation = new int[size];
static int* oIndex2Array(long long index, int size, int omod, int *orientation=0) {
if (orientation == 0)
orientation = new int[size] ;
for (int i = size - 1; i >= 0; i--){
orientation[i] = index % omod;
index /= omod;
Expand All @@ -67,8 +68,9 @@ static int* oIndex2Array(int index, int size, int omod) {
}

// Convert orientation index (with parity constraint) into an array
static int* oparIndex2Array(int index, int size, int omod) {
int* orientation = new int[size];
static int* oparIndex2Array(long long index, int size, int omod, int *orientation=0) {
if (orientation == 0)
orientation = new int[size] ;
orientation[size - 1] = 0;
for (int i = size - 2; i >= 0; i--){
orientation[i] = index % omod;
Expand All @@ -80,34 +82,93 @@ static int* oparIndex2Array(int index, int size, int omod) {
}

// Convert permutation vector (unique) into an index
static int pVector2Index(std::vector<int> permutation) {
static long long pVector2Index(std::vector<int> permutation) {
return pVector2Index(permutation.data(), permutation.size());
}

// Convert permutation array (unique) into an index
static int pVector2Index(int permutation[], int size) {
int t = 0;
for (int i = 0; i < size - 1; i++){
t *= (size - i);
for (int j = i+1; j<size; j++)
if (permutation[i] > permutation[j])
t++;
static long long pVector2Index(int *perm, int n) {
int i, j;
long long r = 0 ;
long long m = 1 ;
unsigned char state[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
} ;
unsigned char inverse[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
} ;
for (i = 0; i+1 < n; i++) {
j = inverse[perm[i]-1];
inverse[state[i]] = j;
state[j] = state[i];
r += m * (j - i) ;
m *= (n - i) ;
}
return t;
return r ;
}

// Convert index into a permutation array (unique)
static int* pIndex2Array(int index, int size) {
int* permutation = new int[size];
permutation[size-1] = 1;
for (int i = size - 2; i >= 0; i--){
permutation[i] = 1 + (index % (size-i));
index /= (size - i);
for (int j = i+1; j < size; j++)
if (permutation[j] >= permutation[i])
permutation[j]++;
static int *pIndex2Array(long long ind, int n, int *perm=0) {
if (perm == 0)
perm = new int[n] ;
int i, j;
unsigned char state[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
};
for (i = 0; i+1 < n; i++) {
long long t = ind / (n - i) ;
j = i + ind - t * (n - i) ;
ind = t ;
perm[i] = 1+state[j];
state[j] = state[i];
}
perm[n-1] = 1+state[n-1] ;
return perm ;
}

static long long pVector2IndexP(int *perm, int n) {
int i, j;
long long r = 0 ;
long long m = 1 ;
unsigned char state[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
} ;
unsigned char inverse[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
} ;
for (i = 0; i+2 < n; i++) {
j = inverse[perm[i]-1];
inverse[state[i]] = j;
state[j] = state[i];
r += m * (j - i) ;
m *= (n - i) ;
}
return r ;
}

static int *pIndex2ArrayP(long long ind, int n, int *perm=0) {
if (perm == 0)
perm = new int[n] ;
int i, j;
unsigned char state[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
};
int pars = n ;
for (i = 0; i+2 < n; i++) {
long long t = ind / (n - i) ;
j = i + ind - t * (n - i) ;
if (j == i)
pars-- ;
ind = t ;
perm[i] = 1+state[j];
state[j] = state[i];
}
if (pars & 1) {
perm[n-1] = 1+state[n-2] ;
perm[n-2] = 1+state[n-1] ;
} else {
perm[n-2] = 1+state[n-2] ;
perm[n-1] = 1+state[n-1] ;
}
return permutation;
return perm ;
}

// Convert permutation vector (non-unique) into an index
Expand Down Expand Up @@ -161,9 +222,9 @@ static int* pIndex3Array(long long index, std::vector<int> solved) {
}

// Convert index into a permutation array (non-unique)
static int* pIndex3Array(long long index, int* solved, int size) {
int* vec = new int[size];

static int* pIndex3Array(long long index, int* solved, int size, int *vec=0) {
if (vec == 0)
vec = new int[size] ;
// compute number of times each element appears
std::map<int, int> counts;
std::map<int, int>::iterator iter;
Expand Down Expand Up @@ -248,11 +309,10 @@ static std::vector<long long> packVector(std::vector<int> vec){

static std::vector<long long> packVector(int vec[], int size){
std::vector<long long> result (1 + size/8);

for (int i = 0; i < size; i += 8) {
long long element = 0;
for (int j = 0; j < 8; j++)
if (i+j < size) element += ((long long)vec[i+j]) << (8*j);
if (i+j < size) element += (1LL+vec[i+j]) << (8*j);
result[i/8] = element;
}
return result;
Expand All @@ -271,7 +331,8 @@ static std::vector<int> unpackVector(std::vector<long long> vec){
}
while(result[result.size() - 1] == 0)
result.pop_back();

for (int i=0; i<result.size(); i++)
result[i]-- ;
return result;
}

Expand Down
36 changes: 30 additions & 6 deletions source/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@
#include <time.h>
#include <string.h>

std::map<std::string, int> setnameLookup ;
std::vector<std::string> setNames ;
int setnameIndex(const std::string &s) {
std::map<std::string, int>::iterator it = setnameLookup.find(s) ;
if (it == setnameLookup.end()) {
setnameLookup[s] = setNames.size() ;
it = setnameLookup.find(s) ;
setNames.push_back(s) ;
}
return it->second ;
}
std::string setnameFromIndex(int i) {
return setNames[i] ;
}
long long maxmem = 8000000000LL ;
int verbose = 0 ;

struct ksolve {
#include "data.h"
#include "move.h"
Expand All @@ -50,7 +67,15 @@ struct ksolve {
static int ksolveMain(int argc, char *argv[]) {

srand(time(NULL)); // initialize RNG in case we need it

while (argc > 3 && argv[1][0] == '-') {
argc-- ;
argv++ ;
switch (argv[0][1]) {
case 'M': maxmem = 1048576 * atoll(argv[1]) ; argc-- ; argv++ ; break ;
case 'v': verbose++ ; break ;
default: std::cout << "Did not understand argument " << argv[0] << std::endl ;
}
}
if (argc != 3){
std::cerr << "ksolve+ v1.3a - Linux Port by Matt Stiefel\n";
std::cerr << "(c) 2007-2013 by Kare Krig and Michael Gottlieb\n";
Expand All @@ -66,7 +91,7 @@ struct ksolve {
exit(-1);
}
std::ifstream scrambleStream(argv[2]);
if (!scrambleStream.good()){
if (argv[2][0] != '!' && !scrambleStream.good()){
std::cout << "Can't open scramble file!\n";
exit(-1);
}
Expand Down Expand Up @@ -154,11 +179,10 @@ struct ksolve {
// give out a warning if we have some undefined permutations on a bandaged puzzle
if (blocks.size() != 0) {
bool hasUndefined = false;
Position::iterator iter;
for (iter = scramble.state.begin(); iter != scramble.state.end(); iter++) {
int setsize = iter->second.size;
for (int iter=0; iter<scramble.state.size(); iter++) {
int setsize = scramble.state[iter].size;
for (int i = 0; i < setsize; i++) {
if (iter->second.permutation[i] == -1) {
if (scramble.state[iter].permutation[i] == -1) {
hasUndefined = true;
}
}
Expand Down
Loading