diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd2d8a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj +*.dot + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app \ No newline at end of file diff --git a/Header/dsatur.h b/Header/dsatur.h new file mode 100644 index 0000000..d095c1d --- /dev/null +++ b/Header/dsatur.h @@ -0,0 +1,19 @@ +#ifndef _DSATUR_H_ +#define _DSATUR_H_ + +#include "graph_color.h" + +using GraphColoring::GraphColor; + +namespace GraphColoring{ + class Dsatur : public GraphColor { + public: + Dsatur(map > input_graph) :GraphColor(input_graph) { + //algorithm = kDSATUR; + } + map color(); + string get_algorithm_string() { return "DSATUR"; } + }; +} + +#endif \ No newline at end of file diff --git a/Header/graph.h b/Header/graph.h deleted file mode 100755 index dc29363..0000000 --- a/Header/graph.h +++ /dev/null @@ -1,97 +0,0 @@ - -#ifndef _GRAPH_H_ -#define _GRAPH_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -using std::queue; -using std::map; -using std::pair; -using std::stack; -using std::string; -using std::vector; -using std::cout; -using std::cerr; -using std::endl; - -namespace GraphColoring { - enum Algorithm {kNone,kDSATUR,kMCS,kHybrid,kLMXRLF,kHybridDSATUR}; - class Graph { - private: - Algorithm algorithm; - map > graph; - map coloring; - bool colored; - - /* Helper Functions */ - /* Parsing Helper Functions */ - vector< vector > get_input(char* input_file); - vector split(string to_split); - - /* Coloring algorithms */ - void dsatur(); - void mcs(); - void hybrid(int CARR);//TODO: Default? - void hybrid_dsatur(); - void lmxrlf(int endcond);//TODO: Default? - void lmxrlf_base(int endcond);//TODO: Default? - void tabucol(int k); //TODO: Default? - /* LMXRLF Helper functions */ - int objf(vector set); - vector make_independent_set(); - vector get_independent(vector set); - int min_objf(vector< vector > list_of_best); - int max_objf(vector< vector > list_of_best); - int min_pos_objf(vector< vector > list_of_best); - int max_pos_objf(vector< vector > list_of_best); - vector uncolored_neighbor(vector new_set); - /* TabuCol helper functions */ - int f(map coloring); - /* Hybrid helper functions */ - map< string,vector > get_subgraph(map< string,int > coloring); - /* Writing helper function */ - string get_color_string(int color,int max_color); - int find_max_color(); - public: - //Default coloring algorithm is DSATUR - Graph():colored(false){ algorithm = kDSATUR; } - explicit Graph(Algorithm new_algorithm) { algorithm = new_algorithm; } - explicit Graph(string new_algorithm); - - /* Mutators */ - void add_edge(string source,string sink); - void add_node(string new_node) { graph.insert(pair >(new_node,vector())); } - void set_algorithm(Algorithm new_algorithm) { algorithm = new_algorithm; } - - /* Coloring functions */ - map color(int condition = 0); - bool verify(); - /* Parsing functions */ - void parse_edge_list(char* input_file); - void parse_edge_matrix(char* input_file); - - /* Accessors */ - unsigned size() { return graph.size(); } - Algorithm get_algorithm() { return algorithm; } - map get_coloring() { return coloring; } - string get_algorithm_string(); - - /* Mutators */ - void set_graph(map > new_graph) { graph = new_graph; } - void set_coloring(map new_coloring) { coloring = new_coloring; } - - /* Print functions */ - void print_coloring(); - void print_chromatic(); - void write_graph(string graph_name = ""); - }; -} - -#endif // _GRAPH_H_ diff --git a/Header/graph_color.h b/Header/graph_color.h index a84cb63..e023a83 100644 --- a/Header/graph_color.h +++ b/Header/graph_color.h @@ -21,43 +21,33 @@ using std::cerr; using std::endl; namespace GraphColoring { - enum Algorithm {kNone,kDSATUR,kMCS,kTABUCOL,kHybrid,kLMXRLF,kHybridDSATUR}; class GraphColor { protected: - Algorithm algorithm; map > graph; map coloring; bool colored; /* Helper Functions */ - /* Parsing Helper Functions */ - vector< vector > get_input(char* input_file); - vector split(string to_split); - /* Writing helper function */ string get_color_string(int color,int max_color); int find_max_color(); public: //Default coloring algorithm is DSATUR - GraphColor():colored(false){ algorithm = kNone; } + GraphColor(map > input_graph):colored(false){ + graph = input_graph; + } /* Mutators */ - void add_edge(string source,string sink); - void add_node(string new_node) { graph.insert(pair >(new_node,vector())); } - void set_algorithm(Algorithm new_algorithm) { algorithm = new_algorithm; } + virtual void set_condition(int con) {} /* Coloring functions */ - virtual map color(int condition = 0) = 0; + virtual map color() = 0; bool verify(); - /* Parsing functions */ - void parse_edge_list(char* input_file); - void parse_edge_matrix(char* input_file); /* Accessors */ unsigned size() { return graph.size(); } - Algorithm get_algorithm() { return algorithm; } map get_coloring() { return coloring; } - string get_algorithm_string(); + virtual string get_algorithm_string() = 0; /* Mutators */ void set_graph(map > new_graph) { graph = new_graph; } @@ -70,4 +60,4 @@ namespace GraphColoring { }; } -#endif // _GRAPH_COLOR_H_ +#endif // _GRAPH_COLOR_H_ \ No newline at end of file diff --git a/Header/hybrid.h b/Header/hybrid.h new file mode 100644 index 0000000..a3a35aa --- /dev/null +++ b/Header/hybrid.h @@ -0,0 +1,28 @@ +#ifndef _HYBRID_H_ +#define _HYBRID_H_ + +#include "graph_color.h" +#include "lmxrlf.h" +#include "tabucol.h" + +using GraphColoring::GraphColor; +using GraphColoring::Lmxrlf; +using GraphColoring::Tabucol; + +namespace GraphColoring{ + class Hybrid : public GraphColor { + private: + int condition; + map< string,vector > get_subgraph(map< string,int > coloring); + public: + Hybrid(map > input_graph) :GraphColor(input_graph) { } + Hybrid(map > input_graph, int con) :GraphColor(input_graph){ + condition = con; + } + map color(); + string get_algorithm_string() { return "HYBRID"; } + void set_condition(int con) { condition = con; } + }; +} + +#endif \ No newline at end of file diff --git a/Header/hybrid_dsatur.h b/Header/hybrid_dsatur.h new file mode 100644 index 0000000..ce7cc0b --- /dev/null +++ b/Header/hybrid_dsatur.h @@ -0,0 +1,21 @@ +#ifndef _HYBRID_DSATUR_H_ +#define _HYBRID_DSATUR_H_ + +#include "graph_color.h" +#include "dsatur.h" +#include "tabucol.h" + +using GraphColoring::GraphColor; +using GraphColoring::Dsatur; +using GraphColoring::Tabucol; + +namespace GraphColoring{ + class HybridDsatur : public GraphColor { + public: + HybridDsatur(map > input_graph) :GraphColor(input_graph) { } + map color(); + string get_algorithm_string() { return "HYBRIDDSATUR"; } + }; +} + +#endif \ No newline at end of file diff --git a/Header/my_lmxrlf.h b/Header/lmxrlf.h similarity index 61% rename from Header/my_lmxrlf.h rename to Header/lmxrlf.h index add3511..7151528 100644 --- a/Header/my_lmxrlf.h +++ b/Header/lmxrlf.h @@ -1,15 +1,15 @@ -#ifndef _MY_LMXRLF_H_ -#define _MY_LMXRLF_H_ +#ifndef _LMXRLF_H_ +#define _LMXRLF_H_ #include "graph_color.h" using GraphColoring::GraphColor; -using GraphColoring::Algorithm; namespace GraphColoring{ - class lmxrlf : public GraphColor { + class Lmxrlf : public GraphColor { private: //helper functions + int condition; vector get_independent(vector set); vector make_independent_set(); int objf(vector set); @@ -20,8 +20,13 @@ namespace GraphColoring{ vector uncolored_neighbor(vector new_set); map lmxrlf_alg(int endcond); public: - lmxrlf() :GraphColor() { algorithm = kLMXRLF; } - map color(int condition = 0); + Lmxrlf(map > input_graph) :GraphColor(input_graph) { } + Lmxrlf(map > input_graph, int con) :GraphColor(input_graph){ + condition = con; + } + map color(); + string get_algorithm_string() { return "LMXRLF"; } + void set_condition(int con) { condition = con; } }; } diff --git a/Header/mcs.h b/Header/mcs.h new file mode 100644 index 0000000..1cd5fa8 --- /dev/null +++ b/Header/mcs.h @@ -0,0 +1,17 @@ +#ifndef _MCS_H_ +#define _MCS_H_ + +#include "graph_color.h" + +using GraphColoring::GraphColor; + +namespace GraphColoring{ + class Mcs : public GraphColor { + public: + Mcs(map > input_graph) :GraphColor(input_graph) { } + map color(); + string get_algorithm_string() { return "MCS"; } + }; +} + +#endif \ No newline at end of file diff --git a/Header/my_dsatur.h b/Header/my_dsatur.h deleted file mode 100644 index ecbafc0..0000000 --- a/Header/my_dsatur.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _MY_DSATUR_H_ -#define _MY_DSATUR_H_ - -#include "graph_color.h" - -using GraphColoring::GraphColor; -using GraphColoring::Algorithm; - -namespace GraphColoring{ - class dsatur : public GraphColor { - public: - dsatur() :GraphColor() { algorithm = kDSATUR; } - map color(int condition = 0); - }; -} - -#endif \ No newline at end of file diff --git a/Header/my_hybrid.h b/Header/my_hybrid.h deleted file mode 100644 index 3be517f..0000000 --- a/Header/my_hybrid.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _MY_HYBRID_H_ -#define _MY_HYBRID_H_ - -#include "graph_color.h" -#include "my_lmxrlf.h" -#include "my_tabucol.h" - -using GraphColoring::Algorithm; -using GraphColoring::GraphColor; -using GraphColoring::lmxrlf; -using GraphColoring::tabucol; - -namespace GraphColoring{ - class hybrid : public GraphColor { - private: - map< string,vector > get_subgraph(map< string,int > coloring); - public: - hybrid() :GraphColor() { algorithm = kHybrid; } - map color(int condition = 0); - }; -} - -#endif \ No newline at end of file diff --git a/Header/my_hybrid_dsatur.h b/Header/my_hybrid_dsatur.h deleted file mode 100644 index 8359fc5..0000000 --- a/Header/my_hybrid_dsatur.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _MY_HYBRID_DSATUR_H_ -#define _MY_HYBRID_DSATUR_H_ - -#include "graph_color.h" -#include "my_dsatur.h" -#include "my_tabucol.h" - -using GraphColoring::Algorithm; -using GraphColoring::GraphColor; -using GraphColoring::dsatur; -using GraphColoring::tabucol; - -namespace GraphColoring{ - class hybrid_dsatur : public GraphColor { - public: - hybrid_dsatur() :GraphColor() { algorithm = kHybridDSATUR; } - map color(int condition = 0); - }; -} - -#endif \ No newline at end of file diff --git a/Header/my_mcs.h b/Header/my_mcs.h deleted file mode 100644 index b96febc..0000000 --- a/Header/my_mcs.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _MY_MCS_H_ -#define _MY_MCS_H_ - -#include "graph_color.h" - -using GraphColoring::GraphColor; -using GraphColoring::Algorithm; - -namespace GraphColoring{ - class mcs : public GraphColor { - public: - mcs() :GraphColor() { algorithm = kMCS; } - map color(int condition = 0); - }; -} - -#endif \ No newline at end of file diff --git a/Header/my_tabucol.h b/Header/my_tabucol.h deleted file mode 100644 index e32e435..0000000 --- a/Header/my_tabucol.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _MY_TABUCOL_H_ -#define _MY_TABUCOL_H_ - -#include "graph_color.h" - -using GraphColoring::GraphColor; -using GraphColoring::Algorithm; - -namespace GraphColoring{ - class tabucol : public GraphColor { - private: - int f(map coloring); - public: - tabucol() :GraphColor() { algorithm = kTABUCOL; } - map color(int condition = 0); - }; -} - -#endif \ No newline at end of file diff --git a/Header/tabucol.h b/Header/tabucol.h new file mode 100644 index 0000000..f3439d0 --- /dev/null +++ b/Header/tabucol.h @@ -0,0 +1,24 @@ +#ifndef _TABUCOL_H_ +#define _TABUCOL_H_ + +#include "graph_color.h" + +using GraphColoring::GraphColor; + +namespace GraphColoring{ + class Tabucol : public GraphColor { + private: + int f(map coloring); + int condition; + public: + Tabucol(map > input_graph) :GraphColor(input_graph) { } + Tabucol(map > input_graph, int con) :GraphColor(input_graph){ + condition = con; + } + map color(); + string get_algorithm_string() { return "TABUCOL"; } + void set_condition(int con) { condition = con; } + }; +} + +#endif \ No newline at end of file diff --git a/Makefile b/Makefile index a5dd7d2..0d043ad 100755 --- a/Makefile +++ b/Makefile @@ -9,12 +9,12 @@ SHELL=/bin/sh PRG=graphColoring DOT=*.dot OBJS=graph_color.o\ - my_dsatur.o\ - my_mcs.o\ - my_lmxrlf.o\ - my_tabucol.o\ - my_hybrid_dsatur.o\ - my_hybrid.o\ + dsatur.o\ + mcs.o\ + lmxrlf.o\ + tabucol.o\ + hybrid_dsatur.o\ + hybrid.o\ main.o CXXFLAGS=-Wall diff --git a/Source/dsatur.cpp b/Source/dsatur.cpp old mode 100755 new mode 100644 index 114ada5..d469475 --- a/Source/dsatur.cpp +++ b/Source/dsatur.cpp @@ -1,9 +1,6 @@ -#ifndef _DSATUR_H_ -#define _DSATUR_H_ +#include "../Header/dsatur.h" -#include "../Header/graph.h" - -void GraphColoring::Graph::dsatur() { +map GraphColoring::Dsatur::color() { vector todo; string max_degree = ""; @@ -85,7 +82,8 @@ void GraphColoring::Graph::dsatur() { if(saturation_name == "") { cerr << "Error: Could not find a max saturated node in the graph (reason unknown)" << endl; - return; + coloring.clear(); + return coloring; } //We now know the most saturated node, so we remove it from the todo list @@ -123,6 +121,5 @@ void GraphColoring::Graph::dsatur() { } saturation_level[saturation_name] = std::numeric_limits::min(); } + return coloring; } - -#endif // _DSATUR_H_ diff --git a/Source/graph.cpp b/Source/graph.cpp deleted file mode 100755 index 393fb4e..0000000 --- a/Source/graph.cpp +++ /dev/null @@ -1,345 +0,0 @@ - -#include "../Header/graph.h" -#include -#include -#include -//TODO: Change atoi, remove this header -#include - -using std::cerr; -using std::endl; -using std::ifstream; -using std::ofstream; -using std::ostringstream; - -ifstream& Getline(ifstream& ifs,string& line) { - getline(ifs,line); - if (!line.empty()) { - while (isspace(line.at(line.size()-1))) { - line = line.substr(0,line.size()-1); - } - } - return ifs; -} - -//TODO: What conditions are needed for each algorithm? -map GraphColoring::Graph::color(int condition) { - switch(algorithm) { - case kDSATUR: - dsatur(); - break; - case kMCS: - mcs(); - break; - case kLMXRLF: - if (condition == 0) { - condition = graph.size(); - } - lmxrlf_base(condition); - break; - case kHybrid: - if (condition == 0) { - condition = graph.size() / 2; - } - hybrid(condition); - break; - case kHybridDSATUR: - hybrid_dsatur(); - break; - default: - cerr << "Warning: No algorithm selected. Continuing with DSATUR." << endl; - dsatur(); - break; - } - colored = true; - return coloring; -} - -string GraphColoring::Graph::get_algorithm_string() { - switch (algorithm) { - case kDSATUR: - return "DSATUR"; - case kMCS: - return "MCS"; - case kLMXRLF: - return "LMXRLF"; - case kHybrid: - return "Hybrid"; - case kHybridDSATUR: - return "HybridDSATUR"; - case kNone: - default: - return "None"; - } -} - -GraphColoring::Graph::Graph(string new_algorithm) { - if (new_algorithm.compare("DSATUR")) { - algorithm = kDSATUR; - } else { - algorithm = kDSATUR; - } -} - -vector GraphColoring::Graph::split(string to_split) { - vector split_string; - unsigned index_start; - for (unsigned i = 0;i < to_split.length();i++) { - index_start = i; - while(i < to_split.length() && !isspace(to_split.at(i))) { i++; } - split_string.push_back(to_split.substr(index_start,i - index_start)); - } - return split_string; -} - -void GraphColoring::Graph::parse_edge_list(char* input_file) { - ifstream file(input_file); - if(file.is_open()) { - string line; - int vertices = -1; - int flag = 0; - while(!flag && Getline(file,line)) { - while(line.size() == 0) { - Getline(file,line); - } - vector words = GraphColoring::Graph::split(line); - if(words.size() != 0) { - if(words[0] == "p") { - vertices = atoi(words[2].c_str()); - flag = 1; - } - } - } - if(!flag || vertices == -3) { - cerr << "File is missing parameter line before edge list" << endl; - cerr << "Should be: \"p edge \"" << endl; - return; - } - for(int i=0; i base; - graph[pre] = base; - } - while(Getline(file,line)) - { - vector words = GraphColoring::Graph::split(line); - if(words[0] == "e") - { - string arg1 = "v"; - arg1.append(words[1]); - string arg2 = "v"; - arg2.append(words[2]); - vector base; - vector base2; - graph[arg1].push_back(arg2); - graph[arg2].push_back(arg1); - } - } - } else { - cerr << "Input File Not Found" << endl; - return; - } -} - -//Used to parse test inputs where the first line is the number of -//vertices, and the next lines are the edge matrix -void GraphColoring::Graph::parse_edge_matrix(char* input_file) { - string pre = "v"; - - ifstream file(input_file); - if(file.is_open()) { - string line; - Getline(file,line); - int n = atoi(line.c_str()); - int i = 0; - while(Getline(file,line)) { - i += 1; - vector words = GraphColoring::Graph::split(line); - if((int)words.size() != n) { - cerr << "Invalid Input, line " << i << " is not the correct length (" - << words.size() << "," << n << "): " << line << endl; - for (unsigned i = 0;i < words.size();i++) { cerr << "\t" << words.at(i) << endl; } - graph.clear(); - return; - } - vector edges; - for(int j = 0; j < n; j++) { - if(words[j] == "1") { - pre = "v"; - string temp; - ostringstream convert; - convert << (j+1); - temp = convert.str(); - edges.push_back(pre.append(temp)); - } - } - pre = "v"; - string temp; - ostringstream convert; - convert << i; - temp = convert.str(); - graph[pre.append(temp)] = edges; - } - if(i != n) { - cerr << "Input is not the right length" << endl; - graph.clear(); - return; - } - file.close(); - } else { - cerr << "Input File Not Found" << endl; - return; - } - return; -} - -vector< vector > GraphColoring::Graph::get_input(char* input_file) { - vector< vector > Input; - - ifstream file(input_file); - if(file.is_open()) { - string line; - while(Getline(file,line)) { - vector words = GraphColoring::Graph::split(line); - if(words.size() > 1) { - for(unsigned i=1; i >::iterator i = graph.begin(); i != graph.end(); i++) - { - for(unsigned j=0; j<(*i).second.size(); j++) - { - if(coloring[(*i).first] == coloring[(*i).second[j]]) - { - cerr << "Graph is not colored correctly" << endl; - return false; - } - } - } - cerr << "Graph is colored correctly" << endl; - return true; -} - -//Used to print the Chromatic Color -void GraphColoring::Graph::print_chromatic() { - int largest = 0; - for(map< string, int >::iterator i = coloring.begin(); i != coloring.end(); i++) - { - if((*i).second > largest) - { - largest = (*i).second; - } - } - - std::cout << get_algorithm_string() << " Chromatic Number: " << largest+1 << endl; -} - -//Used to print the color of each node in the graph -void GraphColoring::Graph::print_coloring() { - std::cout << "----------" << algorithm << " Colorings----------" << endl; - for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { - std::cout << (*i).first << " " << (*i).second << endl; - } -} - -void GraphColoring::Graph::add_edge(string source,string sink) { - map >::iterator source_node; - map >::iterator sink_node; - // Find each node. find will insert the node if it does not exist in the - // graph - source_node = graph.insert(pair >(source,vector())).first; - sink_node = graph.insert(pair >(sink,vector())).first; - // Add the opposite node to the edge list for each node - (*source_node).second.push_back(sink); - (*sink_node).second.push_back(source); -} - -int GraphColoring::Graph::find_max_color() { - map::iterator color_it = coloring.begin(); - int max_color = 0; - for (/*color_it*/;color_it != coloring.end();color_it++) { - if ((*color_it).second > max_color) { - max_color = (*color_it).second; - } - } - return max_color; -} - -#include "../Header/graph_colors.h" - -string GraphColoring::Graph::get_color_string(int color,int max_color) { - return ColorArray[color]; - const int MaxColor = 1023; - color = color * (MaxColor / max_color); - std::stringstream color_changer; - color_changer << "0x" << std::hex << color; - return color_changer.str(); -} - -void GraphColoring::Graph::write_graph(string graph_name) { - int max_color = find_max_color(); - if(max_color > COLOR_ARRAY_SIZE) - { - cerr << "Error: Graph has too many colors to be written" << endl; - return; - } - if (graph_name.empty()) { - graph_name = "colored_graph"; - } - string filename = graph_name+".dot"; - ofstream outfile(filename.c_str()); - if (!outfile.is_open()) { - cerr << "Error: Unable to open \"" << filename << "\"." << endl; - return; - } - outfile << "graph " << graph_name << " {\n"; - map >::iterator graph_it; - graph_it = graph.begin(); - for (/*graph_it*/;graph_it != graph.end();graph_it++) { - outfile << (*graph_it).first << "[label=\"" << (*graph_it).first << "\\n" - << coloring.at((*graph_it).first) << "\""; - if (colored) { - outfile << " style=filled fillcolor=\""; - outfile << get_color_string(coloring.at((*graph_it).first),max_color); - outfile << "\""; - } - outfile << "];\n"; - } - graph_it = graph.begin(); - for (/*graph_it*/;graph_it != graph.end();graph_it++) { - string start_node = (*graph_it).first; - vector connections = (*graph_it).second; - for (unsigned i = 0;i < connections.size();i++) { - if (connections.at(i) < start_node) { - outfile << start_node << " -- " << connections.at(i) << endl; - } - } - } - outfile << "}" << endl; - outfile.close(); -} diff --git a/Source/graph_color.cpp b/Source/graph_color.cpp index a3ab3bc..9b1736f 100644 --- a/Source/graph_color.cpp +++ b/Source/graph_color.cpp @@ -12,194 +12,12 @@ using std::ifstream; using std::ofstream; using std::ostringstream; -ifstream& Getline(ifstream& ifs,string& line) { - getline(ifs,line); - if (!line.empty()) { - while (isspace(line.at(line.size()-1))) { - line = line.substr(0,line.size()-1); - } - } - return ifs; -} - -string GraphColoring::GraphColor::get_algorithm_string() { - switch (algorithm) { - case kDSATUR: - return "DSATUR"; - break; - case kMCS: - return "MCS"; - break; - case kLMXRLF: - return "LMXRLF"; - break; - case kHybrid: - return "Hybrid"; - break; - case kHybridDSATUR: - return "HybridDSATUR"; - break; - case kNone: - break; - default: - break; - } - return "None"; -} - //TODO: What conditions are needed for each algorithm? -map GraphColoring::GraphColor::color(int condition) { +map GraphColoring::GraphColor::color() { return coloring; } -vector GraphColoring::GraphColor::split(string to_split) { - vector split_string; - unsigned index_start; - for (unsigned i = 0;i < to_split.length();i++) { - index_start = i; - while(i < to_split.length() && !isspace(to_split.at(i))) { i++; } - split_string.push_back(to_split.substr(index_start,i - index_start)); - } - return split_string; -} - -void GraphColoring::GraphColor::parse_edge_list(char* input_file) { - ifstream file(input_file); - if(file.is_open()) { - string line; - int vertices = -1; - int flag = 0; - while(!flag && Getline(file,line)) { - while(line.size() == 0) { - Getline(file,line); - } - vector words = GraphColoring::GraphColor::split(line); - if(words.size() != 0) { - if(words[0] == "p") { - vertices = atoi(words[2].c_str()); - flag = 1; - } - } - } - if(!flag || vertices == -3) { - cerr << "File is missing parameter line before edge list" << endl; - cerr << "Should be: \"p edge \"" << endl; - return; - } - for(int i=0; i base; - graph[pre] = base; - } - while(Getline(file,line)) - { - vector words = GraphColoring::GraphColor::split(line); - if(words[0] == "e") - { - string arg1 = "v"; - arg1.append(words[1]); - string arg2 = "v"; - arg2.append(words[2]); - vector base; - vector base2; - graph[arg1].push_back(arg2); - graph[arg2].push_back(arg1); - } - } - } else { - cerr << "Input File Not Found" << endl; - return; - } -} - -//Used to parse test inputs where the first line is the number of -//vertices, and the next lines are the edge matrix -void GraphColoring::GraphColor::parse_edge_matrix(char* input_file) { - string pre = "v"; - - ifstream file(input_file); - if(file.is_open()) { - string line; - Getline(file,line); - int n = atoi(line.c_str()); - int i = 0; - while(Getline(file,line)) { - i += 1; - vector words = GraphColoring::GraphColor::split(line); - if((int)words.size() != n) { - cerr << "Invalid Input, line " << i << " is not the correct length (" - << words.size() << "," << n << "): " << line << endl; - for (unsigned i = 0;i < words.size();i++) { cerr << "\t" << words.at(i) << endl; } - graph.clear(); - return; - } - vector edges; - for(int j = 0; j < n; j++) { - if(words[j] == "1") { - pre = "v"; - string temp; - ostringstream convert; - convert << (j+1); - temp = convert.str(); - edges.push_back(pre.append(temp)); - } - } - pre = "v"; - string temp; - ostringstream convert; - convert << i; - temp = convert.str(); - graph[pre.append(temp)] = edges; - } - if(i != n) { - cerr << "Input is not the right length" << endl; - graph.clear(); - return; - } - file.close(); - } else { - cerr << "Input File Not Found" << endl; - return; - } - return; -} - -vector< vector > GraphColoring::GraphColor::get_input(char* input_file) { - vector< vector > Input; - - ifstream file(input_file); - if(file.is_open()) { - string line; - while(Getline(file,line)) { - vector words = GraphColoring::GraphColor::split(line); - if(words.size() > 1) { - for(unsigned i=1; i >::iterator i = graph.begin(); i != graph.end(); i++) @@ -228,29 +46,17 @@ void GraphColoring::GraphColor::print_chromatic() { } } - std::cout << get_algorithm_string() << " Chromatic Number: " << largest+1 << endl; + //std::cout << get_algorithm_string() << " Chromatic Number: " << largest+1 << endl; } //Used to print the color of each node in the graph void GraphColoring::GraphColor::print_coloring() { - std::cout << "----------" << algorithm << " Colorings----------" << endl; + //std::cout << "----------" << get_algorithm_string() << " Colorings----------" << endl; for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { std::cout << (*i).first << " " << (*i).second << endl; } } -void GraphColoring::GraphColor::add_edge(string source,string sink) { - map >::iterator source_node; - map >::iterator sink_node; - // Find each node. find will insert the node if it does not exist in the - // graph - source_node = graph.insert(pair >(source,vector())).first; - sink_node = graph.insert(pair >(sink,vector())).first; - // Add the opposite node to the edge list for each node - (*source_node).second.push_back(sink); - (*sink_node).second.push_back(source); -} - int GraphColoring::GraphColor::find_max_color() { map::iterator color_it = coloring.begin(); int max_color = 0; diff --git a/Source/hybrid.cpp b/Source/hybrid.cpp old mode 100755 new mode 100644 index 3a4eb5e..c0681bf --- a/Source/hybrid.cpp +++ b/Source/hybrid.cpp @@ -1,7 +1,12 @@ -#include "../Header/graph.h" +#include "../Header/hybrid.h" -void GraphColoring::Graph::hybrid(int CARR) { - lmxrlf_base(CARR); +map GraphColoring::Hybrid::color() { + if (this->condition == 0) { + this->condition = graph.size() / 2; + } + + GraphColor *alg_graph = new Lmxrlf(this->graph, this->condition); + coloring = alg_graph->color(); //coloring = lmxrlf_base(Graph,CARR); //********************************* @@ -18,42 +23,47 @@ void GraphColoring::Graph::hybrid(int CARR) { map< string,int > Colors_temp = coloring; //coloring = lmxrlf(graph.size()); - lmxrlf(graph.size()); + alg_graph->set_condition(graph.size()); + coloring = alg_graph->color(); int Color = 0; for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { if((*i).second > Color) { Color = (*i).second; } } + delete alg_graph; //****************************************************** //***** Run Remainder through Tabucol and Recolor ***** //****************************************************** int subset_color = Color; - Graph subset("tabucol"); - subset.set_graph(get_subgraph(Colors_temp)); - subset.set_coloring(Colors_temp); - subset.color(subset_color); - map tabu_color = subset.get_coloring(); + alg_graph = new Tabucol(get_subgraph(Colors_temp)); + alg_graph->set_coloring(Colors_temp); + alg_graph->set_condition(subset_color); + alg_graph->color(); + map tabu_color = alg_graph->get_coloring(); + //map< string,vector > Graph_subset = get_subgraph(Colors_temp); //map< string,int > tabu_color = tabucol(Graph_subset,subset_color); map< string,int > best; while(tabu_color.size() > 0) { best = tabu_color; subset_color -= 1; + alg_graph->set_condition(subset_color); //tabu_color = tabucol(Graph_subset,subset_color); - subset.color(subset_color); - tabu_color = subset.get_coloring(); + alg_graph->set_coloring(alg_graph->color()); + tabu_color = alg_graph->get_coloring(); } if(best.size() > 0) { for(map< string,int >::iterator i = best.begin(); i != best.end(); i++) { coloring[(*i).first] = Color_temp + (*i).second; } } + return coloring; } -map< string,vector > GraphColoring::Graph::get_subgraph(map< string,int > coloring) { +map< string,vector > GraphColoring::Hybrid::get_subgraph(map< string,int > coloring) { map< string,vector > subgraph; for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { if(coloring[(*i).first] == -1) { @@ -67,29 +77,3 @@ map< string,vector > GraphColoring::Graph::get_subgraph(map< string,int } return subgraph; } - - -//Starts by using DSATUR to get an approximate coloring and then uses decrementing -//tabucol runs to try and reduce the chromatic number -void GraphColoring::Graph::hybrid_dsatur() { - dsatur(); - - int largest = 0; - for(map< string, int >::iterator i = coloring.begin(); i != coloring.end(); i++) - { - if((*i).second > largest) { largest = (*i).second; } - } - largest += 1; - - map< string,int > best = coloring; - tabucol(largest); - map< string,int > tabu_color = coloring; - while(tabu_color.size() > 0) - { - best = tabu_color; - largest -= 1; - tabucol(largest); - tabu_color = coloring; - } - coloring = best; -} diff --git a/Source/my_hybrid_dsatur.cpp b/Source/hybrid_dsatur.cpp similarity index 53% rename from Source/my_hybrid_dsatur.cpp rename to Source/hybrid_dsatur.cpp index bc05f90..7502588 100644 --- a/Source/my_hybrid_dsatur.cpp +++ b/Source/hybrid_dsatur.cpp @@ -1,8 +1,7 @@ -#include "../Header/my_hybrid_dsatur.h" +#include "../Header/hybrid_dsatur.h" -map GraphColoring::hybrid_dsatur::color(int condition) { - GraphColor *temp_graph = new dsatur(); - temp_graph->set_graph(this->graph); +map GraphColoring::HybridDsatur::color() { + GraphColor *temp_graph = new Dsatur(this->graph); coloring = temp_graph->color(); delete temp_graph; @@ -13,16 +12,16 @@ map GraphColoring::hybrid_dsatur::color(int condition) { } largest += 1; - temp_graph = new tabucol(); - temp_graph->set_graph(this->graph); + temp_graph = new Tabucol(this->graph, largest); map< string,int > best = coloring; - map< string,int > tabu_color = temp_graph->color(largest); + map< string,int > tabu_color = temp_graph->color(); while(tabu_color.size() > 0) { best = tabu_color; largest -= 1; - tabu_color = temp_graph->color(largest); + temp_graph->set_condition(largest); + tabu_color = temp_graph->color(); } coloring = best; delete temp_graph; diff --git a/Source/lmxrlf.cpp b/Source/lmxrlf.cpp old mode 100755 new mode 100644 index f8d0979..f92c206 --- a/Source/lmxrlf.cpp +++ b/Source/lmxrlf.cpp @@ -1,5 +1,5 @@ -#include "../Header/graph.h" +#include "../Header/lmxrlf.h" #include #include @@ -12,7 +12,7 @@ int F = 1; int LOCAL = 10; //Returns an independent set from given set -vector GraphColoring::Graph::get_independent(vector set) { +vector GraphColoring::Lmxrlf::get_independent(vector set) { vector delta; for(unsigned i=0; i GraphColoring::Graph::get_independent(vector set) { } //Creates an independent set from the graph -vector GraphColoring::Graph::make_independent_set() { +vector GraphColoring::Lmxrlf::make_independent_set() { vector set; vector todo = get_independent(set); while(todo.size()) { @@ -45,7 +45,7 @@ vector GraphColoring::Graph::make_independent_set() { } //Objective function for LMXRLF -int GraphColoring::Graph::objf(vector set) { +int GraphColoring::Lmxrlf::objf(vector set) { int sum = 0; for(unsigned i=0; i set) { } //Returns the value from the list of best solutions with the minimum objective function -int GraphColoring::Graph::min_objf(vector< vector > list_of_best) { +int GraphColoring::Lmxrlf::min_objf(vector< vector > list_of_best) { if(list_of_best.size() == 0) { cerr << "List of Best Solutions is of size 0" << endl; return -1; @@ -77,7 +77,7 @@ int GraphColoring::Graph::min_objf(vector< vector > list_of_best) { } //Returns the value from the list of best solutions with the maximum objective function -int GraphColoring::Graph::max_objf(vector< vector > list_of_best) { +int GraphColoring::Lmxrlf::max_objf(vector< vector > list_of_best) { if(list_of_best.size() == 0) { cerr << "List of Best Solutions is of size 0" << endl; return -1; @@ -93,7 +93,7 @@ int GraphColoring::Graph::max_objf(vector< vector > list_of_best) { } //Returns the index from the list of best solutions with the minimum objective function -int GraphColoring::Graph::min_pos_objf(vector< vector > list_of_best) { +int GraphColoring::Lmxrlf::min_pos_objf(vector< vector > list_of_best) { if(list_of_best.size() == 0) { cerr << "List of Best Solutions is of size 0" << endl; return -1; @@ -111,7 +111,7 @@ int GraphColoring::Graph::min_pos_objf(vector< vector > list_of_best) { } //Returns the index from the list of best solutions with the maximum objective function -int GraphColoring::Graph::max_pos_objf(vector< vector > list_of_best) { +int GraphColoring::Lmxrlf::max_pos_objf(vector< vector > list_of_best) { if(list_of_best.size() == 0) { cerr << "List of Best Solutions is of size 0" << endl; return -1; @@ -129,7 +129,7 @@ int GraphColoring::Graph::max_pos_objf(vector< vector > list_of_best) { } //Returns a set of uncolored neighbors from the input set -vector GraphColoring::Graph::uncolored_neighbor(vector new_set) { +vector GraphColoring::Lmxrlf::uncolored_neighbor(vector new_set) { vector delta; for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { int flag = 0; @@ -167,7 +167,7 @@ vector GraphColoring::Graph::uncolored_neighbor(vector new_set) return out; } -void GraphColoring::Graph::lmxrlf(int endcond) { +map GraphColoring::Lmxrlf::lmxrlf_alg(int endcond) { map< string, vector > Graph_temp; vector< vector > list_of_best_solutions; srand(time(NULL)); @@ -255,13 +255,15 @@ void GraphColoring::Graph::lmxrlf(int endcond) { } Color += 1; } while(colored_nodes < endcond-1); + return coloring; } //Runs LMXRLF starting with a fully uncolored graph -void GraphColoring::Graph::lmxrlf_base(int endcond) { +map GraphColoring::Lmxrlf::color() { + if (this->condition == 0) { this->condition = graph.size(); } for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { coloring[(*i).first] = -1; } - return lmxrlf(endcond); + return lmxrlf_alg(this->condition); } diff --git a/Source/main.cpp b/Source/main.cpp index 291684a..4dbe79a 100755 --- a/Source/main.cpp +++ b/Source/main.cpp @@ -1,21 +1,33 @@ #include "../Header/graph_color.h" -#include "../Header/my_dsatur.h" -#include "../Header/my_mcs.h" -#include "../Header/my_lmxrlf.h" -#include "../Header/my_hybrid_dsatur.h" -#include "../Header/my_hybrid.h" +#include "../Header/dsatur.h" +#include "../Header/mcs.h" +#include "../Header/lmxrlf.h" +#include "../Header/hybrid_dsatur.h" +#include "../Header/hybrid.h" +#include #include +#include using std::cerr; using std::cout; using std::endl; -using GraphColoring::dsatur; -using GraphColoring::mcs; -using GraphColoring::lmxrlf; -using GraphColoring::hybrid_dsatur; -using GraphColoring::hybrid; +using std::ifstream; +using std::ofstream; +using std::ostringstream; +using GraphColoring::Dsatur; +using GraphColoring::Mcs; +using GraphColoring::Lmxrlf; +using GraphColoring::HybridDsatur; +using GraphColoring::Hybrid; using GraphColoring::GraphColor; -using GraphColoring::Algorithm; + +//functions used to graphs test cases to map +vector split(string to_split); +vector< vector > get_input(char* input_file); +void parse_edge_list(char* input_file); +void parse_edge_matrix(char* input_file); + +map > input_graph; int main(int argc, char** argv) { @@ -23,23 +35,181 @@ int main(int argc, char** argv) cerr << "Usage: " << argv[0] << " file_input" << endl; return -1; } - - GraphColor *graph = new dsatur(); if(argc >= 3 && string(argv[2]) == "-m") { - graph->parse_edge_matrix(argv[1]); - if(graph->size() == 0) { return -2; } + parse_edge_matrix(argv[1]); + if(input_graph.size() == 0) { return -2; } } else if(argc >= 3 && string(argv[2]) == "-l") { - graph->parse_edge_list(argv[1]); - if(graph->size() == 0) { return -2; } + parse_edge_list(argv[1]); + if(input_graph.size() == 0) { return -2; } } else { cout << "No Graph Input Type Selected" << endl; return -1; } + GraphColor *graph = new Hybrid(input_graph); + graph->color(); graph->print_chromatic(); - graph->verify(); - graph->write_graph(); + //graph->verify(); + //graph->write_graph(); return 0; } + +ifstream& Getline(ifstream& ifs,string& line) { + getline(ifs,line); + if (!line.empty()) { + while (isspace(line.at(line.size()-1))) { + line = line.substr(0,line.size()-1); + } + } + return ifs; +} + +vector split(string to_split) { + vector split_string; + unsigned index_start; + for (unsigned i = 0;i < to_split.length();i++) { + index_start = i; + while(i < to_split.length() && !isspace(to_split.at(i))) { i++; } + split_string.push_back(to_split.substr(index_start,i - index_start)); + } + return split_string; +} + +vector< vector > get_input(char* input_file) { + vector< vector > Input; + + ifstream file(input_file); + if(file.is_open()) { + string line; + while(Getline(file,line)) { + vector words = split(line); + if(words.size() > 1) { + for(unsigned i=1; i words = split(line); + if(words.size() != 0) { + if(words[0] == "p") { + vertices = atoi(words[2].c_str()); + flag = 1; + } + } + } + if(!flag || vertices == -3) { + cerr << "File is missing parameter line before edge list" << endl; + cerr << "Should be: \"p edge \"" << endl; + return; + } + for(int i=0; i base; + input_graph[pre] = base; + } + while(Getline(file,line)) + { + vector words = split(line); + if(words[0] == "e") + { + string arg1 = "v"; + arg1.append(words[1]); + string arg2 = "v"; + arg2.append(words[2]); + vector base; + vector base2; + input_graph[arg1].push_back(arg2); + input_graph[arg2].push_back(arg1); + } + } + } else { + cerr << "Input File Not Found" << endl; + return; + } +} + +//Used to parse test inputs where the first line is the number of +//vertices, and the next lines are the edge matrix +void parse_edge_matrix(char* input_file) { + string pre = "v"; + + ifstream file(input_file); + if(file.is_open()) { + string line; + Getline(file,line); + int n = atoi(line.c_str()); + int i = 0; + while(Getline(file,line)) { + i += 1; + vector words = split(line); + if((int)words.size() != n) { + cerr << "Invalid Input, line " << i << " is not the correct length (" + << words.size() << "," << n << "): " << line << endl; + for (unsigned i = 0;i < words.size();i++) { cerr << "\t" << words.at(i) << endl; } + input_graph.clear(); + return; + } + vector edges; + for(int j = 0; j < n; j++) { + if(words[j] == "1") { + pre = "v"; + string temp; + ostringstream convert; + convert << (j+1); + temp = convert.str(); + edges.push_back(pre.append(temp)); + } + } + pre = "v"; + string temp; + ostringstream convert; + convert << i; + temp = convert.str(); + input_graph[pre.append(temp)] = edges; + } + if(i != n) { + cerr << "Input is not the right length" << endl; + input_graph.clear(); + return; + } + file.close(); + } else { + cerr << "Input File Not Found" << endl; + return; + } + return; +} \ No newline at end of file diff --git a/Source/mcs.cpp b/Source/mcs.cpp old mode 100755 new mode 100644 index 7a533df..aa7ca34 --- a/Source/mcs.cpp +++ b/Source/mcs.cpp @@ -1,5 +1,5 @@ -#include "../Header/graph.h" +#include "../Header/mcs.h" #include // TODO: The following optimization can be made via a note in the paper @@ -12,7 +12,7 @@ // in O(1) time. //Maximum Cardinal Search -void GraphColoring::Graph::mcs() { +map GraphColoring::Mcs::color() { map > temp_graph = graph; map< string,int> weight; @@ -45,7 +45,8 @@ void GraphColoring::Graph::mcs() { if(max_vertex == "") { cerr << "Error: Could not find a max weight node in the graph (reason unknown)" << endl; - return; + coloring.clear(); + return coloring; } // Add highest weight node to the queue and increment all of its @@ -96,4 +97,5 @@ void GraphColoring::Graph::mcs() { coloring[min] = color; ordering.pop(); } + return coloring; } diff --git a/Source/my_dsatur.cpp b/Source/my_dsatur.cpp deleted file mode 100644 index 638d327..0000000 --- a/Source/my_dsatur.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "../Header/my_dsatur.h" - -map GraphColoring::dsatur::color(int condition) { - - vector todo; - string max_degree = ""; - int degree = -1; - - //find maximal degree vertex to color first and color with 0 - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) - { - if((int)(*i).second.size() > degree) { - degree = (*i).second.size(); - max_degree = (*i).first; - } - } - if(max_degree == "") - { - cerr << "Error: Could not find a max degree node in the graph (reason unknown)" << endl; - } - coloring[max_degree] = 0; - - //Create saturation_level so that we can see which graph nodes have the - //highest saturation without having to scan through the entire graph - //each time - map saturation_level; - - //Add all nodes and set their saturation level to 0 - for(map >::iterator i = graph.begin(); i != graph.end(); i++) - { - saturation_level[(*i).first] = 0; - } - - //For the single node that has been colored, increment its neighbors so - //that their current saturation level is correct - for(int i=0; i < graph[max_degree].size(); i++) - { - saturation_level[graph[max_degree][i]] += 1; - } - - //Set the saturation level of the already completed node to -infinity so - //that it is not chosen and recolored - saturation_level[max_degree] = std::numeric_limits::min(); - - //Populate the todo list with the rest of the vertices that need to be colored - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) - { - if((*i).first != max_degree) { - coloring[(*i).first] = -1; - todo.push_back((*i).first); - } - } - - //Color all the remaining nodes in the todo list - while(!todo.empty()) - { - int saturation = -1; - string saturation_name = ""; - vector saturation_colors; - //Find the vertex with the highest saturation level, since we keep the - //saturation levels along the way we can do this in a single pass - for(map::iterator i = saturation_level.begin(); i != saturation_level.end(); i++) - { - //Find the highest saturated node and keep its name and neighbors colors - if((*i).second > saturation) - { - saturation = (*i).second; - saturation_name = (*i).first; - - //Since we're in this loop it means we've found a new most saturated - //node, which means we need to clear the old list of neighbors colors - //and replace it with the new highest saturated nodes neighbors colors - //Since uncolored nodes are given a -1, we can add all neighbors and - //start the check for lowest available color at greater than 0 - saturation_colors.clear(); - for(int j=0; j < graph[(*i).first].size(); j++) - { - saturation_colors.push_back(coloring[graph[(*i).first][j]]); - } - } - } - if(saturation_name == "") - { - cerr << "Error: Could not find a max saturated node in the graph (reason unknown)" << endl; - coloring.clear(); - return coloring; - } - - //We now know the most saturated node, so we remove it from the todo list - todo.erase(std::find(todo.begin(), todo.end(), saturation_name)); - - //Find the lowest color that is not being used by any of the most saturated - //nodes neighbors, then color the most saturated node - int lowest_color = 0; - int done = 0; - while(!done) - { - done = 1; - for(unsigned i=0; i::min()) - { - saturation_level[graph[saturation_name][i]] += 1; - } - } - saturation_level[saturation_name] = std::numeric_limits::min(); - } - return coloring; -} - diff --git a/Source/my_hybrid.cpp b/Source/my_hybrid.cpp deleted file mode 100644 index 5df2a8e..0000000 --- a/Source/my_hybrid.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "../Header/my_hybrid.h" - -map GraphColoring::hybrid::color(int condition) { - if (condition == 0) { - condition = graph.size() / 2; - } - - GraphColor *alg_graph = new lmxrlf(); - alg_graph->set_graph(graph); - coloring = alg_graph->color(condition); - //coloring = lmxrlf_base(Graph,CARR); - - //********************************* - //***** Find the Sub Coloring ***** - //********************************* - int Color_temp = 0; - for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { - if((*i).second > Color_temp) { - Color_temp = (*i).second; - } - } - Color_temp += 1; - - map< string,int > Colors_temp = coloring; - - //coloring = lmxrlf(graph.size()); - coloring = alg_graph->color(graph.size()); - int Color = 0; - for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { - if((*i).second > Color) { - Color = (*i).second; - } - } - delete alg_graph; - - //****************************************************** - //***** Run Remainder through Tabucol and Recolor ***** - //****************************************************** - int subset_color = Color; - - alg_graph = new tabucol(); - alg_graph->set_graph(get_subgraph(Colors_temp)); - alg_graph->set_coloring(Colors_temp); - alg_graph->color(subset_color); - map tabu_color = alg_graph->get_coloring(); - - //map< string,vector > Graph_subset = get_subgraph(Colors_temp); - //map< string,int > tabu_color = tabucol(Graph_subset,subset_color); - map< string,int > best; - while(tabu_color.size() > 0) { - best = tabu_color; - subset_color -= 1; - //tabu_color = tabucol(Graph_subset,subset_color); - alg_graph->set_coloring(alg_graph->color(subset_color)); - tabu_color = alg_graph->get_coloring(); - } - if(best.size() > 0) { - for(map< string,int >::iterator i = best.begin(); i != best.end(); i++) { - coloring[(*i).first] = Color_temp + (*i).second; - } - } - return coloring; -} - -map< string,vector > GraphColoring::hybrid::get_subgraph(map< string,int > coloring) { - map< string,vector > subgraph; - for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { - if(coloring[(*i).first] == -1) { - vector neighbors; - for(unsigned j=0; j<(*i).second.size(); j++) { - if(coloring[(*i).second[j]] == -1) - neighbors.push_back((*i).second[j]); - } - subgraph[(*i).first] = neighbors; - } - } - return subgraph; -} diff --git a/Source/my_lmxrlf.cpp b/Source/my_lmxrlf.cpp deleted file mode 100644 index c92a3e6..0000000 --- a/Source/my_lmxrlf.cpp +++ /dev/null @@ -1,269 +0,0 @@ - -#include "../Header/my_lmxrlf.h" - -#include -#include - -using std::cerr; -using std::endl; - -int GLOBAL = 10; -int F = 1; -int LOCAL = 10; - -//Returns an independent set from given set -vector GraphColoring::lmxrlf::get_independent(vector set) { - vector delta; - for(unsigned i=0; i ret; - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { - if(coloring[(*i).first] == -1) { - int flag = 0; - for(unsigned j=0; j GraphColoring::lmxrlf::make_independent_set() { - vector set; - vector todo = get_independent(set); - while(todo.size()) { - set.push_back(todo[rand() % todo.size()]); - todo = get_independent(set); - } - return set; -} - -//Objective function for LMXRLF -int GraphColoring::lmxrlf::objf(vector set) { - int sum = 0; - for(unsigned i=0; i > list_of_best) { - if(list_of_best.size() == 0) { - cerr << "List of Best Solutions is of size 0" << endl; - return -1; - } - int min = objf(list_of_best[0]); - for (unsigned i=1; i > list_of_best) { - if(list_of_best.size() == 0) { - cerr << "List of Best Solutions is of size 0" << endl; - return -1; - } - int max = objf(list_of_best[0]); - for(unsigned i=1; i max) { - max = temp; - } - } - return max; -} - -//Returns the index from the list of best solutions with the minimum objective function -int GraphColoring::lmxrlf::min_pos_objf(vector< vector > list_of_best) { - if(list_of_best.size() == 0) { - cerr << "List of Best Solutions is of size 0" << endl; - return -1; - } - int min = objf(list_of_best[0]); - int min_pos = 0; - for(unsigned i=1; i > list_of_best) { - if(list_of_best.size() == 0) { - cerr << "List of Best Solutions is of size 0" << endl; - return -1; - } - int max = objf(list_of_best[0]); - int max_pos = 0; - for (unsigned i=1; i max) { - max = temp; - max_pos = i; - } - } - return max_pos; -} - -//Returns a set of uncolored neighbors from the input set -vector GraphColoring::lmxrlf::uncolored_neighbor(vector new_set) { - vector delta; - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { - int flag = 0; - for(unsigned j=0; j out; - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { - int initf = 1; - for(unsigned j=0; j GraphColoring::lmxrlf::lmxrlf_alg(int endcond) { - map< string, vector > Graph_temp; - vector< vector > list_of_best_solutions; - srand(time(NULL)); - int colored_nodes = 0; - int Color = 0; - for(map< string,int >::iterator i = coloring.begin(); i != coloring.end(); i++) { - if((*i).second != -1) { - colored_nodes += 1; - } - if((*i).second > Color) { - Color = (*i).second; - } - } - if(Color > 0) { Color += 1; } - do { - int global_iterations; - if (Color == 0) { global_iterations = F*GLOBAL; } - else { global_iterations = (int)(GLOBAL*(float)(1-(float)((colored_nodes*colored_nodes)/(graph.size()*graph.size())))); } - vector set = make_independent_set(); - list_of_best_solutions.push_back(set); - for(int i=0; i set_t = set; - while(uncolored_neighbor(set_t).size() == 0) { - int removal = rand() % set_t.size(); - set_t.erase(set_t.begin() + removal); - } - //Add randomly vertices which do not have colored neighbors to S - vector ucn = uncolored_neighbor(set_t); - while(ucn.size() > 0) { - set_t.push_back(ucn[rand() % ucn.size()]); - ucn = uncolored_neighbor(set_t); - } - //Check ObjF of new set and add if larger than min - if(objf(set_t) > min_objf(list_of_best_solutions)) { - list_of_best_solutions.push_back(set_t); - list_of_best_solutions.erase(list_of_best_solutions.begin() + min_pos_objf(list_of_best_solutions)); - } - } - for(unsigned i=0; i S_plus = list_of_best_solutions[i]; - for(int j=0; j S_star = list_of_best_solutions[i]; - while(uncolored_neighbor(S_star).size() == 0) { - S_star.erase(S_star.begin() + (rand() % S_star.size())); - } - //Add randomly vertices which do not have colored neighbors to S_star - vector ucn = uncolored_neighbor(S_star); - while(ucn.size() > 0) { - S_star.push_back(ucn[rand() % ucn.size()]); - ucn = uncolored_neighbor(S_star); - } - //Check ObjF of S_star and add if smaller than original - if(objf(S_star) > objf(S_plus)) { - S_plus = S_star; - flag = 1;//TODO: flag is never used? - } - } - list_of_best_solutions[i] = S_plus; - } - //Color each vertex in the solution with the highest objf (making sure they haven't already been colored) - vector max_objf = list_of_best_solutions[max_pos_objf(list_of_best_solutions)]; - for(unsigned i=0; i GraphColoring::lmxrlf::color(int condition) { - if (condition == 0) { condition = graph.size(); } - for(map< string, vector >::iterator i = graph.begin(); i != graph.end(); i++) { - coloring[(*i).first] = -1; - } - return lmxrlf_alg(condition); -} - diff --git a/Source/my_mcs.cpp b/Source/my_mcs.cpp deleted file mode 100644 index 8676ddd..0000000 --- a/Source/my_mcs.cpp +++ /dev/null @@ -1,101 +0,0 @@ - -#include "../Header/my_mcs.h" -#include - -// TODO: The following optimization can be made via a note in the paper -// The procedure MCS can be implemented to run in O(|V | + |E|) time. To -// see that, notice that the first loop executes |V | iterations. In the -// second loop, for each vertex of G, all its neighbors are visited. After -// a vertex is evaluated, it is removed from the remaining graph. Therefore, -// the weight λ is increased exactly |E| times. By keeping vertices in an -// array of buckets indexed by λ, the vertex of highest weight can be found -// in O(1) time. - -//Maximum Cardinal Search -map GraphColoring::mcs::color(int condition) { - - map > temp_graph = graph; - map< string,int> weight; - queue ordering; - - // Initially set the weight of each node to 0 - for(map< string, vector >::iterator i = temp_graph.begin(); i != temp_graph.end(); i++) - { - weight[(*i).first] = 0; - } - - // Work through all the ndoes in the graph, choosing the node - // with maximum weight, then add that node to the queue. Increase - // the weight of the queued nodes neighbors by 1. Continue until - // every node in the graph has been added to the queue - for(int i = 0; i < graph.size(); i++) - { - int max_weight = -1; - string max_vertex = ""; - - // Out of the remaining nodes, find the node with the highest weight - for(map< string, vector >:: iterator j = temp_graph.begin(); j != temp_graph.end(); j++) - { - if(weight[(*j).first] > max_weight) - { - max_weight = weight[(*j).first]; - max_vertex = (*j).first; - } - } - if(max_vertex == "") - { - cerr << "Error: Could not find a max weight node in the graph (reason unknown)" << endl; - coloring.clear(); - return coloring; - } - - // Add highest weight node to the queue and increment all of its - // neighbors weights by 1 - ordering.push(max_vertex); - for(unsigned j = 0; j colorset; - for(unsigned i = 0; i < graph[min].size(); i++) { - int col = coloring[graph[min][i]]; - colorset.insert(col); - } - - //Sort and uniquify - vector colorvec; - std::copy(colorset.begin(), colorset.end(), std::back_inserter(colorvec)); - std::sort(colorvec.begin(), colorvec.end()); - - //Pick the lowest color not contained - int newcolor = 0; - for(unsigned i = 0; i < colorvec.size(); i++) { - if(colorvec[i] == newcolor) { - newcolor++; - } - } - color = newcolor; - - coloring[min] = color; - ordering.pop(); - } - return coloring; -} diff --git a/Source/my_tabucol.cpp b/Source/my_tabucol.cpp deleted file mode 100644 index 130bbe5..0000000 --- a/Source/my_tabucol.cpp +++ /dev/null @@ -1,109 +0,0 @@ - -#include "../Header/my_tabucol.h" - -#include -#include -#include - -using std::queue; -using std::cerr; -using std::endl; - -const int TABU_SIZE = 25; -const int REP = 100; -const int NBMAX = 1000; - -int GraphColoring::tabucol::f(map coloring) { - int sum = 0; - for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { - for(unsigned j=0; j< i->second.size(); j++) { - if(coloring[i->first] == coloring[i->second[j]]) { - sum += 1; - } - } - } - return sum; -} - -map GraphColoring::tabucol::color(int k) { - srand(time(NULL)); - for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { - coloring[(*i).first] = rand() % k; - } - queue tabu_color; - queue tabu_vertex; - for(int i=0; i >::iterator x = graph.begin(); - std::advance(x,(rand() % graph.size())); - tabu_vertex.push((*x).first); - tabu_color.push(rand() % k); - } - int nbiter = 0; - while(f(coloring) > 0 && nbiter < NBMAX) { - int best_color = -1; - string best_vertex; - int x = 0; - int original_f = f(coloring); - while(x < REP) { - int flag = 0; - int move_color; - string move_vertex; - while(!flag) { - move_color = rand() % k; - map< string,vector >::iterator mv = graph.begin(); - std::advance(mv,(rand() % graph.size())); - move_vertex = (*mv).first; - int inner_flag = 0; - for(unsigned i=0; i Colors_move = coloring; - Colors_move[move_vertex] = move_color; - map< string,int > Colors_best = coloring; - Colors_best[best_vertex] = best_color; - if(f(Colors_move) < f(Colors_best)) { - best_vertex = move_vertex; - best_color = move_color; - } - x += 1; - if(f(Colors_move) < original_f) { - x = REP; - } - } - if(best_color == -1) { - map< string, int > ret; - cerr << "Best Color was never updated in the loop" << endl; - coloring = ret; - return coloring; - } - tabu_color.pop(); - tabu_color.push(best_color); - tabu_vertex.pop(); - tabu_vertex.push(best_vertex); - coloring[best_vertex] = best_color; - nbiter += 1; - } - - if(!verify()) { - map< string,int > ret; - coloring = ret; - } - return coloring; -} - diff --git a/Source/tabucol.cpp b/Source/tabucol.cpp old mode 100755 new mode 100644 index 595f439..468389d --- a/Source/tabucol.cpp +++ b/Source/tabucol.cpp @@ -1,5 +1,5 @@ -#include "../Header/graph.h" +#include "../Header/tabucol.h" #include #include @@ -13,7 +13,7 @@ const int TABU_SIZE = 25; const int REP = 100; const int NBMAX = 1000; -int GraphColoring::Graph::f(map coloring) { +int GraphColoring::Tabucol::f(map coloring) { int sum = 0; for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { for(unsigned j=0; j< i->second.size(); j++) { @@ -25,10 +25,10 @@ int GraphColoring::Graph::f(map coloring) { return sum; } -void GraphColoring::Graph::tabucol(int k) { +map GraphColoring::Tabucol::color() { srand(time(NULL)); for(map< string,vector >::iterator i = graph.begin(); i != graph.end(); i++) { - coloring[(*i).first] = rand() % k; + coloring[(*i).first] = rand() % this->condition; } queue tabu_color; queue tabu_vertex; @@ -36,7 +36,7 @@ void GraphColoring::Graph::tabucol(int k) { map< string,vector >::iterator x = graph.begin(); std::advance(x,(rand() % graph.size())); tabu_vertex.push((*x).first); - tabu_color.push(rand() % k); + tabu_color.push(rand() % this->condition); } int nbiter = 0; while(f(coloring) > 0 && nbiter < NBMAX) { @@ -49,7 +49,7 @@ void GraphColoring::Graph::tabucol(int k) { int move_color; string move_vertex; while(!flag) { - move_color = rand() % k; + move_color = rand() % this->condition; map< string,vector >::iterator mv = graph.begin(); std::advance(mv,(rand() % graph.size())); move_vertex = (*mv).first; @@ -90,7 +90,7 @@ void GraphColoring::Graph::tabucol(int k) { map< string, int > ret; cerr << "Best Color was never updated in the loop" << endl; coloring = ret; - return; + return coloring; } tabu_color.pop(); tabu_color.push(best_color); @@ -104,5 +104,6 @@ void GraphColoring::Graph::tabucol(int k) { map< string,int > ret; coloring = ret; } + return coloring; } diff --git a/colored_graph.dot b/colored_graph.dot index ac80b24..73f638c 100644 --- a/colored_graph.dot +++ b/colored_graph.dot @@ -5,8 +5,8 @@ v3[label="v3\n1"]; v4[label="v4\n2"]; v5[label="v5\n1"]; v6[label="v6\n2"]; -v7[label="v7\n3"]; -v8[label="v8\n0"]; +v7[label="v7\n0"]; +v8[label="v8\n3"]; v2 -- v1 v3 -- v2 v4 -- v3 diff --git a/graphColoring b/graphColoring index 8db91f6..ca1cbac 100755 Binary files a/graphColoring and b/graphColoring differ diff --git a/graph_color.o b/graph_color.o index 05b6a47..e5043aa 100644 Binary files a/graph_color.o and b/graph_color.o differ diff --git a/main.o b/main.o index e9d4c2c..4fa4192 100644 Binary files a/main.o and b/main.o differ diff --git a/my_dsatur.o b/my_dsatur.o deleted file mode 100644 index d658b2a..0000000 Binary files a/my_dsatur.o and /dev/null differ diff --git a/my_hybrid.o b/my_hybrid.o deleted file mode 100644 index 6966f9a..0000000 Binary files a/my_hybrid.o and /dev/null differ diff --git a/my_hybrid_dsatur.o b/my_hybrid_dsatur.o deleted file mode 100644 index a497d05..0000000 Binary files a/my_hybrid_dsatur.o and /dev/null differ diff --git a/my_lmxrlf.o b/my_lmxrlf.o deleted file mode 100644 index 2da5010..0000000 Binary files a/my_lmxrlf.o and /dev/null differ diff --git a/my_mcs.o b/my_mcs.o deleted file mode 100644 index 02e70f2..0000000 Binary files a/my_mcs.o and /dev/null differ diff --git a/my_tabucol.o b/my_tabucol.o deleted file mode 100644 index c138da4..0000000 Binary files a/my_tabucol.o and /dev/null differ