For some reason when I run dijkstra's algorithm on my randomly generated matrix it does not find paths between all the nodes even though it's clear that it's a connected graph. I've printed out the graphs and they always follow this form
0--2--3
| | |
4--5--6
| | |
7--8--9
Right now I'm only working with a 3*3 matrix and am trying to get that to work properly. The below code makes a adjacency matrix with 9 nodes and randomly generates a number between 1 and 3 to represent the weights of edges. I use 4 for infinity.
source is hard coded to 0 and numOfVertices 9
#include<iostream>
#include <time.h>
#include <math.h>
#define INFINITY 4
#define V 9
using namespace std;
class Dijkstra{
private:
int predecessor[20],distance[20];
bool mark[20];
int source;
int destination;
int numOfVertices;
char gameMode;
public:
int adjMatrix[9][9];
void read();
void initialize();
void setSource(int k);
int getClosestUnmarkedNode();
void calculateDistance();
void output();
int randomEdge();
int randomNode();
void printPath(int);
};
void Dijkstra::read(){
numOfVertices = 4;
for(int i = 0; i < numOfVertices;i++){
for(int j = 0; j < numOfVertices;j++){
if(i == j)
adjMatrix[i][j] = 0;
else if(j >= i){
if(j == i + 1 || j == i - 1 || j == i + sqrt((double)numOfVertices)|| j == i - sqrt((double)numOfVertices))
adjMatrix[i][j] = randomEdge();
else
adjMatrix[i][j] = 4;
if((i % ((int)sqrt((double)numOfVertices)) == ((int)sqrt((double)numOfVertices)) - 1) && j == i + 1)
adjMatrix[i][j] = 4;
}
else
adjMatrix[i][j] = adjMatrix[j][i];
cout<<adjMatrix[i][j]<< " ";
}
cout<< "\n";
}
source = 0;
}
void Dijkstra::initialize(){
for(int i=0;i<numOfVertices;i++) {
mark[i] = false;
predecessor[i] = -1;
distance[i] = INFINITY;
}
distance[source]= 0;
}
int Dijkstra::getClosestUnmarkedNode(){
int minDistance = INFINITY;
int closestUnmarkedNode = 0;
for(int i=0;i<numOfVertices;i++) {
if((!mark[i]) && ( minDistance >= distance[i])) {
minDistance = distance[i];
closestUnmarkedNode = i;
}
}
return closestUnmarkedNode;
}
void Dijkstra::calculateDistance(){
initialize();
int minDistance = INFINITY;
int closestUnmarkedNode;
int count = 0;
while(count < numOfVertices) {
closestUnmarkedNode = getClosestUnmarkedNode();
mark[closestUnmarkedNode] = true;
for(int i=0;i<numOfVertices;i++) {
if((!mark[i]) && (adjMatrix[closestUnmarkedNode][i]>0) ) {
if(distance[i] > distance[closestUnmarkedNode]+adjMatrix[closestUnmarkedNode][i]) {
distance[i] = distance[closestUnmarkedNode]+adjMatrix[closestUnmarkedNode][i];
predecessor[i] = closestUnmarkedNode;
}
}
}
count++;
}
}
void Dijkstra::printPath(int node){
if(node == source)
cout<<node<<"..";
else if(predecessor[node] == -1)
cout<<"No path from "<<source<<"to "<<node<<endl;
else {
printPath(predecessor[node]);
cout<<node<<"..";
}
}
void Dijkstra::output(){
for(int i=0;i<numOfVertices;i++) {
if(i == source)
cout<<source<<".."<<source;
else
printPath(i);
cout<<"->"<<distance[i]<<endl;
}
}
int Dijkstra::randomEdge(){
return rand() % 3 + 1;
}
void Dijkstra::setSource(int k){
source = k;
}
int main(int argc, char** argv){
Dijkstra G;
G.read();
G.calculateDistance();
G.output();
int k;
cin>> k;
exit(0);
}
You are using 4 to represent infinite distance... but 4 is a distance that is easy to reach along a valid path. This code rejects any path with a total distance >=4, because every node starts out with a distance at most 4 (i.e. unreachable) from the source.
Related
I am currently a high school student and a beginner at programming on C++ and LUA.
I am trying to make a program using CodeBlocks, and I just made this code on C++:
#include <cstring>
using namespace std;
int st[20],n,ok,x,p;
char v[8] = "abcdefg",voc[] = "aeiouAEIOU",lit[] = "a";
// (n - 1)! n=9
void afisare(int k){
int i;
for (i=1;i<=k;i++)
cout<<v[st[i]]<<" ";
cout<<endl;
}
void valid(int k,int&ok){
int i;
ok = 0;
//cout<<v[st[k]];
if (strchr(lit,v[st[1]]) != NULL && strchr(lit,v[st[k]]) != NULL)
ok = 1;
for (i = 1; i <= k-1; i++)
if (st[k] == st[i])
ok = 0;
}
void back(){
int k;
k = 1;
x = 0;
st[k] = -1;
while(k > 0){
ok = 0;
while (ok==0 && st[k]<n - 1){
st[k] = st[k] + 1;
valid(k,ok);
}
if (ok == 1)
if (k == n){ //
afisare(k);
x++;
}
else {
k++;
st[k] = -1;}
else
k--;
}
}
int main()
{
//cin>>p;
n = strlen(v);
//while (p > n)
//cin>>p;
back();
cout<<endl<<"x! = "<<x;
return 0;
}
However it only shows:
x! = 0
Does anyone know the solution for this program? I am currently beginner at backtracking by the way.
I've been trying to implement a class which uses a flooding algorithm to generate a list of the indexes for the optimal path between a specified source and destination index.
Such as:
void Dijkstra::findShortestPath(uint sourceIndex, uint destIndex, std::vector<int> & optimalPath);
For example, given a 5x5 2d matrix, find the optimal path between between X and Y:
[1][1][1][1][1]
[1][1][10][10][1]
[X][1][10][Y][1]
[1][1][10][10][1]
[1][1][1][1][1]
Expected result:
start(10)->11->6->1->2->3->4->9->14->13
Where the above index values map to row and column indexes in the matrix:
index = numOfVertices * rowNumber + rowNumber
I have found several different variants, but no implementation yet which does the above.
This algorithim I'm currently trying to extend to this, I found here:
http://www.programming-techniques.com/2012/01/implementation-of-dijkstras-shortest.html?m=1
Though I do not see how a destination node can be specified here, so I am struggling to understand how I can extend this.
My version is below, compiles and runs fine, however you can only specify the source index in the setBoard() function.
Code:
#include <iostream>
#include "stdio.h"
using namespace std;
const int BOARD_SIZE = 5;
const int INFINITY = 999;
class Dijkstra {
private:
int adjMatrix[BOARD_SIZE][BOARD_SIZE];
int predecessor[BOARD_SIZE];
int distance[BOARD_SIZE];
bool mark[BOARD_SIZE];
int source;
int numOfVertices;
public:
int getIndex(int row, int col);
void setBoard();
/*
* Function initialize initializes all the data members at the begining of
* the execution. The distance between source to source is zero and all other
* distances between source and vertices are infinity. The mark is initialized
* to false and predecessor is initialized to -1
*/
void initialize();
/*
* Function getClosestUnmarkedNode returns the node which is nearest from the
* Predecessor marked node. If the node is already marked as visited, then it search
* for another node.
*/
int getClosestUnmarkedNode();
/*
* Function calculateDistance calculates the minimum distances from the source node to
* Other node.
*/
void calculateDistance();
/*
* Function output prints the results
*/
void output();
void printPath(int);
};
int Dijkstra::getIndex(int row, int col)
{
return numOfVertices * row + col;
}
void Dijkstra::setBoard()
{
source = 0;
numOfVertices = BOARD_SIZE;
cout << "Setting board..." << numOfVertices << " source: " << source << "\n";
for (int i = 0; i < numOfVertices; i++)
{
for (int j = 0; j < numOfVertices; j++)
{
if (getIndex(i, j) == 7 || getIndex(i, j) == 8 || getIndex(i, j) == 12 || getIndex(i, j) == 17 || getIndex(i, j) == 18)
{
adjMatrix[i][j] = 10;
}
else
{
adjMatrix[i][j] = 1;
}
}
}
// print board
printf("\n");
printf("\n");
for (int i = 0; i < numOfVertices; i++)
{
for (int j = 0; j < numOfVertices; j++)
{
if (j == 0)
{
printf("\n");
}
if (source == getIndex(i, j))
{
printf("[X]");
}
else
{
printf("[%d]", adjMatrix[i][j]);
}
}
}
printf("\n");
printf("\n");
}
void Dijkstra::initialize()
{
for (int i = 0; i < numOfVertices; i++)
{
mark[i] = false;
predecessor[i] = -1;
distance[i] = INFINITY;
}
distance[source] = 0;
}
int Dijkstra::getClosestUnmarkedNode()
{
int minDistance = INFINITY;
int closestUnmarkedNode;
for (int i = 0; i < numOfVertices; i++)
{
if ((!mark[i]) && ( minDistance >= distance[i]))
{
minDistance = distance[i];
closestUnmarkedNode = i;
}
}
return closestUnmarkedNode;
}
void Dijkstra::calculateDistance()
{
int minDistance = INFINITY;
int closestUnmarkedNode;
int count = 0;
while (count < numOfVertices)
{
closestUnmarkedNode = getClosestUnmarkedNode();
mark[closestUnmarkedNode] = true;
for (int i = 0; i < numOfVertices; i++)
{
if ((!mark[i]) && (adjMatrix[closestUnmarkedNode][i] > 0) )
{
if (distance[i] > distance[closestUnmarkedNode] + adjMatrix[closestUnmarkedNode][i])
{
distance[i] = distance[closestUnmarkedNode] + adjMatrix[closestUnmarkedNode][i];
predecessor[i] = closestUnmarkedNode;
}
}
}
count++;
}
}
void Dijkstra::printPath(int node)
{
if (node == source)
{
cout << (char) (node + 97) << "..";
}
else if (predecessor[node] == -1)
{
cout << "No path from “<<source<<”to " << (char) (node + 97) << endl;
}
else
{
printPath(predecessor[node]);
cout << (char) (node + 97) << "..";
}
}
void Dijkstra::output()
{
for (int i = 0; i < numOfVertices; i++)
{
if (i == source)
{
cout << (char) (source + 97) << ".." << source;
}
else
{
printPath(i);
}
cout << "->" << distance[i] << endl;
}
}
int main()
{
Dijkstra G;
G.setBoard();
G.initialize();
G.calculateDistance();
G.output();
return 0;
}
Once, in void Dijkstra::calculateDistance(), you do
mark[closestUnmarkedNode] = true;
You have the shortest path from source to closestUnmarkedNode.
So you may add just after
if (closestUnmarkedNode == destNode) {
return;
}
to stop the flood fill.
You will have shortest path for all visited nodes including destNode
#include<iostream>
#include<random>
#include<ctime>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std;
int path_checker(vector<pair<int,int> > path, int i, int j)
{
//cout<<"path_checker"<<endl;
std::vector<pair<int, int> >::iterator it;
for(it = path.begin(); it!=path.end();it++)
if(it->first == i && it->second ==j)
return 1;
return 0;
}
int isVertex(int i, int j, int n)
{
//cout<<"isVertex"<<endl;
if((i>=0) && (j>=0))
{
if((i <= n) && (j <= n))
return 1;
}
return 0;
}
void printAllPathsU(int *array, int i, int j, int n, vector<pair<int,int> > path,int index)
{
// cout<<"PrintAllPathsU_first"<<endl;
// vector<pair<int,int>> path2 = {0};
if((i == n) && (j == n))
{
if((path_checker(path,i,j)))
{
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
else
{
path.push_back(make_pair(i,j));
cout<<"Inside printing path"<<endl;
//vector<pair<int,int> >::iterator it;
for(int i = 0; i < path.size();i++)
cout<<"a["<<path[i].first<<"]["<<path[i].second<<"] ";
return;
}
}
if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
//cout<<path.size()<<endl;
path.push_back(make_pair(i,j));
index++;
//len++;
if(isVertex(i,j-1,n))
printAllPathsU((int *)array,i,j-1,n,path,index);
if(isVertex(i-1,j,n))
printAllPathsU((int *)array,i-1,j,n,path,index);
if(isVertex(i,j+1,n))
printAllPathsU((int *)array,i,j+1,n,path,index);
if(isVertex(i+1,j,n))
printAllPathsU((int *)array,i+1,j,n,path,index);
}
else if((*((array+i*n)+j) == 1) && (path_checker(path,i,j)))
{
//cout<<"inside second else"<<endl;
return;
}
else if(*((array+i*n)+j) == 0)
{
// cout<<"inside third else"<<endl;
return;
}
}
void printAllPaths(int *array, int n)
{
vector<pair<int,int> > path;
//cout<<"PrintALLPaths"<<endl;
printAllPathsU(array, 0, 0, n, path, 0);
}
int main()
{ //populating matrix
int n;
cout << "Enter value of n (for n x n matrix): ";
cin >> n;
int i;
int j;
int k;
int test=1;
int array[n][n];
int randomval;
int total_elements = n*n;
int counter_0 = 0;
int max_0 = 0.2 * total_elements;
cout << "Number of zeros(20% of n*n) in matrix: ";
cout<<max_0<<endl;
int count=0;
srand(time(0));
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
array[i][j]=-1;
}
}
while(count < total_elements)
{
i=rand()%n;
j=rand()%n;
if(array[i][j]==1 || array[i][j]==0)
{
continue;
}
else if(array[i][j] == -1)
{
count+=1;
if(i==0 && j==0)
{
array[i][j]=1;
}
else if (counter_0 < max_0)
{
counter_0+=1;
array[i][j] = 0;
}
else if(counter_0 >= max_0)
{
test+=1;
array[i][j] = 1;
}
}
else{continue;}
}
cout<<"# of 1s:"<<test<<" & # of 0s:"<<counter_0<<endl;
cout<<"Elements Populated:"<<count<<endl;
cout<<"Total Elements in matrix:"<<total_elements<<endl;
if(counter_0 < max_0)
{ cout<<"adding more zeros"<<endl;
while(k < (max_0 - counter_0))
{
i = rand()%n;
j = rand()%n;
if(array[i][j] == 0)
{
}
else
{
array[i][j] = 0;
k+=1;
}
}
}
for(i = 0;i < n;i++)
{
for(j = 0;j<n;j++)
{
cout<<array[i][j]<<" ";
}
cout<<endl;
}
//printing paths
if(array[1][0]==0 && array[0][1]==0)
{
cout<<"No Possible paths homie #snorlaxiseverywhere";
}else
{
//printing paths
printAllPaths((int *)array, n);
}
return 0;
}
The question is to traverse through a n * n matrix populated with 1s and 0s, with the number of 0s in the matrix being 20% of the total number of elements, and print all paths and then the shortest path from the [0][0] to [n][n], using four direction: up,down,left and right.
So far I have tried to implement printing all possible paths. However, I am stuck in an infinite loop in the
else if((*((array+i*n)+j) == 1) && (!path_checker(path,i,j)))
{
...
}
I cout the path.size() to check what the size is becoming in each instance, and the output is somewhat like :
35
48
37
...and so on infinitely (values ranging approx between 30-50)
Any ideas how to correct this?
EDIT : Changed up some logic, not stuck infinite loop. But all of the function calls exit through the "second else" and the "third else" inside the function - printAllPathsU(...).
Thanks!
As long as the question is how to "print all paths", you should have an infinite loop because there are infinitely many paths. If the question is how to print all non-self-intersecting paths, then this rephrasing gives a hint on how to go about solving the problem.
I've been working on a program in one of my college classes. I have been having trouble with the implementation of my LRU code as it is not displaying any errors or anything, but compiles. There are two parts. The main that we input the values into, which we then specify which algorithm we want to use to find page faults. I know the main works, along with the FIFO algorithm, but I'm not getting anything with my LRU code (It compiles and "runs" but displays nothing as if I did not click to use the algorithm). Can anyone help me figure out what is wrong?
main.cpp
#include <iostream>
#include <string>
//#include "fifo.cpp"
#include "lru.cpp"
//#include "optimal.cpp"
using namespace std;
int main() {
// List of different variables
string pagestring;
int fs,pn[50], n;
// Prompt for page references
cout<<"Virtual Memory Simulation\nBy blah\n----------\nEnter the number of pages : " << endl;
cin >> n;
cout<<"\n-------------\nPlease enter a list of page numbers separated by commas.\n"<< endl;
cin>>pagestring;
// algorithm to use
char algo;
while (true) {
// Prompt algorithm to use
cout<<"----------\nPlease select an algorithm to use.\n\n1: First-In-First-Out (FIFO)\n2: Least-Recently-Used (LRU)\n3: Optimal\n0: Quit\n"<<endl;
cin>>algo;
if (algo == '1') {
//fifo(pagestring);
}
else if (algo == '2'){
LRU_Execute(pagestring, n);
}
else if (algo == '3'){
cout<<"Optimal Not yet coded"<<endl;
}
else if (algo == '0'){
break;
}
else {
cout<<"Invalid choice. Please try again."<<endl;
}
}
cout<<"Goodbye!!"<<endl;
};
LRU.cpp
#include <iostream>
#include <string>
using namespace std;
class pra
{
int fs,z;
int frame[50], frame1[50][2], pn[50], n, cnt, p, x;
public:
pra();
void init(string pagestring);
void getdata(string pagestring, int n);
void lru(int* pn, int n, string pagestring);
};
pra::pra()
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::init(string pagestring)
{
int i;
for (i = 0; i < fs; i++)
{
frame[i] = -1;
}
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
p = 0;
cnt = 0;
}
void pra::getdata(string pagestring, int n)
{
fs=3;
// index to loop through input string
int i = 0;
// current input string character
char z = pagestring[i];
int x = 0;
//cout << "\nEnter the page numbers : ";
while (z != '\0'){
// skip over commas and spaces
if (!(z == ',')) {
pn[x] = z;
x++;
// cout<<pn[x]<<"-This is pn[x]\n";
}
z = pagestring[++i];
}
//cout<<pn[x]<<"-This is pn[x] AGAIN\n";
this->lru(pn, n, pagestring);
}
void pra::lru(int* pn, int n, string pagestring)
{
init(pagestring);
int ind = 0, fault = 0, pi = 0, j, fn;
char i, z;
p = 0;
cnt = 0;
int min;
cout<<n<<"---"<<i<<" - "<<j<<" - "<<" - "<<fn<<" - "<<z;
for (i = 0; i < fs; i++)
{
frame1[i][0] = -1;
frame1[i][1] = 0;
}
pi = 0;
for (i = 0; i < n; i++)
{
j = 0;
if (ind > fs - 1)
ind = 0;
fault = 1;
min = 999;
while (j < fs)
{
if (frame1[j][0] = pn[pi])
{
fault = 0;
p++;
frame1[j][1] = p;
goto l2;
}
if (frame1[j][1] < min)
{
min = frame1[j][1];
fn = j;
}
j++;
}
j = 0;
while (j < fs)
{
if (frame1[j][0] = -1)
{
fault = 1;
fn = j;
goto l2;
}
j++;
}
ind++;
l2:
if (fault == 1)
{
p++;
frame1[fn][0] = pn[pi];
frame1[fn][1] = p;
cnt++;
}
cout << "\nElement: " << pn[pi];
pi++;
for (z = 0; z < fs; z++)
{
cout << "\t" << frame1[z][0];
}
if (fault == 1)
cout << "\t**Page Fault**";
else
cout << "\t--No Page Fault--";
}
cout << "\nTotal number of page faults: " << cnt;
cout << "\n";
}
void LRU_Execute(string pagestring, int n)
{
pra p;
int j, fault = 0, i, pi, z, fn, ind = 0, ans, ch;
p.getdata(pagestring, n);
//p.lru();
while (ans == 1);
//return 1;
}
I did my cellular automaton in c but now I want to convert it to c++ with using class and object. I am new in c++ that is why I need your help. My program crashes after typing decimal number. I think data is not transfered properly between the functions, but I send few hours on it and I cannot get it. I would be pleased if I could get any advice with finding when my error is. I've got 3 files. One is my main, one is file with functions, and the last one is a header.
Main:
#include <iostream>
#include "cellular.h"
using namespace std;
int main()
{
CA myCA;
myCA.run();
return 0;
}
File with functions:
#include "cellular.h"
#include <cstdio>
CA::CA()
{
int WIDTH = 59;
int numOfRules = 8;
currentState = new int [WIDTH];
nextState = new int[WIDTH];
storeTheRules = new int[numOfRules];
}
CA::~CA()
{
delete [] currentState;
delete [] nextState;
delete [] storeTheRules;
}
void CA::run()
{
int x;
int t;
//enter which cellular you want to print out
printf("Enter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
while(number != -1) {
if(number >= 0 && number <= 255) {
for(x = 0; x < WIDTH; x++) {
currentState[x] = 0;
}
for(x = 0; x < WIDTH; x++) {
t = (int)WIDTH/2;
currentState[t] = 1;
}
// convert decimal number to binary
decimalToBinary(number);
// print binary number
printf("In binary:");
for(x = 0; x < numOfRules; x++)
{
printf("%d", storeTheRules[x]);
}
printf("\n");
//print current state
printCellular();
printf("\n");
// calculate for next generation
calcNextGeneration();
// update array
updateArray();
}
else {
printf("\nWrong number entered! Try again\n");
}
//enter which cellular you want to print out
printf("\nEnter the number of cellular you want to print out 0-255 (-1 to end):\n");
scanf("%d", &number);
}
}
void CA::calcNextGeneration()
{
int i;
int j;
int LENGHT = 27;
for(j = 0; j < LENGHT; j++) {
for (i = 0; i < WIDTH; i++) {
left = currentState[i-1];
middle = currentState[i];
right = currentState[i+1];
nextState[i] = rules(left, middle, right);
}
updateArray();
printCellular();
printf("\n");
}
}
int CA::rules(int left,int middle, int right)
{
if(left == 1 && middle == 1 && right == 1)
return storeTheRules[0];
else if(left == 1 && middle == 1 && right == 0)
return storeTheRules[1];
else if(left == 1 && middle == 0 && right == 1)
return storeTheRules[2];
else if(left == 1 && middle == 0 && right == 0)
return storeTheRules[3];
else if(left == 0 && middle == 1 && right == 1)
return storeTheRules[4];
else if(left == 0 && middle == 1 && right == 0)
return storeTheRules[5];
else if(left == 0 && middle == 0 && right == 1)
return storeTheRules[6];
else if(left == 0 && middle == 0 && right == 0)
return storeTheRules[7];
return 0;
}
void CA::printCellular()
{
int i;
for(i = 0; i < WIDTH; i++) {
if(nextState[i] == 1 || currentState[i] == 1)
printf("#");
else
printf(" ");
}
}
void CA::updateArray()
{
int i;
for(i = 0; i < WIDTH; i++) {
currentState[i] = nextState[i];
}
}
// function to convert decimal number to binary
void CA::decimalToBinary(int n)
{
int k;
int i = 0;
for (numOfRules = 7; numOfRules >= 0; numOfRules--) {
k = n >> numOfRules;
if (k & 1)
storeTheRules[i] = 1;
else
storeTheRules[i] = 0;
i++;
}
printf("\n");
}
Header:
#ifndef CELLULAR_H_INCLUDED
#define CELLULAR_H_INCLUDED
// A cellular automaton class
class CA {
private:
int WIDTH;
int numOfRules;
int *currentState;
int *nextState;
int *storeTheRules;
int number;
int left, middle, right;
public:
// Constructor
CA();
// Destructor
~CA();
// Functions
void run();
int rules(int left, int middle, int right);
void calcNextGeneration();
void printCellular();
void updateArray();
void decimalToBinary(int n);
};
#endif // CELLULAR_H_INCLUDED
I am making my code in CodeBlocks. And.. include cstdio is because I didn't changed my printf's from C code yet.
Thank you for any help.
Regards,
Nel
I didn't read through everything, but a few issues upon first glance:
In your constructor you are creating local variables instead of accessing the class variables you intend to modify.
int WIDTH = 59;
int numOfRules = 8;
Also, just as a personal preference, I wouldn't organize this in such a way that a data entry loop getting input from the user is a part of a class. That could just be personal preference though.