// first monte carlo solver, mildly constraint void oku_mcsol(oku_sod* sod, double temp){ int i,j,num,size = sod->size; int cnt[size+1]; int fit1, fit2, idx1, idx2,tmp,tmp2; //refresh list of unknowns in sod unk_find(sod); //fill sudoku with missing symbols for(i=1;i<size+1;i++) cnt[i] = size; for(i=0;i<size*size;i++) cnt[get_idx(sod,i)]--; j=1; for(i=0;i<get_numunk(sod);i++){ while(cnt[j] < 1 && j <= size+1) j++; cnt[j]--; set_idx(sod,get_unkidx(sod,i),j); } fit1 = fitness(sod); num=0; while(fit1 && num < 200000){ //choose 2 indices idx1 = get_unkidx(sod,rndi() % get_numunk(sod)); idx2 = get_unkidx(sod,rndi() % get_numunk(sod)); //swap tmp = get_idx(sod,idx1); if(tmp == (tmp2 = get_idx(sod,idx2))) continue; set_idx(sod,idx1,tmp2); set_idx(sod,idx2,tmp); fit2 = fitness(sod); if(fit2 > fit1 && exp((fit1 - fit2)/temp) < rndf()){ //swap back tmp = get_idx(sod,idx1); set_idx(sod,idx1,get_idx(sod,idx2)); set_idx(sod,idx2,tmp); } else fit1 = fit2; num++; } printf("Solution found after %d MC Steps\n",num); };
static struct image_extent get_test_extent(const struct image_target_info *target, unsigned d) { const struct image_extent ls = image_target_limits(target); const unsigned high = ~0, low = 8; struct image_extent ext; int i; for (i = 0; i < 4; ++i) set_idx(ext, i, MIN2(get_idx(ls, i), (i == d ? high : low))); if (target->target == GL_TEXTURE_CUBE_MAP || target->target == GL_TEXTURE_CUBE_MAP_ARRAY) { /* Cube maps have to be square and the number of faces * should be a multiple of six. */ ext.y = ext.x; ext.z = 6 * MAX2(ext.z / 6, 1); } else if (image_target_samples(target) > 1) { /* Use the maximum number of samples to keep things * interesting. */ ext.x = image_target_samples(target); } return ext; }
//deepcopy of sod void oku_sod_copy(oku_sod* dst,oku_sod* src){ int i,size = src->size; if(dst->size != src->size){ oku_sod_destroy(dst); oku_sod_init(&dst,src->size); } //sudoku dimendion is size*size for(i=0;i<size*size;i++) set_idx(dst,i,get_idx(src,i)); };
// completely unconstrained monte carlo void oku_mcsol2(oku_sod* sod, double temp){ int i,j,num,size = sod->size; int cnt[size+1]; int fit1, fit2, idx1, idx2,tmp; //refresh list of unknowns in sod unk_find(sod); //fill sudoku with missing symbols for(i=0;i<get_numunk(sod);i++){ set_idx(sod,get_unkidx(sod,i),(rndi() % sod->size) + 1); } fit1 = fitness(sod); num=0; while(fit1 && num < 200000){ //choose 2 indices idx1 = get_unkidx(sod,rndi() % get_numunk(sod)); tmp = get_idx(sod,idx1); set_idx(sod,idx1,(rndi() % sod->size) + 1); fit2 = fitness(sod); if(fit2 > fit1 && exp((fit1 - fit2)/temp) < rndf()){ //swap back set_idx(sod,idx1,tmp); } else fit1 = fit2; num++; } printf("Solution found after %d MC Steps\n",num); };
//Nelder-Meads void oku_ineldermeads(oku_sod* sod){ int i,j,dim,idx,tmpfit; int* fit, *barc; oku_sod** polytope; oku_sod* tmp, *tmp2; int max,maxidx,max2,max2idx,min,minidx; double alpha,beta,gamma; alpha = 1.0; beta = 2.0; gamma = 0.5; unk_find(sod); dim = get_numunk(sod) + 1; fit = (int*) malloc(dim*sizeof(int)); barc =(int*) malloc(dim*sizeof(int)); polytope = (oku_sod**) malloc(dim*sizeof(oku_sod*)); oku_sod_init(&tmp,sod->size); oku_sod_copy(tmp,sod); oku_sod_init(&tmp2,sod->size); oku_sod_copy(tmp2,sod); //init polytope for(i=0;i<dim;i++){ oku_sod_init(&polytope[i],sod->size); oku_sod_copy(polytope[i],sod); for(j=0;j<dim-1;j++) set_idx(polytope[i],get_unkidx(sod,j),rndi() % sod->size); fit[i] = fitness(polytope[i]); printf("Fitness of vertex %d: %d\n",i,fit[i]); } do{ for(j=0;j<dim-1;j++) barc[j] = 0; max = minidx = maxidx = 0; min = INT_MAX; for(i=0;i<dim;i++){ fit[i] = fitness(polytope[i]); min = fit[i] < min ? fit[minidx = i] : min; if(fit[i] > max){ max2 = max; max2idx = maxidx; max = fit[i]; maxidx = i; } else { max = fit[i] > max2 ? fit[max2idx = i] : max2; } //calculate barycenter for(j=0;j<dim-1;j++) barc[j] += get_idx(polytope[i],get_unkidx(sod,j)); } printf("Min: %d Max: %d ",min,max); //we work with fixed point arithmetic with accuracy dim //reflection for(j=0;j<dim-1;j++){ idx = get_unkidx(sod,j); set_idx(tmp,idx,(barc[j] + alpha*(barc[j] - dim*get_idx(polytope[maxidx],idx)))/dim); } tmpfit = fitness(tmp); //accept reflection if((fit[minidx] <= tmpfit) && (tmpfit < fit[max2idx])) oku_sod_copy(polytope[maxidx],tmp); printf("Reflection\n"); continue; //expand if(tmpfit < fit[minidx]){ for(j=0;j<dim-1;j++){ idx = get_unkidx(sod,j); set_idx(tmp2,idx,(barc[j] + beta*(dim*get_idx(tmp,idx) - barc[j]))/dim); } if(fitness(tmp2) < tmpfit){ oku_sod_copy(polytope[maxidx],tmp2); } else { oku_sod_copy(polytope[maxidx],tmp); } printf("Expansion\n"); continue; } //contraction if(tmpfit > fit[max2idx]){ if(tmpfit > fit[maxidx]){ for(j=0;j<dim-1;j++){ idx = get_unkidx(sod,j); set_idx(tmp2,idx,(barc[j] + gamma*(dim*get_idx(polytope[maxidx],idx) - barc[j]))/dim); } if(fitness(tmp2) < fit[maxidx]){ oku_sod_copy(polytope[maxidx],tmp2); printf("Contraction1\n"); continue; } else { for(j=0;j<dim-1;j++){ idx = get_unkidx(sod,j); set_idx(tmp2,idx,(barc[j] + gamma*(dim*get_idx(tmp,idx) - barc[j]))/dim); } if(fitness(tmp2) < tmpfit){ oku_sod_copy(polytope[maxidx],tmp2); printf("Contraction2\n"); continue; } } //shrink polytope for(i=0;i<dim;i++) for(j=0;j<dim-1;j++){ idx = get_unkidx(sod,j); set_idx(polytope[i],idx,(get_idx(polytope[i],idx) + dim*barc[j])/2/dim); } printf("Shrinking\n"); } } } while(min>0); //destroy for(i=0;i<dim;i++) oku_sod_destroy(polytope[i]); oku_sod_destroy(tmp); oku_sod_destroy(tmp2); free(polytope); free(fit); }
void set_blk(oku_sod* sod, int blk, int pos, int val){ set_idx(sod,sod->blkidx[blk][pos],val); }