![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
prim's algorithm
Ok, i have another program for everyone... This time i have to implement prim's algorithm. Each edge has a starting vertex, ending vertex and weight associated with it. The program starts by asking if the graph is supposed to be directed or undirected. Then it asks the user for the number of vertices. The user inputs the vertices until the total has been reached or they enter -1 -1 -1 for the starting vertex, ending vertex and weight. The second part asks the user for a starting vertex and runs the algorithm and displays the final cost of each vertex. After this the user can exit the program or re-run the program with a different starting vertex. 3 things: 1. there can be a maximum of 50 vertices, 2. Vertices can be identified by a number. 3. there will not be loops but there can be cycles.
I am going to start by asking the user how many vertices there are and inserting them correctly. I was thinking of having one class that is the vertex and then another class that is the edge. If this is the case what do i have in the vertex class? Or should i make it one class with the start, end, and weight. The constructor would initiate the start and end to NULL and the weight to 0. Also i was thinking of maybe an array implementation because i know there can be a max of 50 vertices? Anyone have any ideas of how i should get started and what the best way to go about this is? |
|
|
|
|
|
#2 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
ok i thought i was only a little confused but i looked in some books and found an implmentation with vectors and all kinds of crazy stuff that i have no idea how to use. Any ideas on how to implement this. Then i saw some things about a priority queue with the weights as the numbers. I have used queues before but never priority queues. Anyone have any ideas?
|
|
|
|
|
|
#3 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
ok what about this. What if i kept track of each vertex and its corresponding weight in like a record of some kind. Then compare the weight of the vertices like if vertex 1 weight is less than vertex 2 weight it would go higher in the queue. So if i kept this queue in an array by the end i should have an array with the minimum cost at the front?
|
|
|
|
|
|
#4 |
|
Hobbyist Programmer
Join Date: Mar 2006
Location: Lebanon
Posts: 148
Rep Power: 3
![]() |
ive used this implementation last semester.. take a look . the graph is a class you can implement it as you wish i only posted its virtual class..
void Prim(Graph* G, int* D, int s) {
int V[G->n()];
int i, w;
for (i=0; i<G->n(); i++) {
int v = minVertex(G, D);
G->setMark(v, VISITED);
if (v != s) AddEdgetoMST(V[v], v);
if (D[v] == INFINITY) return;
for (w=G->first(v); w<G->n();
w=G->next(v,w))
if (D[w] > G->weight(v,w)) {
D[w] = G->weight(v,w);
V[w] = v;
}
}
}
int minVertex(Graph* G, int* D) {
int j, v;
for (j=0; j<G->n(); j++)
if (G->getMark(j) == UNVISITED)
{ v = j; break; }
for (j++; j<G->n(); j++)
if ((G->getMark(j) == UNVISITED)
&& (D[j] < D[v]))
v = j;
return v;
}
class Graph { // Graph abstract class
public:
virtual int n() =0; // # of vertices for whole graph
virtual int e() =0; // # of edges for whole graph
// Return index of first neighbor for a given vertex
virtual int first(int) =0;
// Return index of next neighbor (get vertex1’s neighbor after // vertex2).
virtual int next(int, int) =0;
// Store new edge, identified by two vertices, 3rd parm is weight
virtual void setEdge(int, int, int) =0;
// Delete edge defined by two vertices
virtual void delEdge(int, int) =0;
// Weight of edge connecting two vertices
virtual int weight(int, int) =0;
// The mark functions are used for traversal (VISITED or not)
virtual int getMark(int) =0;
virtual void setMark(int, int) =0;
}; |
|
|
|
|
|
#5 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
im kinda confused on what all that means. Like what does
int V[G->n()]; |
|
|
|
|
|
#6 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
ok i think i might be on to something. So each vertex can be represented with a number and there is a maximum of 50 vertices. Therefore, i have a method that takes the number of vertices the user wants and makes an array of numbers each one representing a vertex. So then when the user enters the edges they would say a number and then i would take that number from the array. I think this will work. However, i have one question. After they enter the starting vertex for the edge how do i take that number out of the array and i think i am going to have to make it a node linked to the number the user picks as the ending vertex with the cost of the edge in there too. I have a vertex class that just has the method that fills the array with the number the user enteres for the number of vertices. I think i am going to have an edge class. Since i am just using numbers could the start and end just be int and the weight be an int and then just have the constructor set the start and end based on what the user enters? I am confused because something tells me a graph is like a tree but with more than 2 children. I have a feeling that at some point the vertices will have to be nodes linked together like a tree and i will have to recursively go through the graph. I am not sure how to make this though.
|
|
|
|
|
|
#7 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
alright so i got a whole new way of doing it. I have a 2d array the row is the starting vertex and the column is the ending vertex. You type in the starting and ending vertices and the weight and it puts the weight in that spot in the 2d array. The array fills fine. I am having some problems with the prim function. This is the function that actually runs prims algorithm. I pass in the starting vertex and then do the function setting an array for the finished vertices and an array for the finished weights. This prim function is what i am having trouble with. I think it works except i call it recursively and i am not sure what to pass it for the remaining types through. If i pass it the starting vertex again it just keeps overwritting what the first one does. Also, i have to inlcude a way to check to see if the vertex is in the finished set. Secondly, i have to adjust the weight depending on the current vertex weight. Does someone know this algorithm that could help me i think i am close i just need the finishing touches now. here is the code:
#include <iostream>
#include<math.h>
using namespace std;
int matrix[50][50];
int finishedWeight[50];
int finishedVertices[50];
char* edges[50];
int counter = 0;
int size = 0;
void fillMatrix(int vertexNum)
{
for(int i = 0; i < vertexNum; i++)
{
for(int j = 0; j < vertexNum; j++)
{
matrix[i][j] = pow(2,32) - 1;
}
}
}
void insert(int start, int end, int weight)
{
matrix[start][end] = weight;
}
void addUndirected(int vertexNum)
{
int start = 0;
int end = 0;
int weight;
size = vertexNum;
fillMatrix(vertexNum);
while(start != -1)
{
cout << "Please enter a starting vertex: ";
cin >> start;
cout << "Please enter an ending vertex: ";
cin >> end;
cout << "Please enter a weight: ";
cin >> weight;
insert(start, end, weight);
insert(end, start, weight);
}
for(int i = 0; i < vertexNum; i++)
{
for(int j = 0; j < vertexNum; j++)
{
cout << "matrix[" << i << "][" << j << "] = " << matrix[i][j] << endl;
}
}
}
void addDirected(int vertexNum)
{
int start = 0;
int end = 0;
int weight;
size = vertexNum;
fillMatrix(vertexNum);
while(start != -1)
{
cout << "Please enter a starting vertex: ";
cin >> start;
cout << "Please enter an ending vertex: ";
cin >> end;
cout << "Please enter a weight: ";
cin >> weight;
insert(start, end, weight);
}
for(int i = 0; i < vertexNum; i++)
{
for(int j = 0; j < vertexNum; j++)
{
cout << "matrix[" << i << "][" << j << "] = " << matrix[i][j] << endl;
}
}
}
void prim(int startingVertex)
{
cout << "Size = " << size << endl;
int start = startingVertex;
int end;
int weight;
int minx;
int miny;
int minWeight = pow(2, 32) - 1;
for(int k = 0; k < size; k++)
{
finishedVertices[k] = start;
for(int l = 0; l < size; l++)
{
if(matrix[start][l] < minWeight)
{
for(int i = 0; i < size; i++)
{
if(matrix[start][l] != finishedWeight[i])
{
minx = start;
miny = l;
minWeight = matrix[minx][miny];
}
}
}
}
}
finishedVertices[counter] = minx;
cout << "finished vertices at 0 = " << finishedVertices[0] << endl;
cout << "finished vertices at 1 = " << finishedVertices[1] << endl;
finishedWeight[counter] = minWeight;
cout << "FinishedWeight at 0 = " << finishedWeight[0] << endl;
cout << "finishedWeight at 1 = " << finishedWeight[1] << endl;
counter++;
if(counter != size)
prim(2); //note: just to see if it would work with something else
}
int main()
{
addDirected(5);
int option;
cout << "Please enter a starting vertex: ";
cin >> option;
prim(option);
return 0;
} |
|
|
|
|
|
#8 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 333
Rep Power: 4
![]() |
i think for the recursive call of the prim method i need to acess the latest entry in finishedVertex[] and then take the column of that somehow and pass that as the new parameter. I think the main problem is taking the lowest weights column and moving to that row and then doing it again i think that will solve the problem of calling it again and changing weight.
Last edited by cwl157; Apr 18th, 2006 at 9:13 PM. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|