Dijkstra - Shortest Path Print - c++

I have a little problem with dijkstra print path, it's working on small graph size like 10-20 etc. On 100 there is problem, because printing loop going to infinity, when I've tried recurrence method, VS is showing me exepction throw, stack overflow (same problem like up ^). Do u know guys how to repair it ? There is my code.
#include <stdio.h>
#include <iostream>
#include <limits.h>
#include <conio.h>
using namespace std;
struct graphNode {
int weight;
int v;
graphNode *next;
};
class Graph {
public:
graphNode *head, *tail;
int size, vIndex;
int currentWeight;
char type;
void addNode(int v_temp, int v_weight) {
graphNode *temp = new graphNode;
temp->next = nullptr;
if (head == nullptr) {
temp->v = v_temp;
temp->weight = v_weight;
head = temp;
}
else {
tail->next = temp;
temp->v = v_temp;
temp->weight = v_weight;
}
size++;
tail = temp;
}
// GET SET METHODS
char returnType() {
return type;
}
int returnCurrentWeight() {
return currentWeight;
}
void setCurrentWeight(int weight) {
currentWeight = weight;
}
void setVIndex(int temp) {
vIndex = temp;
}
void setType(char type_temp) {
type = type_temp;
}
// Constructor
Graph() {
head = nullptr;
tail = nullptr;
vIndex = 0;
size = 0;
currentWeight = 0;
}
};
struct heapNode {
int v;
int distance;
};
class Heap {
private:
Graph *graphArray;
heapNode **heapArray;
heapNode *root;
int vNumber, size;
int *position, *parent;
public:
heapNode *addEdge(int temp_v, int temp_distance) {
heapNode *temp = new heapNode;
temp->v = temp_v;
temp->distance = temp_distance;
return temp;
}
graphNode *returnVertexHead(int i) {
return graphArray[i].head;
}
char returnType(int i) {
return graphArray[i].returnType();
}
int *returnParent() {
return parent;
}
int returnWeight(int i) {
return graphArray[i].returnCurrentWeight();
}
void setWeight(int i, int weight) {
graphArray[i].setCurrentWeight(weight);
}
bool isInHeap(int temp_v) {
if (position[temp_v] < vNumber) return true;
return false;
}
bool isEmpty(int vNumber) {
if (vNumber == 0) return true;
return false;
}
void decrestDistans(int temp_v, int temp_distance) {
int index = position[temp_v];
heapNode *temp;
heapArray[index]->distance = temp_distance;
while (index && (heapArray[index]->distance < heapArray[(index - 1) / 2]->distance)) {
position[heapArray[index]->v] = (index - 1) / 2;
position[heapArray[(index - 1) / 2]->v] = index;
temp = heapArray[index];
heapArray[index] = heapArray[(index - 1) / 2];
heapArray[(index - 1) / 2] = temp;
index = (index - 1) / 2;
}
}
heapNode *removeMin() {
if (vNumber == 0) return nullptr;
root = heapArray[0];
heapArray[0] = heapArray[vNumber - 1];
position[root->v] = vNumber - 1;
position[heapArray[vNumber - 1]->v] = 0;
--vNumber;
repairHeapDown(0);
return root;
}
void repairHeapDown(int index) {
heapNode *temp;
int parentIndex = index;
int left = index * 2 + 1;
int right = index * 2 + 2;
if (left <= vNumber && heapArray[parentIndex]->distance > heapArray[left]->distance) parentIndex = left;
if (right <= vNumber && heapArray[parentIndex]->distance > heapArray[right]->distance) parentIndex = right;
if (index != parentIndex) {
position[heapArray[parentIndex]->v] = index;
position[heapArray[index]->v] = parentIndex;
temp = heapArray[index];
heapArray[index] = heapArray[parentIndex];
heapArray[parentIndex] = temp;
repairHeapDown(index);
}
}
int dijkstra(int start, int target) {
int *distance = new int[vNumber];
int i, v, weight;
graphNode *current_graph;
heapNode *current_heap;
for (int i = 0; i < vNumber; i++)
{
distance[i] = INT_MAX;
heapArray[i] = addEdge(i, distance[i]);
position[i] = i;
parent[i] = 0;
}
parent[start] = -1;
heapArray[start] = addEdge(start, distance[start]);
position[start] = start;
distance[start] = 0;
decrestDistans(start, distance[start]);
while (!isEmpty(vNumber)) {
current_heap = removeMin();
i = current_heap->v;
if (i == target) {
int temp = 2 * distance[target];
parent[v] = i;
delete[] position;
delete[] distance;
delete[] heapArray;
return temp;
}
current_graph = returnVertexHead(i);
while (current_graph != nullptr) {
v = current_graph->v;
weight = current_graph->weight + returnWeight(i) + distance[i];
if (weight < distance[v]) {
distance[v] = weight;
decrestDistans(v, distance[v]);
parent[v] = i;
}
current_graph = current_graph->next;
}
}
return 0;
}
Heap(Graph *table, int temp_vNumber) {
vNumber = temp_vNumber;
size = temp_vNumber;
root = nullptr;
heapArray = new heapNode*[size];
position = new int[size];
parent = new int[size];
graphArray = table;
}
~Heap() {
delete[] parent;
}
};
void printPath(int *parent, int start, int target)
{
int current = target;
while (current != start) {
cout << current << " ";
current = parent[current];
}
cout << current << " ";
}
int main() {
int n, time_knight, patch_number, temp_v, temp_weight, i,
home_index, gral_index, ni_index, ni_weight, krzak_index;
char type;
gral_index = home_index = ni_index = krzak_index = 0;
i = 0;
cin >> n >> time_knight;
Graph *table = new Graph[n];
while (1) {
cin >> type;
table[i].setType(type);
if (type == '5') gral_index = i;
if (type == '4') home_index = i;
if (type == '3') ni_index = i;
if (type == '2') table[i].setCurrentWeight(time_knight);
if (type == '1') krzak_index = i;
cin >> patch_number;
for (int j = 0; j < patch_number; j++)
{
cin >> temp_v >> temp_weight;
table[i].setVIndex(i);
table[i].addNode(temp_v, temp_weight);
}
i++;
if (i == n) break;
}
Heap *object = new Heap(table, n);
Heap *object2 = new Heap(table, n);
ni_weight = object->dijkstra(ni_index, krzak_index);
table[ni_index].setCurrentWeight(ni_weight);
cout << endl << endl << endl;
printPath(object->returnParent(), ni_index, krzak_index);
cout << endl << endl << endl;
object2->dijkstra(home_index, gral_index);
printPath(object2->returnParent(), home_index, gral_index);
_getch();
return 0;
}

Related

Having trouble printing a chained Hashtable c++

#include <iostream>
#include <list>
using namespace std;
const int TABLESIZE = 3;
class HashTable
{
public:
string k;
int v;
HashTable* next;
HashTable(string k, int v)
{
this->k = k;
this->v = v;
next = NULL;
}
};
class HashMapTable
{
private:
HashTable **t;
public:
HashMapTable()
{
t = new HashTable * [TABLESIZE];
for (int i = 0; i < TABLESIZE; i++)
{
t[i] = NULL;
}
}
int HashFunction(int v)
{
return v % TABLESIZE;
}
void Insert(string k, int v)
{
int hV = HashFunction(v);
HashTable* p = NULL;
HashTable* en = t[hV];
while (en!= NULL)
{
p = en;
en = en->next;
}
if (en == NULL)
{
en = new HashTable(k, v);
if (p == NULL)
{
t[hV] = en;
} else
{
p->next = en;
}
} else
{
en->v = v;
}
}
void PrintTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if(t[i] != NULL)
{
cout << t[i]->k << " " << t[i]->v << endl;
}
}
}
~HashMapTable()
{
for (int i = 0; i < TABLESIZE; i++)
{
if (t[i] != NULL)
delete t[i];
delete[] t;
}
}
};
int main()
{
HashMapTable HT;
cout << "entering the pairs now" << endl;
HT.Insert("Boramir", 25);
HT.Insert("Legolas", 101);
HT.Insert("Gandalf", 49);
cout << "printing the pairs now" << endl;
HT.PrintTable();
}
My issue is that not all the key value pairs in the table are being printed depending on the table size. If it's 3 (the desired amount) only 2 print, but if it's at least 7, they all print? I'm not sure what piece of my code is causing this to happen. Also, if there are multiple pairs in one bucket, the second/third/etc pair doesn't print and I'm not sure why. Thanks for any help.

why i'm getting zero instead of 1?

This is a program of searching a number from linked list using recursion.
#include <iostream>
using namespace std;
class node {
public:
int data;
node *next;
void create(int *,int);
int max(node*,int);
};
node *first;
void node::create(int a[],int n) {
first = new node;
first->data = a[0];
first->next = NULL;
node *last = first;
for (int i = 1; i < n; i++) {
node *t = new node;
t->data = a[i];
t->next = NULL;
last->next = t;
last = t;
}
}
int node::max(node *l, int p) {
if (l->data == p) {
return 1;
}
if (l == 0)
return 0;
else {
max(l->next, p);
return 0;
}
}
int main() {
int a[5] = {1,2,3,4,5};
node m;
m.create(a,5);
cout << m.max(first, 3);
return 0;
}
Hunch. Instead of this:
else {
max(l->next, p);
return 0;
}
This:
else {
return max(l->next, p);
}
Or better yet, let's fix the whole max function to check for null before dereferencing l as well.
int node::max(node *l, int p) {
int result = 0;
if (l != nullptr) {
if (l->data == p) {
result = 1;
}
else {
result = max(l->next, p);
}
}
return result;
}

bigraph match with unordered_map

for the bigraph maximum matching algorithm, I used 2 hash table(unordered_map)to solve it, but when I compiling my code, IDE told me C2100, I even don't know where my code is false, it just happened in the "xhash" document, and I think this problem is associated with iterator. Anyway, please help me to figure out this question, Thanks !
#include<iostream>
#include<queue>
#include<unordered_map>
#include<vector>
using namespace std;
struct Edge
{
int to;
int go;
int length;
Edge* next;
int ID;
};
struct Dot
{
int data;
Edge* first;
};
class Web
{
public:
Web(int num);
~Web();
void Insert(int i, int j, int w);
void DFS(int s, int* visited,queue<int>&);
void BFS(int s, int* visited);
void show()
{
for (int i = 0; i<n; i++)
{
Edge* p = D[i].first;
if (p != NULL)
{
cout << p->length << " ";
p = p->next;
}
}
}
void MostMatch();
private:
int e;
int n;
Dot* D;
vector<Edge*> E;
};
Web::Web(int num)
{
e = 0;
n = num;
D = new Dot[num];
for (int i = 0; i<num; i++)
{
D[i].first = NULL;
D[i].data = 0;
}
}
Web::~Web()
{
delete[] D;
}
void Web::Insert(int i, int j, int w)
{
Edge* p = D[i].first;
int count = 0;
if (D[i].first == NULL)
{
D[i].first = new Edge;
D[i].first->next = NULL;
D[i].first->length = w;
D[i].first->to = j;
D[i].first->go = i;
D[i].first->ID = count++;
E.push_back(D[i].first);
}
else
{
while (p->next != NULL)
p = p->next;
Edge* q = new Edge;
p->next = q;
q->next = NULL;
q->length = w;
q->go = i;
q->to = j;
q->ID = count++;
E.push_back(q);
}
p = D[j].first;
if (D[j].first == NULL)
{
D[j].first = new Edge;
D[j].first->next = NULL;
D[j].first->length = w;
D[j].first->to = i;
D[j].first->ID = count;
e++;
}
else
{
while (p->next != NULL)
p = p->next;
Edge* q = new Edge;
p->next = q;
q->next = NULL;
q->length = w;
q->to = i;
q->ID = count;
e++;
}
}
void Web::MostMatch()
{
cout << "make sure it is a biggraph, press Q to quit." << endl;
char ch;
cin >> ch;
if (ch == 'Q')
{}
else
{
unordered_map<int, int> mape;
unordered_map<int, int> mapd;
int count = 0;
for (int i = 0; i < n; i++)
{
Edge* p;
if (D[i].first)
{
p = D[i].first;
if (mapd.find(i) == mapd.end())
{
while (p)
{
if (mapd.find(p->to) == mapd.end())
{
mapd.insert(i,count++);
mapd.insert(p->to, count++);
mape.insert(p->ID, i);
break;
}
}
}
}
}
unordered_map<int, int>::iterator iter = mape.begin();
while (iter != mape.end())
{
Edge* p = D[E[iter->first]->go].first, *q = D[E[iter->first]->to].first;
while (p)
{
if (mapd.find(p->to) == mapd.end())
{
while (q)
{
if (mapd.find(q->to) == mapd.end())
{
mapd.insert(p->to, count++);
mapd.insert(q->to, count++);
mape.insert(p->ID, count++);
mape.insert(q->ID, count++);
mape.erase(iter->first);
break;
}
}
break;
}
}
iter++;
}
for (iter = mape.begin(); iter != mape.end(); iter++)
{
cout << "v" << E[iter->first]->go << " to v" << E[iter->first]->to << " ID: " << E[iter->first]->ID << endl;
}
}
}
int main()
{
Web w1(8);
w1.Insert(0, 3, 1);
w1.Insert(1, 4, 1);
w1.Insert(1, 5, 1);
w1.Insert(2, 5, 1);
w1.Insert(2, 6, 1);
w1.Insert(2, 7, 1);
w1.Insert(3, 7, 1);
w1.MostMatch();
return 0;
}
I even don't know where my code is false
This is a good reason to minimize your code: https://stackoverflow.com/help/mcve
If your compiler doesn't tell you the error message/line (and, I think, it actually does), try a different one, there is a high chance they are compatible. This one: https://www.onlinegdb.com/online_c++_compiler tells me that lines
mapd.insert(i,count++);
and similar are wrong. Replacing them in the following way compiles:
mapd[i] = count++;

Having trouble creating an array of doubly linked list

I have two problems where I'm having a hard time to understand.
1) I'm having a hard time to understand how to pass my L1 doublyLinkedList into an array so that I can save each list of numbers my txt file reads
2) If I have an uneven negative number my break_into_nodes() method is reading an error as stoi is creating 1 node for a negative sign, how would I create an if statement to continue to breaking it into a node
#include "stdafx.h"
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <cstdlib>
#include "ArgumentManager.h"
using namespace std;
struct Node
{
long long value;
Node *next, *prev;
Node(long long y)
{
value = y;
next = prev = NULL;
}
};
class doubleLinkedList
{
Node *back;
public:
Node *front;
doubleLinkedList() { front = NULL; back = NULL; }
~doubleLinkedList() { destroyList(); }
doubleLinkedList(const string& num, int digitsPerNode) {
appendNodeFront(stoi(num, 0, 10));
}
void appendNodeFront(long int x);
void dispNodesForward(int digits);
void destroyList();
void clean();
};
void doubleLinkedList::clean()
{
destroyList();
}
void doubleLinkedList::appendNodeFront(long int x)
{
Node *n = new Node(x);
if (front == NULL)
{
front = n;
//back = n;
}
else
{
front->prev = n;
n->next = front;
front = n;
}
}
void doubleLinkedList::dispNodesForward(int digits)
{
Node *temp = front;
int temp_val;
if (temp != NULL)
{
/* First node does not get Zero padding */
temp_val = (int)temp->value;
printf("%d", temp_val);
temp = temp->next;
while (temp != NULL)
{
temp_val = (int)temp->value;
printf("%0*d", digits, temp_val);
temp = temp->next;
}
}
}
void doubleLinkedList::destroyList()
{
Node *T = back;
while (T != NULL)
{
Node *T2 = T;
T = T->prev;
delete T2;
}
front = NULL;
back = NULL;
}
void break_into_nodes(doubleLinkedList *list, string number, int digits) {
string node_value;
int num_index, num_iterations;
int i, j;
num_index = number.length();
if (num_index < digits)
{
node_value = number;
list->appendNodeFront(stoi(node_value));
}
else {
/* adjust for incomplete nodes */
if ((number.length() % digits) == 0)
num_iterations = (number.length() / digits);
else
num_iterations = (number.length() / digits) + 1;
for (j = 0; j < num_iterations; j++) {
node_value.clear();
for (i = 0; i < digits; i++) {
num_index--;
if (num_index < 0)
break;
node_value = node_value.insert(0, number.substr(num_index, 1));
}
list->appendNodeFront(stoi(node_value));
}
}
}
// Driver program
int main(int argc, char* argv[]) {
doubleLinkedList l1;
if (argc < 2) {
cerr << "Usage: infinitearithmetic \"input=xyz.txt;digitsPerNode= <number>\"\n";
}
ArgumentManager am(argc, argv);
string filename = am.get("input");
/* Digits per Node ar from 1 to 8 */
int digitsPerNode = stoi(am.get("digitsPerNode"));
ifstream ifs(filename.c_str());
string line;
string num1;
int i = 0;
while (!ifs.eof())
{
getline(ifs, line);
//cout << "" << line << endl;
num1 = line;
break_into_nodes(&l1, num1, digitsPerNode);
l1.dispNodesForward(digitsPerNode);
cout << endl;
l1.clean();
i++;
}
return 0;
}

BFS for graphs using link list, c++

I tried to implement BFS for graphs using link list but i have some issues with it, using a queue it only displays the nodes of that origin and not after it. The answer should be 2031 but i only get 203.
The code is below:
#include <iostream>
#include <cmath>
#include <vector>
#include <stdlib.h>
#include <queue>
using namespace std;
class linkListNode
{
public:
linkListNode *next;
int destination;
bool visited;
linkListNode()
{
next = NULL;
destination =0;
visited=false;
}
};
class linkList
{
public:
linkListNode *head;
linkList()
{
head = NULL;
}
// append type insert
void insert(int value)
{
linkListNode *temp2 = new linkListNode;
temp2->destination = value;
temp2->next = NULL;
linkListNode *nodePtr = new linkListNode;
if (head == NULL)
{
head = temp2;
temp2->next = NULL;
}
else
{
nodePtr = head;
while (nodePtr->next)
{
nodePtr = nodePtr->next;
}
nodePtr->next = temp2;
}
}
void display()
{
linkListNode *temp = new linkListNode;
temp = head;
while (temp)
{
cout << temp->destination << " --> ";
temp = temp->next;
}
cout << endl;
}
int size()
{
linkListNode *temp = head;
int sizer = 0;
while (temp)
{
sizer++;
temp = temp->next;
}
return sizer;
}
};
class edge
{
public:
int origin;
linkList final;
bool visited;
edge()
{
//origin = NULL;
//cost=0;
visited=false;
}
};
class graph
{
private:
vector <edge> vectorOfEdges;
int vertices;
public:
graph(int v)
{
vertices = v;
vectorOfEdges.clear();
}
void addRoute(int ori, int dest)
{
int counter = 0;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin== ori)
{
counter = 1; // means element was present in the list
e.final.insert(dest);
}
vectorOfEdges[i] = e;
}
if (counter == 0) // when counter is set to zero, this means that the element was not found in the vector and needs to be pushed
{
edge e;
e.origin = ori;
e.final.insert(dest);
vectorOfEdges.push_back(e);
}
}
void printGraph()
{
edge e;
for (int i = 0; i<vectorOfEdges.size(); i++)
{
e = vectorOfEdges[i];
cout << e.origin << ":- ";
e.final.display();
cout << endl;
}
}
int sizeOfEdge(edge e)
{
int x = e.final.size() + 1;
return x;
}
int max(int one, int two)
{
if (one > two)
{
return one;
}
else
{
return two;
}
}
void BFS(int start)
{
edge e;
queue <int> q;
int save_index=0;
for (int i=0;i<vectorOfEdges.size();i++)
{
e=vectorOfEdges[i];
if (e.origin == start)
{
save_index=i;
q.push(e.origin);
e.visited=true;
break;
}
}
while (!q.empty())
{
int x=q.front();
cout << x << " " ;
q.pop();
linkListNode *l = e.final.head;
while (l)
{
if (l->visited == false)
{
q.push(l->destination);
l->visited=true;
l=l->next;
}
else
{
l=l->next;
}
}
}
}
};
int main()
{
graph g(4);
g.addRoute(0, 1);
g.addRoute(0, 2);
g.addRoute(1, 2);
g.addRoute(2, 0);
g.addRoute(2, 3);
// g.printGraph();
//cout << "Following is Breadth First Traversal (starting from vertex 2) \n";
g.BFS(1);
}
Your code is only running for the node that you have provided as the starting value for your BFS traversal.
void BFS(int start)
{
queue<int> q;
bool startFound = false;
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == start)
{
q.push(e.origin);
check.push_back(e.origin);
e.visited = true;
startFound = true;
break;
}
}
if (!startFound)
{
cout << "Start vertex not found in the graph" << endl;
return;
}
while (!q.empty())
{
int x = q.front();
cout << x << " ";
q.pop();
for (int i = 0; i < vectorOfEdges.size(); i++)
{
edge e = vectorOfEdges[i];
if (e.origin == x)
{
linkListNode *l = e.final.head;
while (l != NULL)
{
bool found = false;
if (l->visited == false)
{
l->visited = true;
for (int i = 0; i < check.size(); i++)
{
if (check[i] == l->destination)
{
found = true;
break;
}
}
if (found == false)
{
check.push_back(l->destination);
q.push(l->destination);
}
}
l = l->next;
}
}
}
}
}
Instead, do this to run it for every node.