I'm programming a Sudoku solver and have come across two problems.
I would like to generate a specific number of literals, but keep the total number flexible
How can I prevent a negation cycle, so that I have a clean solution for declaring a digit as not possible?
General code with generator regarding my first question:
row(1..3). %coordinates are declared via position of sub-grid (row, col) and position of
col(1..3). %field in sub-grid (sr, sc)
sr(1..3).
sc(1..3).
num(1..9).
1 { candidate(R,C,A,B,N) : num(N) } 9 :- row(R), col(C), sr(A), sc(B).
Here I want to create all candidates for a field, which at the beginning are all the numbers from 1 to 9. So I want for all candidate(1,1,1,1,1-9). But it would be nice to keep the number of candidates for each field flexible, so I can declare a solution if through integrity constraints like
:- candidate(R,C,A,B,N), solution(R1,C,A1,B,N), R != R1, A != A1. %excludes candidates if digit is present in solution in same column
I have excluded all 8 other candidates:
solution(R,C,A,B,N) :- candidate(R,C,A,B,N), { N' : candidate(R,C,A,B,N') } = 1.
Regarding my second question, I basically want to declare a solution, if a specific condition is fulfilled. The problem is, if I have a solution, the condition is no longer true and this leads to a negation cycle:
solution(R,C,A,B,N) :- candidate(R,C,A,B,N), { set1(R',C',A',B') } = { posDigit(N') }, { negDigit(N'') } = { set2(R'',C'',A'',B'') } - 1, not taken(R,C,A,B), not takenDigit(N).
taken(R,C,A,B) :- solution(R,C,A,B,N).
I would be glad I somebody offers input on how to solve these problems.
I've got a protocol that supports bursts, where each transaction is composed of N individual transfers. Each transfer has a unique index from 0 to N-1. I would like to cover that all transfer orders have been seen (i.e. 0 1 2 3, 1 2 3 0, 0 2 3 1, etc.). The value of N is variable (though in my case I only care about 4 and 8 for now).
The naive approach would be to cover each index individually and cross them, but this would mean I would need multiple covergroups, one per each value of N.
For N = 4:
covergroup some_cg;
coverpoint idxs[0];
coverpoint idxs[1];
coverpoint idxs[2];
coverpoint idxs[3];
cross idxs[0], idxs[1], idxs[2], idxs[3] {
ignore_bins non_unique_idxs[] = some_func_that_computes_bins_for_4_idxs();
}
endgroup
For N = 8:
covergroup some_cg;
coverpoint idx[0];
coverpoint idx[1];
coverpoint idx[2];
coverpoint idx[3];
coverpoint idx[4];
coverpoint idx[5];
coverpoint idx[6];
coverpoint idx[7];
cross idx[0], idx[1], idx[2], idx[3], idx[4], idx[5], idx[6], idx[7] {
ignore_bins non_unique_idxs[] = some_func_that_computes_bins_for_8_idxs();
}
endgroup
The two functions that generate the ignore bins each have to return different types (queue of struct with 4/8 fields), even though conceptually the operation for computing all illegal combinations is similar, regardless of the value of N. This could probably be solved with some clever use of the streaming operator, to stream the contents of the structs into arrays of N elements. The issue of redundancy in the covergroup definitions remains though. The only way I can think of solving this is by generating the code.
Another idea would be to pack all indexes into a packed array of the appropriate size and cover that:
covergroup some_other_cg;
coverpoint packed_idxs {
ignore_bins non_unique_idxs[] = some_func_that_computes_bins_for_N_idxs();
}
endgroup
// Probably won't compile, but it would also be possible to use the streaming op
// Idea is to pack into integral type
foreach (idxs[i])
packed_idxs[i * idx_len +: len] = idxs[i];
It's a pain to debug coverage holes, as it's difficult to figure what transfer order a certain packed value belongs to, especially if the values are shown in decimal radix. I believe the way values are displayed varies from tool to tool and it's not possible to control this. I also don't see any possibility to give names to individual bins using strings.
I would welcome any input that would improve upon any of the two suggestions. The goal is to have one coverage wrapper class with a parameter for the number of transfers and to be able to instantiate that and get the coverage:
class transfer_orders_coverage #(int unsigned NUM_TRANSFERS);
// ...
endclass
Adding as and 'Answer' since it was too long for comment. Pardon me if I am not clear.
Can you add some logic before sampling CG and use some input argument that denotes array position of idxs? For the crosses, you can maintain a packed array of size N and make individual bits 1 when a particular pattern is detected. At the end of sim, you can sample the coverage for that pattern in some different CG.
Basically the idea is to offload logic inside the covergroups and add logic surrounding sample function. Here is a rough idea about what I was thinking.
class transfer_orders_coverage #(int unsigned N = 4);
int idxs[N];
bit [(N -1) : 0] pattern; // Make indexes HIGH according to sampled pattern
// ...
covergroup cross_cg;
mycp_cross: coverpoint pattern{
ignore_bins myignbn = {some_generic_function_for_N(pattern)};
}
endgroup
covergroup indiv_cg with function sample (int index);
mycp_indiv: coverpoint idxs[index]{
// some bins to be covered in ith position of idxs
}
endgroup
function new();
cross_cg = new;
indiv_cg = new;
endfunction
function bit [(N -1) : 0] some_generic_function_for_N(bit [(N -1) : 0] pattern);
// check which bits in "pattern" are to be covered and which are to be ignored
//return some_modified_pattern;
endfunction
function void start();
// Any logic for sampling ith position
foreach(idxs[i]) begin
indiv_cg.sample(i);
pattern[i] = 1'b1;
end
cross_cg.sample();
endfunction
endclass
module top();
transfer_orders_coverage #(4) tr;
initial begin
tr = new;
tr.start();
end
endmodule
Let me know if it seems feasible or not.
I guess, the following solution may work in this case.
covergroup some_cg (int num);
4n_cp : coverpoint ({idxs[0], idxs[1], idxs[2], idxs[3]}) iff (num == 4)
{
option.weight = (num == 4) ? 1 : 0; // Weight might change depending on other coverpoints
ignore_bins non_unique_index[] = <Your Function>;
}
8n_cp : coverpoint ({idxs[0], idxs[1], idxs[2], idxs[3], idxs[4], idxs[5], idxs[6], idxs[7]}) iff (num == 8)
{
option.weight = (num == 8) ? 1 : 0; // Weight might change depending on other coverpoints
ignore_bins non_unique_index[] = <Your Function>;
}
endgroup
// Where you instantiate covergroups
some_cg c1 = new(4);
Let me know, how the above idea works.
include "globals.mzn";
%Data
time_ID = [11,12,13,14,15];
eventId = [0011, 0012, 0013, 0021, 0022, 0031, 0041, 0051, 0061, 0071];
int:ntime = 5;
int:nevent = 10;
set of int: events =1..nevent;
set of int: time = 1..ntime;
array[1..nevent] of int:eventId;
array[1..nevent] of var time:event_time;
array[1..ntime] of int:time_ID;
solve satisfy;
constraint
forall(event in eventId)(
exists(t in time_ID)(
event_time[event] = t ));
output[ show(event_time) ];
I'm trying to assign times to an event using the code above.
But rather than randomly assign times to the events, it returns an error " array access out of bounds"
How can I make it select randomly from the time array?
Thank you
The error was because you tried to assign the index 11 (the first element in eventId array) in "event_time" array.
The assigment of just 1's is correct since you haven't done any other constraints on the "event_time" array. If you set the number of solutions to - say - 3 you will see other solutions. And, in fact, the constraint as it stand now is not really meaningful since it just ensures that there is some assignment to the elements in "event_time", but this constraint is handled by the domain of "event_time" (i.e. that all indices are in the range 1..ntime).
So I'm trying to write a simple genetic algorithm for solving a sudoku (not the most efficient way, I know, but it's just to practice evolutionary algorithms). I'm having some problems coming up with an efficient evaluation function to test if the puzzle is solved or not and how many errors there are. My first instinct would be to check if each row and column of the matrix (doing it in octave, which is similar to matlab) have unique elements by ordering them, checking for duplicates and then putting them back the way they were, which seems long winded. Any thoughts?
Sorry if this has been asked before...
Speedups:
Use bitwise operations instead of sorting.
I made 100 line sudoku solver in c it reasonably fast. For or super speed you need to implement DLX algorhitm, there is also some file on matlab exchange for that.
http://en.wikipedia.org/wiki/Exact_cover
http://en.wikipedia.org/wiki/Dancing_Links
http://en.wikipedia.org/wiki/Knuth's_Algorithm_X
#include "stdio.h"
int rec_sudoku(int (&mat)[9][9],int depth)
{
int sol[9][9][10]; //for eliminating
if(depth == 0) return 1;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
sol[i][j][9]=9;
for(int k=0;k<9;k++)
{
if(mat[i][j]) sol[i][j][k]=0;
else sol[i][j][k]=1;
}
}
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(mat[i][j] == 0) continue;
for(int k=0;k<9;k++)
{
if(sol[i][k][mat[i][j]-1])
{
if(--sol[i][k][9]==0) return 0;
sol[i][k][mat[i][j]-1]=0;
}
if(sol[k][j][mat[i][j]-1])
{
if(--sol[k][j][9]==0) return 0;
sol[k][j][mat[i][j]-1]=0;
}
}
for(int k=(i/3)*3;k<(i/3+1)*3;k++)
{
for(int kk=(j/3)*3;kk<(j/3+1)*3;kk++)
{
if(sol[k][kk][mat[i][j]-1])
{
if(--sol[k][kk][9]==0) return 0;
sol[k][kk][mat[i][j]-1]=0;
}
}
}
}
}
for(int c=1;c<=9;c++)
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(sol[i][j][9] != c) continue;
for(int k=0;k<9;k++)
{
if(sol[i][j][k] != 1) continue;
mat[i][j]=k+1;
if(rec_sudoku(mat,depth-1)) return 1;
mat[i][j]=0;
}
return 0;
}
}
}
return 0;
}
int main(void)
{
int matrix[9][9] =
{
{1,0,0,0,0,7,0,9,0},
{0,3,0,0,2,0,0,0,8},
{0,0,9,6,0,0,5,0,0},
{0,0,5,3,0,0,9,0,0},
{0,1,0,0,8,0,0,0,2},
{6,0,0,0,0,4,0,0,0},
{3,0,0,0,0,0,0,1,0},
{0,4,0,0,0,0,0,0,7},
{0,0,7,0,0,0,3,0,0}
};
int d=0;
for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(matrix[i][j] == 0) d++;
if(rec_sudoku(matrix,d)==0)
{
printf("no solution");
return 0;
}
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
printf("%i ",matrix[i][j]);
}
printf("\n");
}
return 1;
}
The check is easy, you'll create sets for rows, columns, and 3x3's adding a number if it does not exist and altering your fitness accordingly if it does not.
The real trick however is "altering your fitness" accordingly. Some problems seem well suited to GA and ES (evolution strategies), that is we look for a solution in tolerance, sudoku has an exact answer... tricky.
My first crack would probably be creating solutions with variable length chromosomes (well they could be fixed length but 9x9's with blanks). The fitness function should be able to determine which part of the solution is guaranteed and which part is not (sometimes you must take a guess in the dark in a really tough sudoku game and then back track if it does not work out), it would be a good idea to create children for each possible branch.
This then is a recursive solution. However you could start scanning from different positions on the board. Recombination would combine solutions which combine unverified portions which have overlapping solutions.
Just thinking about it in this high level easy going fashion I can see how mind bending this will be to implement!
Mutation would only be applied when there is more than one path to take, after all a mutation is a kind of guess.
Sounds good, except for the 'putting them back' part. You can just put the numbers from any line, column or square in the puzzle in a list and check for doubles any way you want. If there are doubles, there is an error. If all numbers are unique there's not. You don't need to take the actual numbers out of the puzzle, so there is no need for putting them back either.
Besides, if you're writing a solver, it should not make any invalid move, so this check would not be needed at all.
I would use the grid's numbers as an index, and increment an 9 elements length array's respective element => s_array[x]++ where x is the number taken from the grid.
Each and every element must be 1 in the array at the end of checking one row. If 0 occurs somewhere in the array, that line is wrong.
However this is just a simple sanity check if there are no problems, line-wise.
PS: if it were 10 years ago, I would suggest an assembly solution with bit manipulation (1st bit, 2nd bit, 3rd bit, etc. for the values 1,2 or 3) and check if the result is 2^10-1.
When I solved this problem, I just counted the number of duplicates in each row, column and sub-grid (in fact I only had to count duplicates in columns and sub-grids as my evolutionary operators were designed never to introduce duplicates into rows). I just used a HashSet to detect duplicates. There are faster ways but this was quick enough for me.
You can see this visualised in my Java applet (if it's too fast, increase the population size to slow it down). The coloured squares are duplicates. Yellow squares conflict with one other square, orange with two other squares and red with three or more.
Here is my solution. Sudoku solving solution in C++
Here is my solution using set. If for a line, a block or a column you get a set length of (let say) 7, your fitness would be 9 - 7.
If you are operating on a small set of integers sorting can be done in O(n) using bucket sorting.
You can use tmp arrays to do this task in matlab:
function tf = checkSubSet( board, sel )
%
% given a 9x9 board and a selection (using logical 9x9 sel matrix)
% verify that board(sel) has 9 unique elements
%
% assumptions made:
% - board is 9x9 with numbers 1,2,...,9
% - sel has only 9 "true" entries: nnz(sel) = 9
%
tmp = zeros(1,9);
tmp( board( sel ) ) = 1; % poor man's bucket sorting
tf = all( tmp == 1 ) && nnz(sel) == 9 && numel(tmp) == 9; % check validity
Now we can use checkSubSet to verify the board is correct
function isCorrect = checkSudokuBoard( board )
%
% assuming board is 9x9 matrix with entries 1,2,...,9
%
isCorrect = true;
% check rows and columns
for ii = 1:9
sel = false( 9 );
sel(:,ii) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
sel = false( 9 );
sel( ii, : ) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
end
% check all 3x3
for ii=1:3:9
for jj=1:3:9
sel = false( 9 );
sel( ii + (0:2) , jj + (0:2) ) = true;
isCorrect = checkSubSet( board, sel );
if ~isCorrect
return;
end
end
end