Sudoku in Java. Index out of Bounds Exception - arrays

I've got an IndexOutOfBounds exception in the following program. It consists of three files:
Important are only two of them, the GUI is working fine. Here is the first one:
interface SudokuObserver {
public void modified(int i, int j);
}
public class SudokuData
{
public int[][] feld = new int[9][9];
public SudokuObserver obs = null;
public SudokuData()
{
int i,j;
for (i=0; i<9; i++) {
for (j=0; j<9; j++) {
feld[i][j] = 0;
}
}
}
public int getNumber(int x, int y)
{
return feld[x][y];
}
public void setNumber(int x, int y, int v)
{
feld[x][y] = v;
if (obs != null)
obs.modified(x, y);
}
public void setObserver(SudokuObserver o)
{
obs = o;
}
So the Sudoku field is allocated as a 9x9 integer array. The following file is called SudokuSolver and has an algorithm to write the possible numbers for each square into an ArrayList. Then the second algorithm works as following: He finds the square which has the minimum of possible numbers, sets the first of the numbers saved in the ArrayList on that square and does this recursive, so he starts again at defining the possible numbers for each square, taking the one with the smallest number of possibilities and picks the first one to put it into that field. A for-loop runs over the possible Numbers for each square while doing that.
import java.util.*;
public class SudokuSolver
{
SudokuData data;
public SudokuSolver(SudokuData d)
{
data = d;
}
{
/*Pseudoalgorithm:
- Inserts the numbers 1-9 into a Collection called res
- Looks at line x, which numbers are in there and erases them out of the
collection
- Looks at column y, which numbers are in there and erases them out of the
collection
- Looks in the 3x3 Square (x,y) which numbers are already in there and erases
them out of the collection
- Gives back the possible candidates for that field
*/
Here i initialize my ArrayList.
public ArrayList<Integer> offen(int x, int y)
{
ArrayList<Integer> res = new ArrayList<Integer>();
/* The collection is saved in an ArrayList */
int k = 0;
Here I just fill in the numbers 1-9 in my ArrayList.
for (int i=1;i<10;i++)
{
res.add(i);
}
Now comes the difficult part: I loop over j from zero to nine, then over k. The line is constant with the given x, the j runs over the columns, so i got every square in the given line, and in every square i check for every number from 1-9. Care: the index goes from 0-9 while the elements go from 1-9 so k has to be 0-9 cause the get()-method takes an index as input. If there is any compliance I remove the element from the ArrayList.
for (int j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[x][j] == (res.get(k)))
res.remove(k);
}
Same stuff as above for the columns, constant column and j loops.
for (k=0;k<9;k++)
{
if (this.data.feld[j][y] == res.get(k))
res.remove(k);
}
}
Now i get my inputs in two new variables, just because i had typed the code part below before with wrong variable names.
int m = x;
int n = y;
Here is the part for the 3x3 squares, i do this with if conditions, so this is just one of the 9 parts, I didn't want to post them all here, cause they just differ in a few constants. I check in which square my input x,y is, and then I loop over the square and check which numbers are there, which are also still in my ArrayList and remove them.
if (m<=2 && n<=2)
{
for (m=0;m<3;m++)
{
for (n=0;n<3;n++)
{
for (k=0;k<9;k++)
{
if (this.data.feld[m][n] == res.get(k))
res.remove(k);
}
}
}
}
Now I return the ArrayList
return res;
}
//findSolution() finds a Solution
public boolean findSolution()
{
/*Possible Strategy:
- Find the square, which has the fewest possible candidates
- If there are more than one candidates, who have the minimum of candidates,
take any of them
- If there are no more open candidates, there is a solution found. Return
true
- Loop over the candidates of this square and by setting the first possible
candidate into this square[x][y]
- Call the method findSolution() recursive to find in dependence of the set
value the values for the other fields
If there is a blind alley, take the next possible candidate (Backtracking!)
*/
int j = 0;
int k = 0;
int x = 0; // x coordinate of the field with the fewest open candidates
int y = 0; // y coordinate of the field with the fewest open candidates
int counter_offene_felder = 0; // counts the number of open fields
int min = 9;
I'm looping over j and k, looking if the number of possible candidates is more than 0, that means I'm running through the whole sudoku field and count the number of open fields.
for (j=0;j<9;j++)
{
for (k=0;k<9;k++)
{
if ( this.offen(j,k).size() >= 0)
{
counter_offene_felder += 1;
}
If the number is < than min = 9 possible candidates, i take it as the min and save the coordinates of that field
if ( (this.offen(j,k)).size() < min )
{
x = j;
y = k;
}
}
}
now i initialize and ArrayList for the field with the fewest possible candidates and put them into this ArrayList with my offen-method
ArrayList<Integer> candidate_list = this.offen(x,y);
for (k=0;k<this.offen(x,y).size();k++)
{ // runs over candidates
int v = this.offen(x,y).get(k); // takes the first candidate
this.data.setNumber(x,y,v); // writes the first candidate into square [x][y]
this.findSolution(); // calls findSolution() recursive
}
If there are no more open fields, I've found a solution
if (counter_offene_felder == 0)
{
return true;
}
else return false;
}
}
The problem is, that I get an IndexOutOfBounds Exception at line 39, at Index 8 Size 8. But I don't know why. :(

Not positive that this is where you are getting your error... but you could run into an issue when you do something like this.
for (k=0;k<9;k++)
{
if (this.data.feld[j][y] == res.get(k))
res.remove(k);
}
For instance, say that at k=1 the if statement evaluates to true. Then you will remove an element from the ArrayList. Then when k=8, and IndexOutOfBounds exception will be thrown because the ArrayList only contains 8 elements (0-7)
Assuming that no other threads will be modifying this.data.feld[][], you will only ever get one match when going through this loop.. so you could do something like this...
int match = -1;
for (k=0;k<res.size();k++) {
if (this.data.feld[j][y] == res.get(k)){
match = k;
break;
}
}
if(match != -1)
res.remove(match);

I think the contains() method will help eliminate your exceptions for this loop.
Try replacing your code with this:
for (m=0;m<3;m++)
{
for (n=0;n<3;n++)
{
if (res.contains(this.data.field[m][n]))
res.remove(res.indexOf(this.data.field[m][n]));
}
}
It will iterate over the data.field, and check the ArrayList to see if it contains the value at m,n. If it does, it will remove it.

Related

Making a Directed Acyclic Graph

I'm working on a task, where the final step is to take an array of pairs (where a pair is essentially an edge in a graph) and make an Acyclic graph from it. If a pair happens to create a cycle in the graph, then it should be skipped. The DAG is to be stored as an adjacency matrix (the edges are unweighted, hence it is of type bool matrix[][] )
I tried to implement a modified DFS, based on what I read online. The task is in C, and I'm new to the language, so sorry for the crudeness of the code.
The point is that it doesn't skip the cycle-forming pairs and I'm stuck at this point. Any advice or help is appreciated.
int MAX; //number of nodes in the graph
int player; //a node in the graph
typedef struct
{
int winner;
int loser;
} pair; //a directed edge from player 'winner' to player 'loser'
pair pairs[MAX * (MAX - 1) / 2]; //array of all valid pairs
int main(void)
{
/* Get input from console for:
MAX - desired number of players, <= 9,
. . .
int results[MAX][MAX]; - a table (2D array), where each element
results[A][B] shows the number of wins that player A
has over player B, and vice versa.
Element results[X][X] = 0 always.
A new pair is only added when two players have unequal
number of wins over each other: results[A][B] != results[B][A],
so that pairs[i].winner is the one having more wins than losses
against pairs[i].loser .
pairs[] is then sorted in descending order according to
the value of pairs[i].winner .
The goal is to create another 2D array
bool matrix[MAX][MAX];
by adding each pair in pairs[] sequentially,
so that matrix[][] is the adjacency matrix of a
Directed Acyclic Graph. (a.k.a. if a pair happens to create
a cycle, it must not be added)
*/
DAG();
}
void DAG(void)
{
int from, to;
for (int i = 0; i < pair_count; i++)
{
//Create an edge in graph
from = pairs[i].winner;
to = pairs[i].loser;
matrix[from][to] = true;
//Check if this edge made a cycle
bool visited[MAX];
bool onStack[MAX];
if (cyclicGraph(visited, onStack))
{
matrix[from][to] = false;
}
//Here we should have the DAG in locked
return;
}
bool cyclicGraph(bool visited[], bool onStack[])
{
for (int k = 0; k < MAX; k++)
{
//Run the hasCycle-DFS only from unvisited vertices
if (!visited[k] && hasCycle(k, visited, onStack))
{
//if it forms a cycle,
return true;
}
}
return false;
}
bool hasCycle(int x, bool visited[], bool onStack[])
{
// we push this 'x' node onto the stack
onStack[x] = true;
int child;
for (int i = 0; i < MAX; i++)
{
if (locked[x][i]) //x's children are only i's holding True values in array "locked[x][i]"
{
child = i;
if (onStack[child])
{
return true;
}
if (!visited[child] && hasCycle(child, visited, onStack))
{
return true;
}
}
}
//we pop the 'x' from the stack and mark it as visited
onStack[x] = false;
visited[x] = true;
return false;
}
I went back to this problem after a while and I found the bug. The two arrays bool visited[MAX]; bool onStack[MAX]; holding the information for the nodes being visited or being on the recursion stack during the DFS hadn't been initialized. A simple solution is to initialize them with false values:
memset(visited, false, sizeof visited);
memset(onStack, false, sizeof onStack);
Conclusion: always make sure to initialize your variables.

Updating specific elements in C array

I'm having trouble conceptualising how to go about some of my code.
My C program wishes to compare each individual element of an array of structs aka arr_person[i].name against a user's input to see if there's a match. (i.e. if the user types in "Billy" and "Billy" is also a string in arr_person[].name array)
for(i=0;i<num_of_lines;i++)
{
if(strcmp(nameInput, arr_person[i].name)==0) {
printf("Match at element %d\n", i);
}
}
Then, a separate function finds reoccurring elements within arr_person[i].name by iterating through the array, and if the same name occurs twice, it will take the corresponding integer values of the same elemental positions and will add them up and store in new variable newChange. For example, if "Billy" occurs twice in the array, at arr_person[0].name and arr_person[4].name, and arr_person[0].number = 15 and arr_person[4].number = 10, then I want to update the number such that it becomes 25.
for(i = 0; i < num_of_lines; i++) {
for(j=0;j<num_of_lines;j++) {
if(strcmp(arr_person[j].name, arr_person[i].name)==0)
*newNumber = arr_person[i].number + arr_person[j].number;
}
}
How do I go about this so that any elements in the array that don't reoccur are still kept the same?
If the user inputs "Rachel" and Rachel only appears once in the array, and her corresponding number is 85, I want to print
Rachel 85
But if the user inputs "Billy" and Billy occurs twice, and he has the two numbers 10 and 15 as corresponding integers in another array, I want to print
Billy 25
I've only been programming for a few months. Thanks in advance.
Seems like the only thing you need to do is this:
int sum = 0;
for(int i=0;i<num_of_lines;i++)
{
if(strcmp(nameInput, arr_person[i].name)==0)
sum += arr_person[i].number;
}
I would structure it like this:
// Previous code from your post slightly modified to function
// returns -1 on no match and index otherwise
int match(struct person *arr_person, char *nameInput, int num_of_lines)
{
for(int i=0;i<num_of_lines;i++) {
if(strcmp(nameInput, arr_person[i].name)==0)
return i;
}
return -1;
}
int sum(struct person *arr_person, char *nameInput, int num_of_lines)
{
int sum = 0;
for(int i=0;i<num_of_lines;i++) {
if(strcmp(nameInput, arr_person[i].name)==0)
sum += arr_person[i].number;
}
return sum;
}
int main()
{
// Insert code for declaration and initialization
int index = match(arr_person, nameInput, num_of_lines);
if(index >= 0) {
printf("Match at element %d\n", index);
printf("%s %d\n", nameInput, sum(arr_person, nameInput, num_of_lines));
} else {
printf("No match\n");
}
}

Recursive traversal of 2d array to find unique paths

I need to traverse a 2D-Array of 0's (which represent open pathways) and 1's which represent walls. I have to calculate the number of unique paths from (0,0) to (N-1,N-1) of an NxN Grid. I have written a recursive method to do this however i cannot figure out why the traversal part of my method (i.e the straight, left and right movements) are not working as expected:
public static void TraversePath(int [][] Grid, boolean[][] isTraversed, int column, int row) {
if(row < 0 || column < 0 || row > Grid[0].length || column > Grid[0].length )
return; // if you go out of bounds
if(isTraversed[column][row] == true)
return; // if you have already been to the point
if(Grid[column][row]==1) {
isTraversed[column][row] = true; // if the current point is a wall mark it as traversed
return;
}
if(Grid[column][row]!=1 && (row == Grid[0].length-1 && column == Grid[0].length-1)) { //if you get to an endpoint that isn't a wall
uniquePaths++; //counter that tallys the unique paths
isTraversed[column][row] = true;
return;
}
TraversePath(Grid,column,row+1);//Straight
TraversePath(Grid,column-1, row);//Left
TraversePath(Grid,column+1, row);//Right
}
public static void main(String[] args) {
int [][]Grid = new int[][]
{
{0,1,1,0},
{0,0,1,0},
{0,0,0,0},
{0,1,1,0}
};
boolean[][] isTraversed = new boolean[Grid.length][Grid.length];
for(int i = 0; i < Grid.length; i++) {
for(int j = 0; j< Grid.length; j++)
isTraversed[i][j] = false;
}
TraversePath(Grid,isTraversed,0,0);
System.out.println(uniquePaths);
}
I keep getting a StackOverFlow error (hey, sounds familiar) when I run this code. I figure it probably has something to do with how I am marking the edges as visited in the isTraversed boolean graph but I am not sure. Any help would be super appreciated.
This is the main method that I'm using to test the array, it's a simple 4x4 grid with 2 unique paths to (3,3).
Your Stack Overflow Error is caused by the fact that you can continuously move left then right again. Assuming that you could only move in the positive directions, you could make a very simple recursive function using dynamic programing to prevent you from getting a Stack Overflow error.
public static int possiblePaths(int[][] grid, int x,int y,int [][] dp){
if(x<0||x>=grid.length||y<0||y>=grid[0].length)
return 0;
if(dp[x][y]==-1){
dp[x][y]=possiblePaths(grid,x+1,y,dp)+possiblePaths(grid,x,y+1,dp);
}
return dp[x][y];
}
public static void main(String[] args) {
int [][]Grid = new int[][]
{
{0,1,1,0},
{0,0,1,0},
{0,0,0,0},
{0,1,1,0}
};
int [][] dp = new int[Grid.length][Grid[0].length];
for(int i = 0; i < Grid.length; i++) {
for(int j = 0; j< Grid[0].length; j++)
if(Grid[i][j]==1)
dp[i][j]=0;
else
dp[i][j]=-1;
}
dp[Grid.length-1][Grid[0].length-1]=0;
System.out.println(possiblePaths(Grid,0,0,dp));
}
What this basically states that the amount of ways to get from (x,y) to the end is the sum of # of paths from (x+1,y) and # of paths from (x,y+1) and remembers these numbers in the dp (Dynamic Programing) array so you do not need to recalculate them. In the dp array, the cells where there are walls are set to 0 because there are 0 ways to get to the end from the wall.
There are a couple of errors in this code, but the main problem is that you do not set isTraversed[column][row] = true if you just make a normal step without running into any of the if-statements.
Another big problem is, that the isTraversed array is shared across different search paths. This means that a grid-field visited in one branch of the iteration cannot be visited in another branch. Ultimately, your result will thus be always at most 1. In order to avoid this you could make a deep copy of isTraversed just before you enter the next iteration step.
boolean[][] isTraversedCopy = new boolean[isTraversed.length][isTraversed[0].length];
for(int i=0; i<isTraversed.length; i++)
for(int j=0; j<isTraversed[i].length; j++)
isTraversedCopy[i][j]=isTraversed[i][j];
TraversePath(Grid,isTraversedCopy, column,row+1);//Straight
TraversePath(Grid,isTraversedCopy, column-1, row);//Left
TraversePath(Grid,isTraversedCopy, column+1, row);//Right
Other problems are:
TraversePath(Grid,column,row+1);//Straight and the following lines are missing an argument (isTraversed)
in the first if-statement it should be
if(row < 0 || column < 0 || row >= Grid[0].length || column >= Grid[0].length)
Why is there no possibility to move to the bottom?
Optional but this will make readability of your code easier: You should change row and column to make it consistent to your representation of the gridworld and with the normal use of 2d-arrays. Additionally, your definition of straight, left, right is a bit confusing and does not fit to the grid definition.

Cryptography based in error correcting codes

I need to implement McEliece in C and this function is supposed to put a
matrix in systematic form. (U need a such matrix to encrypt the message by
matrix vector multiplication. Can someone help me to understand it?
You can find the whole code with all classes here. This function is from the file mat.c
int * mat_rref(binmat_t A)//This code is supposed to put matrix A in
//systematic form. typedef struct matrix{int
//rown, int coln, int alloc_size}*binmat_t;
{
int i,j,failcnt,findrow,max=A->coln - 1;
int *perm;
perm = malloc(A->coln * sizeof(int));//initialise permutation
for(i=0;i<A->coln;i++)
perm[i]=i;//initialize permutation.
failcnt = 0;
for(i=0;i<A->rown;i++,max--)
{
findrow=0;
for(j=i;j<A->rown;j++)
{
if(mat_coeff(A,j,max))//(A->elem[(j*A->coln)+max])
{
//max--;
if (i!=j)//not needed as ith row is 0 and jth row is 1.
A=mat_rowxor(A,i,j);//xor to the row.(swap)?
findrow=1;
break;
}//largest value found (end if)
// break;
}
if(!findrow)//if no row with a 1 found then swap last column and the column with no 1 down.
{
perm[A->coln - A->rown - 1 - failcnt] = max;
failcnt++;
if (!max)
{
return NULL;
}
i--;
}
else
{
perm[i+A->coln - A->rown] = max;
for(j=i+1;j<A->rown;j++)//fill the column downwards with 0's
{
if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1])
A=mat_rowxor(A,j,i);//check the arg. order.
}
for(j=i-1;j>=0;j--)//fill the column with 0's upwards too.
{
if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1])
A=mat_rowxor(A,j,i);
}
}
}//end for(i)
return(perm);
}

Algorithm to iterate N-dimensional array in pseudo random order

I have an array that I would like to iterate in random order. That is, I would like my iteration to visit each element only once in a seemingly random order.
Would it be possible to implement an iterator that would iterate elements like this without storing the order or other data in a lookup table first?
Would it be possible to do it for N-dimensional arrays where N>1?
UPDATE: Some of the answers mention how to do this by storing indices. A major point of this question is how to do it without storing indices or other data.
I decided to solve this, because it annoyed me to death not remembering the name of solution that I had heard before. I did however remember in the end, more on that in the bottom of this post.
My solution depends on the mathematical properties of some cleverly calculated numbers
range = array size
prime = closestPrimeAfter(range)
root = closestPrimitiveRootTo(range/2)
state = root
With this setup we can calculate the following repeatedly and it will iterate all elements of the array exactly once in a seemingly random order, after which it will loop to traverse the array in the same exact order again.
state = (state * root) % prime
I implemented and tested this in Java, so I decided to paste my code here for future reference.
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class PseudoRandomSequence {
private long state;
private final long range;
private final long root;
private final long prime;
//Debugging counter
private int dropped = 0;
public PseudoRandomSequence(int r) {
range = r;
prime = closestPrimeAfter(range);
root = modPow(generator(prime), closestPrimeTo(prime / 2), prime);
reset();
System.out.println("-- r:" + range);
System.out.println(" p:" + prime);
System.out.println(" k:" + root);
System.out.println(" s:" + state);
}
// https://en.wikipedia.org/wiki/Primitive_root_modulo_n
private static long modPow(long base, long exp, long mod) {
return BigInteger.valueOf(base).modPow(BigInteger.valueOf(exp), BigInteger.valueOf(mod)).intValue();
}
//http://e-maxx-eng.github.io/algebra/primitive-root.html
private static long generator(long p) {
ArrayList<Long> fact = new ArrayList<Long>();
long phi = p - 1, n = phi;
for (long i = 2; i * i <= n; ++i) {
if (n % i == 0) {
fact.add(i);
while (n % i == 0) {
n /= i;
}
}
}
if (n > 1) fact.add(n);
for (long res = 2; res <= p; ++res) {
boolean ok = true;
for (long i = 0; i < fact.size() && ok; ++i) {
ok &= modPow(res, phi / fact.get((int) i), p) != 1;
}
if (ok) {
return res;
}
}
return -1;
}
public long get() {
return state - 1;
}
public void advance() {
//This loop simply skips all results that overshoot the range, which should never happen if range is a prime number.
dropped--;
do {
state = (state * root) % prime;
dropped++;
} while (state > range);
}
public void reset() {
state = root;
dropped = 0;
}
private static boolean isPrime(long num) {
if (num == 2) return true;
if (num % 2 == 0) return false;
for (int i = 3; i * i <= num; i += 2) {
if (num % i == 0) return false;
}
return true;
}
private static long closestPrimeAfter(long n) {
long up;
for (up = n + 1; !isPrime(up); ++up)
;
return up;
}
private static long closestPrimeBefore(long n) {
long dn;
for (dn = n - 1; !isPrime(dn); --dn)
;
return dn;
}
private static long closestPrimeTo(long n) {
final long dn = closestPrimeBefore(n);
final long up = closestPrimeAfter(n);
return (n - dn) > (up - n) ? up : dn;
}
private static boolean test(int r, int loops) {
final int array[] = new int[r];
Arrays.fill(array, 0);
System.out.println("TESTING: array size: " + r + ", loops: " + loops + "\n");
PseudoRandomSequence prs = new PseudoRandomSequence(r);
final long ct = loops * r;
//Iterate the array 'loops' times, incrementing the value for each cell for every visit.
for (int i = 0; i < ct; ++i) {
prs.advance();
final long index = prs.get();
array[(int) index]++;
}
//Verify that each cell was visited exactly 'loops' times, confirming the validity of the sequence
for (int i = 0; i < r; ++i) {
final int c = array[i];
if (loops != c) {
System.err.println("ERROR: array element #" + i + " was " + c + " instead of " + loops + " as expected\n");
return false;
}
}
//TODO: Verify the "randomness" of the sequence
System.out.println("OK: Sequence checked out with " + prs.dropped + " drops (" + prs.dropped / loops + " per loop vs. diff " + (prs.prime - r) + ") \n");
return true;
}
//Run lots of random tests
public static void main(String[] args) {
Random r = new Random();
r.setSeed(1337);
for (int i = 0; i < 100; ++i) {
PseudoRandomSequence.test(r.nextInt(1000000) + 1, r.nextInt(9) + 1);
}
}
}
As stated in the top, about 10 minutes after spending a good part of my night actually getting a result, I DID remember where I had read about the original way of doing this. It was in a small C implementation of a 2D graphics "dissolve" effect as described in Graphics Gems vol. 1 which in turn is an adaption to 2D with some optimizations of a mechanism called "LFSR" (wikipedia article here, original dissolve.c source code here).
You could collect all possible indices in a list and then remove a random indece to visit. I know this is sort of like a lookup table, but i don't see any other option than this.
Here is an example for a one-dimensional array (adaption to multiple dimensions should be trivial):
class RandomIterator<T> {
T[] array;
List<Integer> remainingIndeces;
public RandomIterator(T[] array) {
this.array = array;
this.remainingIndeces = new ArrayList<>();
for(int i = 0;i<array.length;++i)
remainingIndeces.add(i);
}
public T next() {
return array[remainingIndeces.remove((int)(Math.random()*remainingIndeces.size()))];
}
public boolean hasNext() {
return !remainingIndeces.isEmpty();
}
}
On a side note: If this code is performance relevant, this method would perform worse by far, as the random removing from the list triggers copies if you use a list backed by an array (a linked-list won't help either, as indexed access is O(n)). I would suggest a lookup-structure (e.g. HashSet in Java) that stores all visited indices to circumvent this problem (though that's exactly what you did not want to use)
EDIT: Another approach is to copy said array and use a library function to shuffle it and then traverse it in linear order. If your array isn't that big, this seems like the most readable and performant option.
You would need to create a pseudo random number generator that generates values from 0 to X-1 and takes X iterations before repeating the cycle, where X is the product of all the dimension sizes. I don't know if there is a generic solution to doing this. Wiki article for one type of random number generator:
http://en.wikipedia.org/wiki/Linear_congruential_generator
Yes, it is possible. Imagine 3D array (you not likely use anything more than that). This is like a cube and where all 3 lines connect is a cell. You can enumerate your cells 1 to N using a dictionary, you can do this initialization in loops, and create a list of cells to use for random draw
Initialization
totalCells = ... (xMax * yMax * zMax)
index = 0
For (x = 0; x < xMax ; x++)
{
For (y = 0; y < yMax ; y++)
{
For (z = 0; z < zMax ; z++)
{
dict.Add(i, new Cell(x, y, z))
lst.Add(i)
i++
}
}
}
Now, all you have to do is iterate randomly
Do While (lst.Count > 0)
{
indexToVisit = rand.Next(0, lst.Count - 1)
currentCell = dict[lst[indexToVisit]]
lst.Remove(indexToVisit)
// Do something with current cell here
. . . . . .
}
This is pseudo code, since you didn't mention language you work in
Another way is to randomize 3 (or whatever number of dimensions you have) lists and then just nested loop through them - this will be random in the end.

Resources