import of cs677/hw1
git-svn-id: svn://anubis/gvsu@135 45c1a28c-8058-47b2-ae61-ca45b979098e
This commit is contained in:
parent
a396cf9d62
commit
f9633e53f3
12
cs677/hw1/Makefile
Normal file
12
cs677/hw1/Makefile
Normal 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
|
10
cs677/hw1/cs677-hw1-nodes.txt
Normal file
10
cs677/hw1/cs677-hw1-nodes.txt
Normal 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
202
cs677/hw1/minimum-energy.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
cs677/hw1/test-impossible.txt
Normal file
3
cs677/hw1/test-impossible.txt
Normal file
@ -0,0 +1,3 @@
|
||||
START
|
||||
GOAL
|
||||
START NOWHERE 1
|
13
cs677/hw1/test-long-short.txt
Normal file
13
cs677/hw1/test-long-short.txt
Normal 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
|
Loading…
x
Reference in New Issue
Block a user