As a homework assignment, I am to implement an adjacency list using an array of pointers to linked lists for each vertex. Each linked list has an element <destination> that states the vertex neighbor of adjacency list vertex.
The adjacency list is undirected and unweighted, so I am treating all weights as 1.
/* Adjacency List Node data structure (edge)
* Linked List data structure for storing linked vertices
*/
struct adjacencyListNode
{
int destination;
struct adjacencyListNode *next;
};
/* Adjacency List Vertex data structure (vertex)
* <AdjacencyList> consists of pointers to <n> adjacencyListVertex
*/
struct adjacencyListVertex
{
struct adjacencyListNode *head;
};
I am trying to perform Dijkstra's Algorithm on the adjacency list to find the minimum path from s to t.
Right now I am implementing the following algorithm:
/* Prints the length and path taken of the shortest path in adjacency list between s and t.
* Uses Dijkstra’s algorithm to compute shortest path.
* S: source vertex
* V: destination vertex
*/
void shortestPath(int s, int t) {
int known[size]; // shortest distance to vertex is know
int cost[size]; // distance from source <s> to each vertex
int path[size]; //path
// Initialization: Set all distances to infinity (represented by -1), since arrays have not been visited and graph is positively weighted
for (int index = 0; index<size; index++) {
cost[index] = INFINITY;
known[index] = 0;
}
// Set distance from source->source to 0
cost[s-1] = 0;
// Starting at s, traverse towards all reachable unvisited verticies, visit it and repeat
while (isFinished(known, size) == false) {
// Select a vertex from list of unvisited nodes which has the smallest cost
int cheapestVertex, cheapestValue = INFINITY+1;
for (int costCheck = 0; costCheck<size; costCheck++) {
if ((known[costCheck] == 0) && (cost[costCheck] < cheapestValue)) {
// We found a cheaper unvisited vertex
// cout << "Cheapest vertex: " << costCheck << endl;
cheapestVertex = costCheck;
cheapestValue = cost[cheapestVertex];
}
// cout << "found? " << cheapestVertex << " " << cheapestValue << endl;
}
// cout << "Cheapest vertex: " << cheapestVertex << endl;
// For each unvisited neighbor of our cheapest (unvisited) vertex
adjacencyListNode* iterator = A[cheapestVertex].head; // iterator is our first neighbor
while (iterator)
{
// Calculate the new cost from the current vertex <cheapestVertex>
if (cost[cheapestVertex]+1 < cost[iterator->destination] && known[iterator->destination] == 0) {
cost[iterator->destination] = cost[cheapestVertex]+1;
}
iterator = iterator->next; // move to next neighbor, repeat
}
// cout << "Cheapest vertex: " << cheapestVertex << " known." << endl;
// Mark the current vertex <cheapestVertex> as visited
known[cheapestVertex] = 1;
// DEBUG: (REMOVE BEFORE SUBMISSION)
for (int i = 0; i<size; i++) {
cout << "Vertex " << i << " : known? " << known[i] << ", cost? " << cost[i] << endl;
}
cout << endl;
if (cost[t-1] != INFINITY) break; // We already know shortest path, end.
}
// We know the shortest path cost to t
cout << "Cost to t: " << cost[t] << endl;
}
bool isFinished(int array[], int arraySize) {
bool finished = true;
for (int iterator=0; iterator < arraySize; iterator++) {
if (array[iterator] == 0) {
// vertex not known, we're not done.
finished = false;
}
}
return finished;
}
I am passing the following input, which just adds the stated related vertices and calls my shortest-path algorithm.
0 1
1 2
1 3
2 4
3 5
5 38
6 7
6 10
8 9
11 12
12 13
12 15
12 21
13 14
14 15
16 17
17 18
18 19
19 20
20 39
21 22
22 23
22 31
23 24
23 32
24 25
24 33
25 26
26 27
27 28
28 29
29 30
31 40
34 35
34 37
35 36
36 37
1
shortest-path
My code traverses from 0->1->2->3->4->5->38 and then repeats 38 infinitely.
Does anyone see where my issue is?
You have a few issues. As this is homework, I won't give you the full answers.
Issue 1: What happens if there are nodes that are unreachable from s? This is what is happening in your example.
Hint: You need to work out when to stop the loop (other than the one you have already). Look at your cheapest selection - how would you determine that there isn't a valid one?
Hint #2 - You current loop won't set a value for cheapestVertex if all remaining vertices have a cost of INFINITE, so you will be using an uninitialized value. Maybe check what the cheapest cost you found was before proceeding.
Issue 2: cost[iterator->destination] = cost[cheapestVertex]+1;
Hint: are you sure this is correct to do on every occasion? What if the node already has a cheaper cost, or has already been visited?
Issue 3: You can stop looking once you have t known. No need to check the whole graph. Note: This is an change that you don't necessarily need as your code will work without it.
Related
I am trying to implement Dijksta's shortest path using a min heap, but I am having issues with the distance field not updating correctly after performing relaxation. I also get segmentation fault when trying some test cases and I am not sure why. On pressing R,the program should read in a graph, and build the edge adjacency list of the graph. The edge adjacency list is an array (indexed by the vertices) of singularly linked lists, where the list according to a node v denotes the outgoing neighbors of node v.This is built using the graphinput.txt and the buildGraph function I outline at the bottom; The input text file is the following where 25 and 50 are the number of vertices and edges respectively:
25 50
1 1 3
1 6 2
1 2 7
1 11 1
6 11 3
11 6 2
7 1 4
11 12 4
2 7 10
7 2 10
16 12 7
21 16 4
21 22 1
22 21 2
3 1 5
18 21 1
18 22 3
22 23 5
12 18 8
18 12 7
7 13 3
12 8 2
2 8 1
2 9 3
4 3 4
5 4 7
10 5 3
4 10 10
14 4 15
15 10 8
10 15 6
10 15 7
8 13 2
8 9 1
9 9 4
13 18 1
23 23 7
23 24 4
23 14 1
24 13 9
14 19 1
19 24 1
15 14 2
14 20 16
14 25 30
20 25 15
24 25 26
23 25 8
25 15 2
17 16 13
On reading F S T 1, the program is to print the length of the shortest path from node s to node t.
On reading F S T 0, the program is to output the shortest path from node s to node t.
If the nodes are not reachable it is to output an error.
Here are the structs I am using where d in ELEMENT is the distance, p is the parent and key is the value. In heap, H is an array of type ELEMENT with index ranging from 0 to capacity
These are my heap structs:
struct ELEMENT{ //declaring the element struct with a key
int key;
int d;
int p;
};
struct HEAP{ //declaring the heap struct with a capacity size and a pointer h
int capacity;
int size;
ELEMENT *h;
};
My graph structs:
struct GRAPH{
int v;
int e;
struct ELEMENT *h;
struct LIST** A;
};
struct LIST{
int neighbor;
int weight;
struct LIST* next;
};
I then use the following heap functions:
ELEMENT deleteMin(GRAPH *g){
ELEMENT trueMin;
if(g->v >=1){ //proceeds only if the heap size is greater than or equal to 1
trueMin = g->h[1]; //initializing element variable for the min that gets deleted
}
if(g->v < 1){ //if the heap is empty print this error
cout << "Error: heap empty" << endl;
}
else{
ELEMENT min = g->h[1];
g->h[1] = g->h[g->v];
g->v--;
minHeapify(g,g->h[1].key);
trueMin = min; //else min is equal to first element, is swapped with the last, size is decreased, and minheapfiy is called
}
return trueMin;
}
void decreaseKey(GRAPH *g, int index, int value){
if(index > g->v || index < 1){ //if the index is greater than the size of the index is less than 1 print error
//cout<< "Error: invalid index" << endl;
return;
}
if(value > g->h[index].d){// if the value trying to be increased is greater than the current index value print error
//cout << "Error: new key is bigger than current key" << endl;
return;
}
else{
g->h[index].d = value; //else set the index equal to the key value and swap the parent until the parent has a less value
while( index > 1 && g->h[parent(index)].d > g->h[index].d){
swap(&g->h[index], &g->h[parent(index)]);
index = parent(index);
}
}
}
void minHeapify(GRAPH *g, int i){ //minHeapify algorithm to maintain min heap property where the parent of any given node is always less than its children
int smallest = 0;
int l = left(i);
int r = right(i);
if(l <= g->v && g->h[l].d < g->h[i].d){ //checking if children exist
smallest = l;//setting the smallest equal to left if the left is smaller
} else{
smallest = i;
}
if(r <= g->v && g->h[r].d < g->h[smallest].d){ //checking if children exist
smallest = r;//setting the smallest equal to right if the right is smaller
}
if(smallest != i){ //if the smallest is not equal to i entered by user then swap and minHeapify function
int temp = g->h[i].d;
int temp1 = g->h[i].key;
int temp2 = g->h[i].p;
g->h[i].key = g->h[smallest].key;
g->h[i].d = g->h[smallest].d;
g->h[i].p = g->h[smallest].p;
g->h[smallest].key = temp;
g->h[smallest].d = temp1;
g->h[smallest].p = temp2;
minHeapify(g, smallest);
}
}
void buildHeap(GRAPH *g){
for(int i = floor(g->v/2); i >= 1; i--){
minHeapify(g, i); //performing the buildHeap operation
}
}
int parent(int i){
return floor(i/2);//parent function to return parent node
}
int left(int i){//left function to return left node
return 2 * i;
}
int right(int i){//right function to return right node
return (2 * i + 1);
}
void swap(ELEMENT *a, ELEMENT *b){ //swaps elements using pointers and a temp variable
ELEMENT temp;
temp = *a;
*a = *b;
*b = temp;
return;
}
For my graph, I use the following functions:
GRAPH* initializeGraph(){ //initializing the graph
GRAPH *g = new GRAPH;
g->v=0;
g->h=nullptr;
g->A=nullptr;
g->e=0;
return g;
}
void initializeSingleSource(GRAPH *g, int s)
{
for (int i = 1; i <= g->v; i++)
{
g->h[i].d = INT_MAX - 1000; //setting all the distances to infinity
g->h[i].p = -1; //setting parent field to nonexistent
}
g->h[s].d = 0; //setting the source distance to 0 to start the algorithm
//g->h = new ELEMENT[g->v + 1];
}
void relax(GRAPH *g, int u, int v, int w)
{
int uindex = 0; //variables to search for the index of u and v
int vindex = 0;
for(int i = 1; i <= g->v; i++){ //searching
if(g->h[i].key == u){
uindex = i;
break;
}
}
for(int i = 1; i <= g->v; i++){ //searching
if(g->h[i].key == v){
vindex = i;
break;
}
}
if (g->h[vindex].d > g->h[uindex].d + w) //performing relaxation on indices
{
g->h[vindex].d = g->h[uindex].d + w;
g->h[vindex].p = u;
decreaseKey(g, g->h[vindex].d, w + g->h[uindex].d); //calling decreasekey to maintain minheap property
}
}
void Dijkstra(GRAPH *g, int s, int t, int flag) //s and t are source and target nodes flag determines what to print
{
g->h = new ELEMENT[g->v + 1];
for (int i = 1; i <= g->v; i++) { //setting i
g->h[i].key = i;
}
initializeSingleSource(g,s); //setting initial fields
std::vector<ELEMENT> S; //vector to hold extracted min elements
buildHeap(g); //calling buildheap on g
//cout << g->h[s].d << endl;
while (g->v > 0)
{
ELEMENT u = deleteMin(g); //extracting min
S.push_back(u);
LIST *temp = g->A[u.key]; //pointer for adjacency list
while(temp){
relax(g, u.key,temp->neighbor,temp->weight); //performing relaxation
cout << "update " << temp->neighbor << " distance to " << g->h[temp->neighbor].d << endl; //for debugging purposes
temp = temp->next;
}
}
for(int i = 0; i < S.size(); i++){
if(S[i].key == t){
if(S[i].d == INT_MAX - 1000){ //if distance is still infinity after relaxation then error
std::cout << "Error: node " << t << " not reachable from " << s << std::endl;
}
else{
if(flag == 1){ //if flag is 1 then output the length of the shortest path
std::cout << "LENGTH: " << S[i].d << std::endl;
}
// if (flag == 0 && s == t){
// cout << "PATH: " << s << endl; //wrote this to get more test cases passing without solving real problem
//}
else if(flag == 0){ //if 0 output the path for shortest distance
vector<int> path;
int temp = t;
while(temp != -1){ //while temp os not -1 loop through vector
for(int i = 0; i < S.size(); i++){
if(S[i].key == temp){
path.insert(path.begin(), temp); //insert path until -1
temp = S[i].p;
break;
}
}
}
std::cout << "PATH: ";
for(int i = 0; i < S.size(); i++){
std::cout << path[i]; //printing path as comma separated list
if(i < path.size() - 1){
std::cout << ", ";
}
}
std::cout << std::endl;
}
}
}
}
delete g->h;
}
void buildGraph(GRAPH *g)
{
//GRAPH *g = new GRAPH;
ifstream myfile("Ginput.txt"); //building the adjacency list
int v1 = 0, e1 = 0;
myfile >> v1 >> e1;
if (v1 == 0 || e1 == 0){
std::cout << "Errorr: unable to open file " << std::endl;
}
g->v = v1;
g->e = e1;
g->h = nullptr;
g->A = new LIST *[v1 + 1];
for (int i = 1; i <= v1; i++)
{
g->A[i] = NULL;
}
int u,v,w;
while (myfile >> u >> v >> w)
{
LIST *temp = new LIST;
temp->neighbor = v;
temp->weight = w;
temp->next = NULL;
if (g->A[u] == NULL)
{
g->A[u] = temp;
}
else
{
temp->next = g->A[u];
g->A[u] = temp;
}
}
myfile.close();
}
And this is an example of the output I get when I print what relax is doing in my while loop of dijkstra function.
R
COMMAND: R
F 1 1 1
COMMAND: F 1 1 1
update 11 distance to 32712
update 2 distance to 32718
update 6 distance to 32713
update 1 distance to 2147482647
update 15 distance to 32713
update 25 distance to 2147482647
update 13 distance to 32720
update 25 distance to 2147482647
update 14 distance to 32712
update 24 distance to 2147482647
update 23 distance to 2147482647
update 23 distance to 2147482647
update 21 distance to 2147482647
update 22 distance to 2147482647
update 16 distance to 32715
update 25 distance to 2147482647
update 24 distance to 2147482647
update 12 distance to 32718
update 22 distance to 2147482647
update 21 distance to 2147482647
update 16 distance to 32715
update 12 distance to 32718
update 14 distance to 32712
update 10 distance to 32719
update 25 distance to 2147482647
update 20 distance to 2147482647
update 19 distance to 2147482647
update 4 distance to 32726
update 18 distance to 2147482647
update 8 distance to 32713
update 18 distance to 2147482647
update 12 distance to 32718
update 6 distance to 32713
update 15 distance to 32713
update 15 distance to 32713
update 5 distance to 32714
update 9 distance to 2147482647
update 9 distance to 2147482647
update 13 distance to 32720
update 13 distance to 32720
update 2 distance to 32718
update 1 distance to 32713
update 11 distance to 32712
update 4 distance to 32726
update 10 distance to 32719
update 3 distance to 2147482647
update 1 distance to 32718
update 9 distance to 2147482647
update 8 distance to 32713
update 7 distance to 2147482647
LENGTH: 0
F 6 11 0
COMMAND: F 6 11 0
update 11 distance to 32714
update 15 distance to 32713
update 25 distance to 2147482647
update 13 distance to 32720
update 25 distance to 2147482647
update 14 distance to 32712
update 24 distance to 2147482647
update 23 distance to 2147482647
update 23 distance to 2147482647
update 21 distance to 2147482647
update 22 distance to 2147482647
update 16 distance to 32715
update 25 distance to 2147482647
update 24 distance to 2147482647
update 12 distance to 32718
update 22 distance to 2147482647
update 21 distance to 2147482647
update 16 distance to 32715
update 12 distance to 32718
update 14 distance to 32712
update 10 distance to 32719
update 25 distance to 2147482647
update 20 distance to 2147482647
update 19 distance to 2147482647
update 4 distance to 32726
update 18 distance to 2147482647
update 8 distance to 32713
update 18 distance to 2147482647
update 12 distance to 32718
update 6 distance to 3
update 15 distance to 32713
update 15 distance to 32713
update 5 distance to 32714
update 9 distance to 2147482647
update 9 distance to 2147482647
update 13 distance to 32720
Segmentation fault (core dumped)
This is the piece of main where I use Dijkstra function:
case 'F':
printf("COMMAND: %c %d %d %d\n",c ,f, i, v);
if (!g) {
std::cout << "Error: graph not initialized" << std::endl;
break;
}
if(f > 25 || f < 1 || i > 25 || i < 1){
if (v != 0 && v != 1){
std::cout << "Error: one or more invalid nodes" << std::endl;
std::cout << "Error: invalid flag value" << std::endl;
break;
}
}
if(f > 25 || f < 1 || i > 25 || i < 1){
std::cout << "Error: one or more invalid nodes" << std::endl;
break;
}
if (v != 0 && v != 1) {
std::cout << "Error: invalid flag value" << std::endl;
break;
}
Dijkstra(g,f,i,v);
buildGraph(g); //called to avoid errors when extractmin is called to decrease graph size
break;
If anyone could please tell me what I am doing incorrectly, I would greatly appreciate it.
I am trying to navigate through a ghetto map. I'm inputting my nodes from a .txt that has values like this:
3 -1
2 3 -1
1 -1
0 1 4 6 -1
3 5 7 -1
4 7 8 -1
3 7 -1
4 5 6 8 -1
5 7 -1
10 -1
9 -1
So:
node 0 will be connected to node 3
node 1 will be connected to nodes 2 and 3
node 2 will be connected to node 1
and so on... the '-1' is just to terminate the line
Currently, I am storing them in an array of size 11, where I've just used getline() to pull each line number into the matching array cell; this is to output to the screen. I will also put them into a 2d array where each value had its own cell. I'm going to ask the user for a starting node, and ending node, then I'll use a recursive function to calculate a path between the two (if there is one), and output how many nodes are along that path. I'm not even interested in the optimal path, any will do.
How would I go about this recursively?
The unfinished code thus far:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
const int ARRAY_SIZE = 11;
void toString(string network[ARRAY_SIZE]);
int numNodes(string network[], int start, int end);
int main()
{
int start;
int end;
// inputting network into array
string network[ARRAY_SIZE];
ifstream in;
in.open("network.txt");
if (in.is_open())
{
while (!in.eof())
{
for (int i = 0; i < ARRAY_SIZE; i++)
{
getline(in, network[i]);
}
}
}
in.close();
//start of user prompts
cout << "Welcome. " << endl << "Here is the network " << endl << endl;
toString(network);
// the loop for start val
do
{
cout << "Please enter a a starting node number (0-10), enter '-1' to quit" << endl;
cin >> start;
if (start == -1)
return 0;
} while (start < 0 && start > 10);
toString(network);
//loop for end value
do
{
cout << "Please enter an ending node number (0-10), enter '-1' to quit" << endl;
cin >> end;
if (start == -1)
return 0;
} while (end < 0 && end > 10);
//recursive stuffs
return 0;
}
int numNodes(string network[], int start, int end)
{
//unfinished function
int num;
//base case
if (start == end)
{
return 1;
}
//recursion
else
{
}
return num;
}
void toString(string network[ARRAY_SIZE])
{
cout << endl;
for (int i = 0; i < ARRAY_SIZE; i++)
{
cout << network[i] << endl;
}
cout << endl;
}
Not sure what you mean by 'ghetto map', I'm guessing you its just a joke.
What you are actually talking about is a concept in Computer Science/Discrete Mathematics called a Graph. There are many types of graphs, graphs that have only positive weights graphs that contain negative weights, graphs in which all paths are bidirectional, graphs which paths are uni directional graphs where edges must all be connected, graphs were edges have a certain wight, capacity and/or some other feature etc...
In this case what I think what you are dealing with is an unweighted (no weights assigned to edges) directed (a connection from A to B does not imply a connection from B to A) graph (unweighted directed graph) and where the graph may additional be unconnected or not.
You are additionally using a type of Adjacency List in order to represent the connections between graph nodes.
There are many algorithms to traverse a graph (such as Dijkstras for path finding or Uniform Cost Search), however most if not all these algorithms come from two basic search algorithms called Depth First Search and Breadth First Search
Depth first search is exactly what the name implies. If you have some structure to represent your graph (say, your adjacency list) you will continually search the right or left most node to the deepest point until you either hit your goal or a dead end. This might look like the following (note this is Python):
def DepthFirstSearch(adjacencylist, start, end):
traversallist = []
traversallist.push(start)
for edge in adjacencylist[start]:
if edge.connectsTo(end):
traversalstack.push(end)
return traversallist
else:
resursivelist = DepthFirstSearch(adjacencylist, edge.endNode(), end)
if resursive_list != []:
return traversallist.extend(recursivelist)
return []
if it returns an empty list ([]) there was no connection. If it didn't there was a connection and returned the first path found.
Breadth frist search is exaclty what its name implies. In the same scenario as before, instead of searching for the deepest node you search along each connecting edge first before going deeper. This might look like the following:
#note that queue starts with the start element
def BreadthFirstSearch(adjacencylist, queue, end):
start = queue.pop()
traversallist = []
traversallist.push(start)
for edge in adjacencylist[start]:
if edge.connectsTo(end):
traversalstack.push(end)
return traversallist
queue.push(adjacencylist[start])
if not queue.empty():
return traversallist.extend(BreadthFirstSearch(adjacencylist, queue, end))
else:
return []
Both of these methods, however, will run infinently in the case where you have a loop during traversal. To avoid this, you can setup a list (or for bettern runtime complexity, a hashtable) to see if you've already traversed something.
def DepthFirstSearch(adjacencylist, start, end, closedset):
...
if start not in closedset:
...
else:
return []
def BreadthFirstSearch(adjacencylist, queue, end, closedset):
...
if start not in closedset:
...
else:
return []
This should give you enough information to implement a graph path finder that will return a path (of which you can simply return the size of if you only need the number of nodes) in c++.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So first, we start with an array of 50. The range of the values within the array can be 1-100, not repeating. Then we display the highest value of that random array. Then we display the lowest value in the array. Then comes the sorting, which would be easy using the standard library functions in the <algorithm> header, but since it's not allowed, we need to find another way around it. Then sort from high to low.
So, to display this easily... First we start with an array[50] with random numbers between 1-100
72 29 11 41 31 27 21 46 43 40 17 45 30 32 25 15 19 88 22 24 51 34 99 23 26 37 1 4 2 9 33 44 12 39 38 3 47 48 5 42 49 18 54 55 87 16 28 20 50 9
Now we display the highest number
99
Then the lowest
1
The we sort them
1 2 3 4 5 9 9 11 12 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 54 55 72 87 88 99
Then reverse sort them
99 88 87 72 55 54 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 12 11 9 9 5 4 3 2 1
So.. how would I go about doing this without algorithms?
The usual way to do this is by using loops.
For example, to traverse an array, printing every element, we could use a loop like:
for (int i=0; i<50; i++) {
std::cout << array[i] << std::endl;
}
All of the problems you mention, except sorting, can be done using a simple loop like the one above. You'll have to do your own bookkeeping in order to solve the problems, but it shouldn't be too difficult.
As for sorting, that's a more challenging problem. You might start with the wikipedia article to see how that is handled. You probably want to try implementing selection sort.
You can use bitset sort since the range of values of the array is limited to 1-100, and there is no repetition you can have a bitset array of 100 ints where each index specifies can be a 0 (that number isn't in the array) or a 1 (the number is in the array). For example the array [1, 5, 3] can be represented by the bitset array [1, 0, 1, 0, 1].
pseudo code:
MAX_SIZE = 100
bitset = new int[MAX_SIZE]
smallest = biggest = -1
for each value in array {
smallest = value if value < smallest
biggest = value if value > biggest
bitset[value-1] = 1
}
sorted = (i for i in 0..bitset.length - 1 if bitset[i] == 1)
reverse_sorted = (sorted[i] for i in sorted.length-1..0)
Not very professional but works
int array[50], used[50], sortedArray[50], buildSort = 1, genNum, max = 0, min = 101;
bool x;
srand(time(0));
//Array Generator
for(int i = 0; i < 50; i++){
do{
genNum = (1+rand()%100);
x = false;
for(int j =0; j < 50; j++){
if(genNum == used[j]){
x = true;
}
}
}while(x == true);
used[i] = genNum;
array[i] = genNum;
}
cout << "Numbers: ";
for(int d = 0; d < 50; d++){
cout << array[d] << " ";
}
cout << endl << endl;
//Max and Min finder
for(int m = 0; m < 50; m++){
if(array[m] > max){
max = array[m];
}
if(array[m] < min){
min = array[m];
}
}
cout << "Max is: " << max << endl;
cout << "Min is: " << min << endl << endl;
//Sorting
sortedArray[0] = min;
for(int v = min+1; v <= max; v++){
for(int r = 0; r < 50; r++){
if(array[r] == v){
sortedArray[buildSort] = array[r];
buildSort++;
}
}
}
cout << "Sorted: ";
for(int k = 0; k < 50; k++){
cout << sortedArray[k] << " ";
}
cout << endl << endl;
cout << "Reverse sorting: ";
for(int l = 49; l >=0; l--){
cout << sortedArray[l] << " ";
}
Well, I have not checked this code and I'm sure it has some errors in it, but hopefully this will at least give you some ideas and a good base to go off of:
/******************
*
* Your array should have 51 spots.
* The last element should be 0.
*
******************/
uint8_t findMax(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t highest = 0;
for(; *arrayToSearch; arrayToSearch++){
highest = (*arrayToSearch > highest) ? *arrayToSearch : highest;
}
return highest;
}
uint8_t findMin(uint8_t *arrayToSearch){
// Your array should end in a sentinel value of 0
uint8_t lowest = 101;
for(; *arrayToSearch; arrayToSearch++){
lowest = (*arrayToSearch < lowest) ? *arrayToSearch : lowest;
}
return lowest;
}
void sortAscending(uint8_t *arrayToSearch){
// sort from low to high
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll the sorted values to the array to search */
int i;
for(i=0; i < count; i++){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/*
* We can actually write sortDescending the same way and just modify
* the last loop to put them in reverse order
*/
void sortDescending(uint8_t *arrayToSearch){
// sort from low to high and then order as high to low
// get count of array (According to your question, it should be 50, but we'll verify)
unsigned short count = 0;
uint8_t *countingPoint;
countingPoint = arrayToSeach; // make countingPoint point to the first element
while(*countingPoint){
count++;
countingPoint++;
}
// now we'll create a second array
uint8_t sortedArray[count];
// now let's begin sorting.
unsigned long int totalIterations = 0;
while(totalIterations < count){
uint8_t currentSmallest = 101; // value which will not ever exist.
signed long int smallestIndex = -1;
unsigned short offset = 0;
uint8_t *startOfArray;
startOfArray = arrayToSearch;
for(; *startOfArray; *startOfArray++, offset++){
if(currentSmallest > *startOfArray){
smallestIndex = offset;
currentSmallest = *startOfArray;
}
} /* end for */
sortedArray[totalIterations] = currentSmallest;
*(smallestIndex + arrayToSearch) = 101; /* set the value above 100 so it will be
skipped in the next for loop */
totalIterations++;
} /* end while */
/* now we'll copy the values to the arrayToSearch in reverse order */
int i;
for(i=(count-1); i >= 0; i--){
*(i+arrayToSearch) = sortedArray[i];
}
// and we're done.
}
/* calling these */
int main(){
uint8_t yourArray[51];
// ... your code to populate this array
yourArray[50] = 0; // set the last spot to 0.
uint8_t highest = findMax(yourArray);
uint8_t lowest = findMin(yourArray);
// now make yourArray sorted by lowest to highest
sortAscending(yourArray);
// ... Whatever you need to do with it in ascending order.
// now make it sorted by highest to lowest
sortDescending(yourArray);
// ... Whatever you need to do with it in descending order.
return 0;
}
I'm a C-programmer so this is a rather C-style answer.
Some additional information that might be helpful can be found at:
http://www.sanfoundry.com/c-program-sort-array-ascending-order/
http://www.programmingsimplified.com/c/source-code/c-program-bubble-sort
http://en.wikipedia.org/wiki/Sorting_algorithm
The Wikipedia page (last link) might seem a little overwhelming, but there is a lot of great content on it.
I hope this will be of some help to you. Again, I'm not sure if the code I included will work properly. It's merely meant to convey the general idea.
I've hit a wall in attempting to understand Dijkstra's algorithm. The algorithm, in short, finds the shortest distances between A and B given distances between the two.
I will post my version of the algorithm (I haven't had much success looking online thus far), followed by the distances between nodes.
void GraphM::findShortestPath()
{
for (int i = 1; i <= nodeCount; i++) // From Node i...
{
for (int v = 1; v <= nodeCount; v++) // ...through Node v...
{
for (int w = 1; w <= nodeCount; w++) // ...to Node w
{
if (!T[i][w].visited || !T[i][v].visited)
{
T[i][w].dist = min(T[i][w].dist, T[i][v].dist + C[v][w]);
T[i][v].visited = true;
T[i][w].visited = true;
}
}
}
}
cout << "1 to 2 is " << T[1][2].dist << endl;
}
This outputs the following:
1 to 2 is 48
...when it should be
1 to 2 is 40
The values I'm working with are as follows:
1 2 50
1 3 20
1 5 30
2 4 10
3 2 20
3 4 40
5 2 20
5 4 25
...where, in each line, the first token is the first node, the second token is the second node, and the third token is the distance between those nodes (in the algorithm's case, these tokens would be i, v, and T[i][v].dist). In the algorithm, nodeCount is the number of nodes in the grid (5), and w is a node that we are looking for the distance to, from i. C[v][w] returns the original distance between v and w. So, if v was 5 and w was 2, C[v][w] would return 20. This is constant, whereas T[v][w].dist (for instance) can be changed.
Any nonexistant node relationships such as C[5][3] or T[1][4].dist (at least at the outset) return INT_MAX, which is equivalent to infinity.
Also, for anyone wondering; yes, this is a homework assignment. Unfortunately, my professor has necessitated some specific details (such as using a struct T), and she never went into much detail on how to write Dijkstra's algorithm into code, other than a somewhat vague outline. I am simply asking if someone can tell me what I am doing wrong and how to fix it, if possible.
Any help is very much appreciated and would save me a lot of time from banging my head against a wall.
This is not Dijkstra's algorithm. What you are trying to implement is Floyd-Warshall algorithm. This would find the minimum distance for all pair of vertices.
http://en.wikipedia.org/wiki/Floyd–Warshall_algorithm
Note that the first loop loops through the transfer node. With this implementation you don't need to remember which edge you already visited.
void GraphM::findShortestPath()
{
// Initialize T[i][j] to C[i][j] or MAX_INT here
for (int k = 1; k <= nodeCount; k++) // Through Node k...
{
for (int u = 1; u <= nodeCount; u++) // ...From Node u...
{
for (int v = 1; v <= nodeCount; u++) // ...to Node v
{
// if going through k provides a cheaper path, update T[u][v]
T[u][v] = min(T[u][v], T[u][k] + T[k][v]);
}
}
}
cout << "1 to 2 is " << T[1][2]<< endl;
}
Given a n*n matrix and a value k, how do we find all the neighbors for each element?
for example: in a 4*4 matrix, with k=2
say matrix is :
[ 1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16]
where these values are the indexes of the location, the neighbors for 1 are 1,2,3,5,6,9 . The values 3,6 and 9 come only because k =2 and wouldnt be there if k was = 1.
similarly the neighbors of 6 will be 1 2 3 5 6 7 8 9 10 11 and 14
Can you please help me to write a c code to implement this in c++.
It is the problem of von Neumann neighborhood, please can some one implement it in c++. Thanks
Your neighbors will form a diamond pattern around your target element. The points of the diamond will be k hops away from the target element. So the top will be k rows up, the left will be k columns over, etc. The diamond expands uniformly as you go from level to level. If you start at the top point and go one row down (closer to the target node) then you go out 1 to each side. It's symmetric in the other directions. In other words, the difference in x coordinates between a neighbor and the target node plus the difference in y will be <= k.
So just make two nested for loops that iterate over this diamond. Outer loop iterates over the rows, inner loop over the columns. Start at the top then expand the diamond by 1 at each outer loop iteration until you reach the same row as the target element, then contract until you reach the bottom point.
Obviously you'll need to test boundary conditions for going outside the matrix.
This should do the trick for k=1. Make minor changes to make it work for all k
int width = 4;
int height = 4;
int k = 1;
int value = 2;
bool hasRight = (value % width != 0);
bool hasLeft = (value % width != 1);
bool hasTop = (value > 4);
bool hasBottom = (value < (height * width - width));
cout << value; // Always itself
if(hasRight == true) {
cout << value+1 << " "; // Right
if(hasTop == true) {
cout << value-width << " " << value-width+1 << " "; // Top and Top-right
}
if(hasBottom == true) {
cout << value+width << " " << value+width+1; // Bottom and Bottom-right
}
}
if(hasLeft == true) {
cout << value-1 << " "; // Left
if(hasTop == true) {
cout << value-width-1 << " "; // Top-left
}
if(hasBottom == true) {
cout << value+width-1 << " "; // Bottom-left
}
}