0

I am working with Graphs, and writing code some well known algorithms. Currently I am working on the Dijkstra Algorithm.

So, I have made my own Heap class which works as a min-priority queue for the implementation of the Dijkstra algorithm. Since, in the Dijkstra algorithm, you need to update the distance of a vertex (which is already in the heap), from the source vertex in the Graph, if its distance is less than it's current distance, and then accordingly adjust the values in a Heap.

For this, I need to keep an int position[] array to keep a track of the positions at which the elements are currently in the Heap

This is my Vertex Class ::

    class Node{
    public:
        int data;
        int weight;

        .....

        friend int& operator [](int *a, Node i) {
            return a[i.data];
        }
    };

My minPriorityQueue class ::

template <typename t>
class minPriorityQueue {
    int size, currentPosition;
    int *position;
    t *data;
    bool (*compare)(t data1, t data2);
public:
    minPriorityQueue(int size, bool (*func1)(t data1, t data2), int *position) {
        this->size = size;
        currentPosition = 1;
        data = new t[size];
        compare = func1;
        this->position = position;
    }

   ........

    void swapPositionValue(int parent, int temp) {
        int tempPosition = position[data[parent]];
        position[data[parent]] = position[data[temp]];
        position[data[temp]] = tempPosition;
    }    

    ......
};

Since my vertices are 0,1,2,3, ... So, I try to overload the []operator of my Vertex class so that it returns me the data of the current vertex (which is one from 0,1,2,3 ..., so I can use it to access that index of the position array.

I get the compilation error :: error: 'int operator[](int*, graph::Vertex)' must be a nonstatic member function Well, since I get this error I assume that it must have been specified in the standard that I cannot overload the []operator using a friend function, but why I cannot do it?? Does it lead to any ambiguity? I don't see what can be ambiguous in what I am currently using.

Secondly, is there any way I can swap the values in my position array? My minPriorityQueue class is a generic class which I am using at several other places at my code as well. In the function swapPositionValue if I change my swap statements to this ::

    int tempPosition = position[data[parent].data];
    position[data[parent].data] = position[data[temp].data];
    position[data[temp].data] = tempPosition;

Then the whole idea of "generic" priority queue will be sacrificed! Since, it won't work with other classes!

Is there a way that I can achieve this functionality??

EDIT1 :: The complete Code :: http://ideone.com/GRQHHZ (Using Ideone to paste the code, Because the code is still very large, containing 2 classes)

This is what I am trying to achieve :: http://www.geeksforgeeks.org/greedy-algorithms-set-7-dijkstras-algorithm-for-adjacency-list-representation/ (I am just using the algorithm)

Explanation of what is the functionality of operator[]:: In my Dijkstra implementation all the nodes are initially inserted into the Heap, with the start node, having the weight = 0, and all the other nodes with weight = INFINITY (which means I cannot reach the vertices) so start vertex is the topmost element of the heap! Now when I remove the topmost element, all the Node that have a path from the removed Node will get modified, their weight will be modified from INFINITY to some finite value. So, I need to update the Nodes in the Heap, and then I need to move them to their correct positions, according to their new weights!! To update their weights, I need to know at what position are the Nodes located in the Heap, and the position is decided by the data of the Node. So, overloading the []operator was just a small way out for me, so that when I do position[Node], I can access position[Node.data].

Why this is not a duplicate:: The linked question is a broad operator overloading post, it just mentions 1 point where it states that []operator can only be overloaded with member functions and not otherwise, does not state why! And this is a specific problem I am facing where I do not want to sacrifice the generic property of my self made Heap, and use it for the Dijkstra as well.

EDIT2 :: While writing this explanation I realize I had made a big mistake in my overloaded function. I have changed it! Please check it. Probably it makes more sense now. Apologies!!

The overloaded function now looks like ::

friend int& operator [](int *a, Node i) {
    return a[i.data];
}

EDIT3 :: In implement my Graph class with Adjacency Matrix, and it is a boolean 2D array, because my current implementation is for Unweighted graphs, and accordingly the shortest path becomes the least number of edges traversed! (Just in case that mattered!)

Thanks for reading all of this huge question, and for any help! :)

user007
  • 2,156
  • 2
  • 20
  • 35
  • 1
    Show us the code that's giving you this error. Otherwise, we can't tell you what's wrong with it. – Drew Dormann Jul 15 '15 at 05:10
  • Yes, and strip all other code. BTW: What you want to overload it for is irrelevant and the standard library already contains a heap that might be a good idea to use instead. – Ulrich Eckhardt Jul 15 '15 at 05:12
  • You seem to be missing some basic understandings. The `[]` operator can be customised for your `Vertex` class, which lets you invoke it a la `my_vertex[n]`. Simply returning the `Vertex` `data` member doesn't make much sense, as you list it as an `int` - not an array, vector or other random access type that needs a `[n]` index. The function should be defined like `Return_Type operator[](size_t n)` *optional-*`const { return ...; }` – Tony Delroy Jul 15 '15 at 05:13
  • 3
    Your `operator[]` doesn't even begin to make sense. It must be a member function, with one argument being the thing that the caller will place inside the `[]` . Your version has an extra argument `a` which it doesn't even use, and it isn't a member function. – M.M Jul 15 '15 at 05:13
  • @DrewDormann : Well, probably the wrong thing is that I cannot overload the `[]` using friend function, The code is more than 400 lines, I will make the small and post! – user007 Jul 15 '15 at 05:15
  • @MattMcNabb: I know it doesn't use, but if you see the `swapPositionValue` function, you will realise that I need to get the `data` of the `Vertex` to make my `position` array work! Further, I know it is not a member function! That is the question!! Why does it only need a member function? And is there a way to get the data without loosing the `generic` property! – user007 Jul 15 '15 at 05:17
  • Where is your heap? I don't see how this priority queue is supposed to work, or what `position` is for – M.M Jul 15 '15 at 05:19
  • @MattMcNabb: I'll just post the heap code! Just give me 5min – user007 Jul 15 '15 at 05:20
  • Language standard aside, what is the **meaning** of `operator []` in your code, and how is it compared to `operator[]` of the standard containers? –  Jul 15 '15 at 05:25
  • When you say "swap" two nodes in the heap, do you actually mean you want to exchange the `data` member of two particular nodes, without changing their weights? (I'm assuming `weight` is what defines its position in the heap, and your compare function compares weights). This is weird... – M.M Jul 15 '15 at 05:27
  • 1
    Please move your second question to a different post. It is completely unrelated to your first. – Benjamin Lindley Jul 15 '15 at 05:30
  • @BenjaminLindley: But, probably its just in continuation, I guess! First what are the ambiguities and then is there a way to work it out with my code! – user007 Jul 15 '15 at 06:15
  • But how is this meaning compared to the `operator[]` of the standard containers, and even that of raw array? –  Jul 15 '15 at 06:32
  • @NickyC : The meaning is compared because in a normal `int` array if I do `a[i]` I get that data at `ith` position, in my case I want to do `position[node]` which returns me `position[node.data]` and `node` is some `ith` object in the `Heap` – user007 Jul 15 '15 at 06:35
  • @NickyC Probably it solves the first part of the question, that why we cannot do it, one of the ans states >> answer to "Why" is "Just because"., That probably means I cannot achieve this? And I will have to code a new heap, which is only for the `Node` class? and I cannot reuse the code? – user007 Jul 15 '15 at 06:54
  • @user007: Your comment to me made no sense. My previous comment stands. Your two questions are unrelated. Even if they were somehow related, they still belong as two separate posts. – Benjamin Lindley Jul 15 '15 at 07:34
  • @BenjaminLindley Well it seemed that it didn't make sense to anyone else either! Never Mind.. Thank you so much everyone for looking into it! :) – user007 Jul 15 '15 at 08:44
  • 1
    Well, probably I understood a bit of what you are trying to do! Though its very haphazardly written! No matter what you do you cannot use operator overloading to achieve, is what I can make out from attached links and comments, because it just isn't allowed! One more thing that you can try doing is passing another function pointer to your class and when you need to swap positions just call that function with the needed parameters. And when you don't need it, simply assign that function pointer to NULL. I guess that is what you needed! – coderzz027 Jul 15 '15 at 15:59
  • @coderzz027 : And then calling the function everytime i need to change the positions! Yes, that might work. Probably that was what I was looking for. Thank you so much.. I will try doing it. – user007 Jul 15 '15 at 19:12
  • @coderzz027 It just worked!! Thank you so much!! :) :) :) It was pissing me off since morning! And finally it worked! Thank you so much.. I would have accepted your answer, had the question still been accepting responses! Thank you so much :) – user007 Jul 15 '15 at 19:54

0 Answers0