C++ Remove duplication in a set of list - c++

I'm trying to remove duplications in the return list in this question
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5 and target 8,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
My question is how to efficiently remove the duplication?
The following is my code:
public class Solution {
public static void main(String[] args) {
int[] input = { 10, 1, 2, 7, 6, 1, 5 };
// int[] input = { 2, 1, 1, 4, 4, 2 };
System.out.println(combinationSum2(input, 8));
}
private static class Entry {
List<Integer> list;
int target;
int index; // the previous index
public Entry(int target) {
list = new LinkedList<Integer>();
this.target = target;
}
public int add(int num, int index) {
this.list.add(num);
this.index = index;
this.target -= num;
return target;
}
public Entry copy() {
Entry copy = new Entry(this.target);
copy.list = new ArrayList<>();
copy.list.addAll(list);
copy.target = target;
copy.index = index;
return copy;
}
}
public static List<List<Integer>> combinationSum2(int[] input, int target) {
List<List<Integer>> ret = new LinkedList<List<Integer>>();
if (null == input || input.length <= 0)
return ret;
Arrays.sort(input);
int N = input.length;
Queue<Entry> pool = new LinkedList<Entry>();
for (int i = 0; i < N; i++) {
if (input[i] <= target) {
Entry entry = new Entry(target);
entry.add(input[i], i);
pool.add(entry);
}
}
while (!pool.isEmpty()) {
Entry cur = pool.poll();
if (cur.target == 0) {
ret.add(cur.list);
} else if (cur.target > 0) {
for (int i = cur.index + 1; i < N; i++) {
if (cur.target - input[i] >= 0) {
Entry copy = cur.copy();
copy.add(input[i], i);
pool.offer(copy);
} else {
break;
}
}
}
}
return ret;
}
}
My first idea is to sort the lists in the return list, them compare one by one to remove duplication. But is there any faster way? or any suggestion?

My suggestion is to use HashSet to prevent adding any existing entry.
The first thing to do is override the equals and hashCode function for your Entry class. (more material)
private static class Entry {
List<Integer> list;
int target;
int index;
int hash; // <---- add this
public Entry(int target) {
list = new LinkedList<Integer>();
this.target = target;
hash = target;
}
public int add(int num, int index) {
this.list.add(num);
this.index = index;
this.target -= num;
hash = hash * 17 + num;
return target;
}
public Entry copy() {
Entry copy = new Entry(this.target);
copy.list = new ArrayList<>();
copy.list.addAll(list);
copy.target = target;
copy.index = index;
copy.hash = hash;
return copy;
}
#Override
public boolean equals(Object obj) {
Entry e = (Entry) obj;
if ((this.target != e.target) || (this.list.size() != e.list.size())) {
return false;
}
for (int i = 0; i < this.list.size(); i++) {
if (!this.list.get(i).equals(e.list.get(i)))
return false;
}
return true;
}
#Override
public int hashCode() {
return hash;
}
}
The next step is to use a hashset to filter the result.
Set<Entry> nodup = new HashSet<Entry>();
while (!pool.isEmpty()) {
Entry cur = pool.poll();
if (cur.target == 0) {
nodup.add(cur);
} else if (cur.target > 0) {
// ... your code
}
}
for (Entry entry : nodup) {
ret.add(entry.list);
}

You can remove duplicates or repeated elements from List in Java by converting List into HashSet in Java. but before doing that just keep in mind that Set doesn't preserver insertion order which is guaranteed by List, in fact that’s the main difference between List and Set in Java.
So when you convert List to HashSet all duplicates elements will be removed but insertion order will be lost.
More detailed explanation can be found here

You can use hashing as another solution, though it will use O(n) in terms of space (the same in time).
Essentially, traverse the list from head to end. For every newly encountered element, we check whether it is in the hash set (HashSet): if yes, we remove it; otherwise we put it in.

Related

Pointer to array of pointers to structs in C++

I need some help, I'm learing data structers and I got a task to write a programm based on array of pointers to structres which can add elements and do other task with array.I have next model of levels:
first level --> net of shops
second level --> shop
third level --> goods
I've written types for this
typedef struct
{
QString date;
QString prod_code;
QString name;
}goods;
typedef struct
{
QString address;
QString number;
void **sublevel;
}shop;
typedef struct
{
QString website;
QString name;
QString owner;
QString address;
void **sublevel;
}net;
Then I've created global variable void **Start which points to array of pointers:
// init list
void ** init_list()
{
void** p = new void*[SIZE_AR];
p = p+2;
((int*)p)[COUNT_POS] = 0;
((int*)p)[SIZE_POS] = SIZE_AR;
return p;
}
void ** Start = init_list();
COUNT_POS - index of elements where I store count of currently used elemnets
SIZE_POS - size of array allocated in dynamic memory
SIZE_AR - default size for array
But I get segmentation fault when I try to add to element to the last level
(for previous two ones works fine):
// expand array if it overfilled
void ExpandArrPtr (void **&ar, int &SizeAr, int Cnt)
{
void **arW;
arW = new void*[SizeAr+DELTA+2];
for (int K = SizeAr-1; K >= 0; K--) {
arW[K+2] = ar[K];
}
SizeAr = SizeAr + DELTA;
ar=ar-2;
delete []ar;
ar=arW+2;
((int*)ar)[COUNT_POS] = Cnt;
((int*)ar)[SIZE_POS] = SizeAr;
}
// binary search
void bin_search(void **start, QString key, int &pos, bool &find, Cmpmethod func)
{
int mid;
int high, low;
find = false;
if((int*)start[COUNT_POS] == 0)
{
pos = 0;
qDebug()<<"zero elem\n";
return;
}
low = 0;
high = ((int*)start)[COUNT_POS] - 1;
do
{
mid = (high + low) / 2;
int result = func(start[mid], key);
if(result == 0)
{
pos = mid;
find = true;
return;
}
else if(result == 1)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}while(low <= high);
pos = low;
}
// function for adding in any level
void addtosort(void **&start, void *pnew, int pos)
{
int count = ((int*)start)[COUNT_POS];
int size = ((int*)start)[SIZE_POS];
if(count == size)
{
ExpandArrPtr(start, size, count);
}
if(pos == count)
{
start[pos] = pnew;
}
else
{
for(int i = count;i >= pos;i--)
{
start[i+1] = start[i];
}
start[pos] = pnew;
}
count++;
((int*)start)[COUNT_POS] = count;
}
void add_goods(void **&Start, goods * Pnew)
{
int pos;
bool find;
bin_search((((shop*)(Start))->sublevel), Pnew->name, pos, find, compare_goods);
addtosort((((shop*)(Start))->sublevel), Pnew, pos);
}
// finding the item in second level to add
void find_place(QString key)
{
int pos;
bool find;
int count = ((int*)Start)[COUNT_POS];
for(int i = 0;i < count;i++)
{
bin_search(((net*)(Start)[i])->sublevel, key, pos, find, compare_shop);
if(find)
{
goods * Pnew = new goods;
Pnew->date = "foo"
Pnew->name = "bar"
add_goods(((net*)(Start)[pos])->sublevel, Pnew);
break;
}
}
}
What can cause such problem?

Index from address in array of pointers?

The code below a solution to the following requirement:
"Change the representation of Link and List from §27.9 without changing the user interface provided by the functions. Allocate Links in an array of Links and have the members: first, last, prev, and next be ints (indices into the array). " - Exercise 6 Chapter 27 - Programming: Principles and Practice Using C++ B. Stroustrup
The interface is inherited from an ordinary implementation of an Intrusive doubly linked list. I've added the bool array (and the associated functions) to keep track of memory:
#include <iostream>
struct Link
{
int next;
int prev;
};
//------------------------------------------------------------------------------------
struct List
{
Link** head;
int first; // points to the current first node
int last;
bool* available;
int list_size;
int get_index()
{
for (int i = 0; i < list_size; ++i)
{
if (available[i] == true)
{
available[i] = false;
return i;
}
}
throw std::bad_alloc("bla bla!\n");
}
List()
{
list_size = 30;
head = new Link*[list_size];
available = new bool[list_size];
first = -1;
last = -1;
for (int i = 0; i < list_size; ++i)
{
available[i] = true;
}
}
void List::push_back(Link* l)
{
if (l == nullptr)
{
throw std::invalid_argument("bla bla!\n");
}
int index = get_index();
head[index] = l;
if (last != -1)
{
head[last]->next = index;
head[index]->prev = last;
}
else
{
first = index;
head[index]->prev = -1;
}
last = index;
head[index]->next = -1;
}
void push_front(Link* l)
{
if (l == nullptr)
{
throw std::invalid_argument("bla bla\n");
}
int index = get_index();
head[index] = l;
if (first != -1)
{
head[first]->prev = index;
head[index]->next = first;
}
else
{
last = index;
head[index]->next = -1;
}
first = index;
head[index]->prev = -1;
}
// index = ptr - base
std::ptrdiff_t index_from_address(Link* l) { return l - head[0]; }
Link* front() const { return head[first]; }
};
//------------------------------------------------------------------------------------
int main()
{
List l;
for (int i = 0; i < 10; ++i)
{
l.push_back(new Link());
}
for (int i = 0; i < 10; ++i)
{
l.push_front(new Link());
}
std::cout <<"first = "<< l.first <<", index = " << l.index_from_address(l.front());
getchar();
}
Expected result:
first = 19, index = 19
Actual result:
first = 19, index = 194
Why?
l - head[0]
Here you compare the values of the two pointers. You let all pointers in the array be default initialized, so their values are indeterminate, and therefore the behaviour of accessing the values is undefined.
You probably intended index_from_address to find the index where a particular pointer object is stored - rather than the object that is pointed to, since the pointed to object is not in the array pointed by head. To do that, you must add a whole bunch of &:
Link*& front() const // return a reference to the pointer object, not a copy
// take a reference to the pointer as an argument, add const for good measure
std::ptrdiff_t index_from_address(Link*& l) const
// compare the addresses of the pointers, rather than values
{ return &l - &head[0]; }

how do i implement heap data structure using c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Using this simple example of a binary heap. How would i implement this data structure using c++ code.
1
/ \
3 6
/\ /\
5 9 8
Also apart from being able to gain easy access to the max or min values in an array, how is this data structure useful?
the example come from the following link: http://www.algolist.net/Data_structures/Binary_heap
Here is my simplest C++ implementation for heap. The code is well-commented.
/*
Usage:
heap Heap;
Heap.clear();
Heap.insert(value);
Heap.remove();
Heap.print();
*/
struct heap {
int myarray[NN+1]; // myarray to store the numbers as heap, 1 indexed
int n; // the number of nodes in my array
heap() { // constructor
clear(); // we clear the heap
}
void clear() { // initialize the heap
n = 0; // initially there are no nodes in the heap
}
void insert( int K ) { // inserting an element K in the heap
if( n == NN ) { // the heap is full
printf("cannot insert any more element, the heap is full\n");
return;
}
++n; // so, we have a new element, we increased n before adding
// the element because we start from index 1
myarray[n] = K; // inserted the element at the rightmost position
int p = n; // for keeping the current position
while( p > 1 ) { // p = 1 means we are on the root, and its a heap
int pr = p / 2; // pr is the parent of p
if( myarray[pr] > myarray[p] ) { // parent is greater than child
swap( myarray[pr], myarray[p] );
p = pr; // now the new position of the current element is pr
} else break; // otherwise its a heap, so we can stop here
}
}
int remove() { // removing the minimum element from the heap
if( n == 0 ) { // is the heap is empty
printf("The heap is empty, cannot delete.\n");
return -1;
}
int K = myarray[1]; // first element in the heap is the minimum
myarray[1] = myarray[n]; // brought the last element in 1st position
n--; // as we removed one element, now we need to maintain the heap
int p = 1; // as we moved the rightmost element in index 1
while( 2 * p <= n ) { // means p has at least one child, if 2*p > n
// we are sure that p is in the last level
int ch = 2 * p; // contains the index of the child
if( 2 * p + 1 <= n ) { // right child exists
if( myarray[ch] > myarray[ch+1] ) // right child is smaller
// than left child
ch++; // ch contains the index of the right child
}
if( myarray[p] > myarray[ch] ) { // so, current node is larger
// than its child
swap( myarray[p], myarray[ch] );
p = ch; // new position of the current element
} else break; //current node is smaller than its children, so heap
}
return K; // as we stored the minimum element in K
}
void print() { // printing the heap
printf("Number of elements: %d\n", n);
for( int i = 1; i <= n; i++ ) printf("%d ", myarray[i]);
printf("\n");
}
// Time: O(nlogn)
// Extra space: O(1) as we will pass the input array as res here
void heapSort(int* res) {
for(int i = 0, len = n; i < len; ++i) {
res[i] = remove();
}
}
};
I am writing below Java implementation it can help you to write code in c++;
import java.util.Arrays;
/**
* Min heap implementation, also caters to duplicate
*/
public class MinHeap {`
private int capacity = 10;
private int size;
int[] items;
public MinHeap() {
items = new int[capacity];
size = 0;
}
public void ensureExtraCapacity() {
if (size == capacity) {
items = Arrays.copyOf(items, capacity * 2);
capacity *= 2;
}
}
private int getLeftChildIndex(int index) {
return 2 * index + 1;
}
private int getRightChildIndex(int index) {
return 2 * index + 2;
}
private int getParentIndex(int index) {
return (index - 1) / 2;
}
private boolean hasLeftChild(int index) {
return size > getLeftChildIndex(index);
}
private boolean hasRightChild(int index) {
return size > getRightChildIndex(index);
}
private boolean hasParent(int index) {
if(index == 0)
return false;
return getParentIndex(index) >= 0;
}
private int leftChild(int index) {
return items[getLeftChildIndex(index)];
}
private int rightChild(int index) {
return items[getRightChildIndex(index)];
}
private int parent(int index) {
return items[getParentIndex(index)];
}
private void swapValues(int index1, int index2) {
int temp = items[index1];
items[index1] = items[index2];
items[index2] = temp;
}
public int peek() {
if (size == 0) throw new IllegalStateException();
return items[0];
}
public int poll() {
if (size == 0) throw new IllegalStateException();
int polled = items[0];
items[0] = items[size - 1];
size--;
heapifyDown();
return polled;
}
public void add(int item) {
ensureExtraCapacity();
items[size] = item;
size++;
heapifyUp();
}
private void heapifyUp() {
int index = size - 1;
while (hasParent(index) && parent(index) > items[index]) {
swapValues(index, getParentIndex(index));
index = getParentIndex(index);
}
}
private void heapifyDown() {
int index = 0;
while (hasLeftChild(index)) {
int minimumChildIndex = getLeftChildIndex(index);
if (hasRightChild(index) && rightChild(index) < leftChild(index))
minimumChildIndex = getRightChildIndex(index);
if (items[index] < items[minimumChildIndex]) {
break;
} else {
swapValues(index, minimumChildIndex);
}
index = minimumChildIndex;
}
}
/* public void printMinHeap() {
while (size > 0) {
int poll = poll();
System.out.println(poll);
}
}*/
/* public static void main(String[] args) {
MinHeap minHeap = new MinHeap();
minHeap.add(7);
minHeap.add(3);
minHeap.add(4);
minHeap.add(10);
minHeap.add(1);
minHeap.add(15);
minHeap.add(2);
minHeap.add(17);
minHeap.add(1);
minHeap.printMinHeap();
}*/
}

Dijkstra algorithm. Min heap as a min-priority queue

I'm reading about Dijkstra's algorithm in CLRS, Third Edition (p. 662). Here is a part from the book I don't understand:
If the graph is sufficiently sparse — in particular, E = o(V^2/lg V) — we can improve the algorithm by implementing the min-priority queue with a binary min-heap.
Why should the graph be sparse?
Here is another part:
Each DECREASE-KEY operation takes time O(log V), and there are still
at most E such operations.
Suppose my graph looks like this:
I'd like to calculate the shortest path from 1 to 6 and use the min-heap approach. So first off, I add all my nodes to a min priority queue. After building a min heap, the min node is the source node (since its distance to itself is 0). I extract it and update distances of all its neighbors.
Then I need to call decreaseKey on the node with the lowest distance to make a new minimum of the heap. But how do I know its index in constant time?
Node
private static class Node implements Comparable<Node> {
final int key;
int distance = Integer.MAX_VALUE;
Node prev = null;
public Node(int key) {
this.key = key;
}
#Override
public int compareTo(Node o) {
if (distance < o.distance) {
return -1;
} else if (distance > o.distance) {
return 1;
} else {
return 0;
}
}
#Override
public String toString() {
return "key=" + key + " distance=" + distance;
}
#Override
public int hashCode() {
return key;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Node)) {
return false;
}
Node other = (Node) obj;
return key == other.key;
}
}
MinPriorityQueue
public static class MinPriorityQueue {
private Node[] array;
private int heapSize;
public MinPriorityQueue(Node[] array) {
this.array = array;
this.heapSize = this.array.length;
}
public Node extractMin() {
Node temp = array[0];
swap(0, heapSize - 1, array);
heapSize--;
sink(0);
return temp;
}
public boolean isEmpty() {
return heapSize == 0;
}
public void buildMinHeap() {
for (int i = heapSize / 2 - 1; i >= 0; i--) {
sink(i);
}
}
public void decreaseKey(int index, Node key) {
if (key.compareTo(array[index]) >= 0) {
throw new IllegalArgumentException("the new key must be greater than the current key");
}
array[index] = key;
while (index > 0 && array[index].compareTo(array[parentIndex(index)]) < 0) {
swap(index, parentIndex(index), array);
index = parentIndex(index);
}
}
private int parentIndex(int index) {
return (index - 1) / 2;
}
private int left(int index) {
return 2 * index + 1;
}
private int right(int index) {
return 2 * index + 2;
}
private void sink(int index) {
int smallestIndex = index;
int left = left(index);
int right = right(index);
if (left < heapSize && array[left].compareTo(array[smallestIndex]) < 0) {
smallestIndex = left;
}
if (right < heapSize && array[right].compareTo(array[smallestIndex]) < 0) {
smallestIndex = right;
}
if (index != smallestIndex) {
swap(smallestIndex, index, array);
sink(smallestIndex);
}
}
public Node min() {
return array[0];
}
private void swap(int i, int j, Node[] array) {
Node temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
Why should the graph be sparse?
The running time of Dijkstra's algorithm depends on the combination of the underlying data structure and the graph shape (edges and vertices).
For example, using a linked list would require O(V²) time, i.e. it only depends on the number of vertices.
Using a heap would require O((V + E) log V), i.e. it depends on both the number of vertices and the number of edges.
If your E is sufficiently smaller compared to V (as in E << V² / logV), then using heap becomes more efficient.
Then I need to call decreaseKey on the node with the lowest distance to make a new minimum of the heap. But how do I know its index in constant time?
If you're using a binary heap, then extractMin always runs in O(log V) time and gives you the node with the lowest distance (a.k.a. key).
For example, if you're implementing the binary min-heap as an array H, then the first element of the array H[1] (by convention we count from 1) will always be the element with the lowest distance, so finding it only takes O(1).
However, after each extractMin, insert or decreaseKey you have to run swim or sink to restore the heap condition, consequently moving the lowest-distance node to the top. This takes O(log V).
What you also want to do is maintain a mapping between keys in the heap and vertices, as mentioned in the book: "make sure that
vertices and corresponding heap elements maintain handles to each other" (briefly discussed in section 6.5).
Let's suppose that your graph consists of vertices (Node) in your case you have 7 (0 ->6 ) and edges. These are represented by the following model :
Node model :
public class Vertex{
final private String id;
final private String name;
public Vertex(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Vertex other = (Vertex) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
#Override
public String toString() {
return name;
}
}
And the edges will be present by this model : Edge
public class Edge {
private final String id;
private final Vertex source;
private final Vertex destination;
private final int weight;
public Edge(String id, Vertex source, Vertex destination, int weight) {
this.id = id;
this.source = source;
this.destination = destination;
this.weight = weight;
}
public String getId() {
return id;
}
public Vertex getDestination() {
return destination;
}
public Vertex getSource() {
return source;
}
public int getWeight() {
return weight;
}
#Override
public String toString() {
return source + " " + destination;
}
}
The graph (nodes + edges) will be present by this class : Graph
public class Graph {
private final List<Vertex> vertexes;
private final List<Edge> edges;
public Graph(List<Vertex> vertexes, List<Edge> edges) {
this.vertexes = vertexes;
this.edges = edges;
}
public List<Vertex> getVertexes() {
return vertexes;
}
public List<Edge> getEdges() {
return edges;
}
}
This is a simple implementation of Dijkstra’s algorithm. It does not use any performance optimization :
public class DijkstraAlgorithm {
private final List<Vertex> nodes;
private final List<Edge> edges;
private Set<Vertex> settledNodes;
private Set<Vertex> unSettledNodes;
private Map<Vertex, Vertex> predecessors;
private Map<Vertex, Integer> distance;
public DijkstraAlgorithm(Graph graph) {
// create a copy of the array so that we can operate on this array
this.nodes = new ArrayList<Vertex>(graph.getVertexes());
this.edges = new ArrayList<Edge>(graph.getEdges());
}
public void execute(Vertex source) {
settledNodes = new HashSet<Vertex>();
unSettledNodes = new HashSet<Vertex>();
distance = new HashMap<Vertex, Integer>();
predecessors = new HashMap<Vertex, Vertex>();
distance.put(source, 0);
unSettledNodes.add(source);
while (unSettledNodes.size() > 0) {
Vertex node = getMinimum(unSettledNodes);
settledNodes.add(node);
unSettledNodes.remove(node);
findMinimalDistances(node);
}
}
private void findMinimalDistances(Vertex node) {
List<Vertex> adjacentNodes = getNeighbors(node);
for (Vertex target : adjacentNodes) {
if (getShortestDistance(target) > getShortestDistance(node)
+ getDistance(node, target)) {
distance.put(target, getShortestDistance(node)
+ getDistance(node, target));
predecessors.put(target, node);
unSettledNodes.add(target);
}
}
}
private int getDistance(Vertex node, Vertex target) {
for (Edge edge : edges) {
if (edge.getSource().equals(node)
&& edge.getDestination().equals(target)) {
return edge.getWeight();
}
}
throw new RuntimeException("Should not happen");
}
private List<Vertex> getNeighbors(Vertex node) {
List<Vertex> neighbors = new ArrayList<Vertex>();
for (Edge edge : edges) {
if (edge.getSource().equals(node)
&& !isSettled(edge.getDestination())) {
neighbors.add(edge.getDestination());
}
}
return neighbors;
}
private Vertex getMinimum(Set<Vertex> vertexes) {
Vertex minimum = null;
for (Vertex vertex : vertexes) {
if (minimum == null) {
minimum = vertex;
} else {
if (getShortestDistance(vertex) < getShortestDistance(minimum)) {
minimum = vertex;
}
}
}
return minimum;
}
private boolean isSettled(Vertex vertex) {
return settledNodes.contains(vertex);
}
private int getShortestDistance(Vertex destination) {
Integer d = distance.get(destination);
if (d == null) {
return Integer.MAX_VALUE;
} else {
return d;
}
}
/*
* This method returns the path from the source to the selected target and
* NULL if no path exists
*/
public LinkedList<Vertex> getPath(Vertex target) {
LinkedList<Vertex> path = new LinkedList<Vertex>();
Vertex step = target;
// check if a path exists
if (predecessors.get(step) == null) {
return null;
}
path.add(step);
while (predecessors.get(step) != null) {
step = predecessors.get(step);
path.add(step);
}
// Put it into the correct order
Collections.reverse(path);
return path;
}
}
Then create a test class and add your graph values :
public class TestDijkstraAlgorithm {
private List<Vertex> nodes;
private List<Edge> edges;
#Test
public void testExcute() {
nodes = new ArrayList<Vertex>();
edges = new ArrayList<Edge>();
for (int i = 0; i < 11; i++) {
Vertex location = new Vertex("Node_" + i, "Node_" + i);
nodes.add(location);
}
addLane("Edge_0", 0, 1, 5);
addLane("Edge_1", 0, 2, 40);
addLane("Edge_2", 0, 3, 21);
addLane("Edge_3", 2, 3, 13);
addLane("Edge_4", 2, 4, 19);
addLane("Edge_5", 4, 5, 32);
addLane("Edge_6", 3, 5, 41);
addLane("Edge_7", 4, 6, 14);
addLane("Edge_8", 5, 6, 8);
// Lets check from location Loc_1 to Loc_10
Graph graph = new Graph(nodes, edges);
DijkstraAlgorithm dijkstra = new DijkstraAlgorithm(graph);
dijkstra.execute(nodes.get(0));
LinkedList<Vertex> path = dijkstra.getPath(nodes.get(10));
assertNotNull(path);
assertTrue(path.size() > 0);
for (Vertex vertex : path) {
System.out.println(vertex);
}
}
private void addLane(String laneId, int sourceLocNo, int destLocNo,
int duration) {
Edge lane = new Edge(laneId,nodes.get(sourceLocNo), nodes.get(destLocNo), duration );
edges.add(lane);
}
}

Is Iterative Deepening Search supposed to be that slow?

My Data Structure:
class Cell
{
public:
struct CellLink
{
Cell *cell;
int weight;
};
public:
int row;
int column;
vector<CellLink> neighbors;
State state;
int totalCost = 0;
};
The primary function:
void AI::IterativeDeepeningSearch(Cell* cell)
{
Cell* temp;
int bound = 0;
while (true)
{
naturalFailure = false;
temp = IDShelper(cell, bound);
if (IsExit(temp))
{
break;
}
bound++;
}
}
The Helper:
Cell* AI::IDShelper(Cell* cell, int bound)
{
Cell* temp = cell;
SetEnvironment(cell, State::visited);
PrintEnvironment();
if (bound > 0)
{
for (int i = 0; i < cell->neighbors.size(); i++)
{
temp = IDShelper(cell->neighbors[i].cell, bound - 1);
if (IsExit(temp))
{
naturalFailure = true;
return temp;
}
}
}
else if (IsExit(cell))
{
return cell;
}
return temp;
}
I have made an Iterative Deepening Search for a maze. The problem is that it is taking literally hours to complete the search on a 21x21 maze while other algorithms take a couple of seconds.
I know that IDS is supposed to be slow but is it supposed to be that slow?
I think I can see why this is slow.
In your helper, you're visiting the neighbors like so:
if (bound > 0)
{
for (int i = 0; i < cell->neighbors.size(); i++)
{
temp = IDShelper(cell->neighbors[i].cell, bound - 1);
if (IsExit(temp))
{
naturalFailure = true;
return temp;
}
}
}
but you're never using past results. You mark something as visited, but never check whether it is already visited.