import of cs677/hw1

git-svn-id: svn://anubis/gvsu@135 45c1a28c-8058-47b2-ae61-ca45b979098e
This commit is contained in:
josh 2008-08-30 16:32:24 +00:00
parent a396cf9d62
commit f9633e53f3
5 changed files with 240 additions and 0 deletions

12
cs677/hw1/Makefile Normal file
View File

@ -0,0 +1,12 @@
TARGET := minimum-energy
all: $(TARGET)
$(TARGET): $(TARGET).cc
$(CXX) -o $@ $^
.PHONY: test
test:
./$(TARGET) test-impossible.txt
./$(TARGET) test-long-short.txt

View File

@ -0,0 +1,10 @@
S1
S6
S1 S2 10
S2 S3 8
S2 S4 13
S2 S5 24
S2 S6 51
S3 S4 14
S4 S5 9
S5 S6 17

202
cs677/hw1/minimum-energy.cc Normal file
View File

@ -0,0 +1,202 @@
#include <iostream>
#include <fstream>
#include <string>
#include <queue>
#include <map>
using namespace std;
/**************************************************************************
* The Transition class holds a (cost, destination node) pair *
*************************************************************************/
class Transition
{
public:
int cost;
string destination;
};
/**************************************************************************
* Path objects represent a path through the the graph starting at the *
* start node. The Path object has a certain cost associated with it. *
* The path may or may not end on the goal node. *
*************************************************************************/
class Path
{
public:
int cost;
vector<string> node_list;
map<string, bool> visited_nodes;
Path()
{
cost = 0;
}
Path(const Path & orig, const Transition & t)
{
cost = orig.cost + t.cost;
node_list = orig.node_list;
node_list.push_back(t.destination);
visited_nodes = orig.visited_nodes;
visited_nodes[t.destination] = true;
}
// comparison operator for making a min priority_queue
bool operator()(const Path & p1, const Path & p2)
{
return p1.cost > p2.cost;
}
};
/* This function allows Path objects to be printed to ostream objects */
ostream & operator<<(ostream & out, const Path & p)
{
int sz = p.node_list.size();
out << '[';
for (int i = 0; i < sz; i++)
{
out << p.node_list[i];
if (i < sz-1)
out << ", ";
}
out << ']';
return out;
}
/**************************************************************************
* Global type definitions *
*************************************************************************/
typedef vector<Transition> Transition_List_t;
typedef map<string, Transition_List_t> Transition_Table_t;
/**************************************************************************
* Function Prototypes *
*************************************************************************/
void createTransition(Transition_Table_t & transitions,
string src, string dest, int cost);
void solveMinEnergy(string start, string goal,
Transition_Table_t & transitions);
/**************************************************************************
* Main Function *
*************************************************************************/
int main(int argc, char * argv[])
{
if (argc != 2)
{
cerr << "Usage: minimum-energy <input-file>" << endl;
return 42;
}
ifstream i(argv[1]);
if (!i.is_open())
{
cerr << "Could not open " << argv[1] << endl;
return 1;
}
string startNode;
string goalNode;
Transition_Table_t node_transitions;
// Read the input file
i >> startNode;
i >> goalNode;
while (!i.eof())
{
string src, dest;
int cost;
i >> src >> dest >> cost;
createTransition(node_transitions, src, dest, cost);
}
i.close();
solveMinEnergy(startNode, goalNode, node_transitions);
return 0;
}
/**************************************************************************
* Add a new transition into the node_transitions table *
*************************************************************************/
void createTransition(Transition_Table_t & transitions,
string src, string dest, int cost)
{
if (transitions.find(src) == transitions.end())
{
/* src is not a key in transitions, so insert a new one */
Transition_List_t tl;
transitions[src] = tl;
}
Transition t;
t.cost = cost;
t.destination = dest;
transitions[src].push_back(t);
}
/**************************************************************************
* Solve the minimum energy problem for start node start, goal node goal, *
* and transition table set transitions *
*************************************************************************/
void solveMinEnergy(string start, string goal,
Transition_Table_t & transitions)
{
priority_queue<Path, vector<Path>, Path> pathQueue;
/* Create an initial path with just the starting node in it */
Path init;
init.cost = 0;
init.node_list.push_back(start);
init.visited_nodes[start] = true;
pathQueue.push(init);
/* LOOP
* IF there are no paths left in the pathQueue
* THEN there is no path to the goal; exit loop
* END IF
* IF the shortest path in the pathQueue ends at the goal node,
* THEN we are done; exit loop
* END IF
* Remove the shortest path in the pathQueue
* FOR EACH transition from the last node in the shortest path
* IF the destination of the transition has not been visited
* yet in this path
* THEN Add a new path to the pathQueue with the destination
* node of the transition appended to the end of the path
* END IF
* END FOR EACH
* END LOOP
*/
for (;;)
{
if (pathQueue.size() == 0)
{
cout << "There is no path from " << start << " to " << goal
<< "!" << endl;
break;
}
if (pathQueue.top().visited_nodes.find(goal)
!= pathQueue.top().visited_nodes.end())
{
cout << "The minimum-energy set of reactions follows the path "
<< pathQueue.top() << " with a energy cost of "
<< pathQueue.top().cost
<< endl;
break;
}
Path p = pathQueue.top();
pathQueue.pop();
string last = p.node_list[p.node_list.size() - 1];
if (transitions.find(last) != transitions.end())
{
for (int i = 0, sz = transitions[last].size(); i < sz; i++)
{
if (p.visited_nodes.find(transitions[last][i].destination)
== p.visited_nodes.end())
{
/* the destination has not yet been visited in this path */
Path newPath(p, transitions[last][i]);
pathQueue.push(newPath);
}
}
}
}
}

View File

@ -0,0 +1,3 @@
START
GOAL
START NOWHERE 1

View File

@ -0,0 +1,13 @@
START
GOAL
START I1 10
START I2 10
START I3 1
I1 GOAL 5
I2 GOAL 4
I3 I4 1
I4 I5 1
I5 I6 1
I6 I7 1
I7 GOAL 2