GithubHelp home page GithubHelp logo

brrcrites / graph-coloring Goto Github PK

View Code? Open in Web Editor NEW
44.0 3.0 11.0 2.57 MB

C++ Graph Coloring Package

License: MIT License

C++ 98.48% CMake 1.52%
dsatur-algorithm mcs-algorithm lmxrlf-algorithm c-plus-plus graph-coloring map-coloring graph-algorithms tabucol-algorithm

graph-coloring's Introduction

Build Status

C++ Graph Coloring Package

Contact

If you have questions or reqeusts about this repository please feel free to reach out to me about it. Also feel free to email me if you open a PR and I seem to be neglecting it.

Setup

This project has two primary uses:

  • As an executable for finding the chromatic number for an input graph (in edge list or edge matrix format)
  • As a library for finding the particular coloring of an input graph (represented as a map<string,vector<string>> edge list)

In either of these cases, the project requires the use of the CMake build system to allow for easy integration into other projects. To generate an executable which can color an input graph file, simply run the following commands from the project root.

cmake .
make

This will generate a color executable which can be used to find the chromatic number of an input graph. You can also test that the system is currently running by executing the color-test executable which will also be generated by the above commands.

If you want to use these algortihms as a library for another project that uses CMake, you can add it as a subproject dependency to your project.

Graph Coloring Library

The algorithms hybridLMXRLF and hybridDSATUR are currently broken, see #29

This system uses a map graph representation as input

map<string,vector<string> > input_graph;

Each node is a unique string, and maps to a vector<string> that represent that node's neighbors. If your system uses a unique hash string you can use that directly, if your nodes are numbered then you can use std::to_string() to convert those id's to unique strings directly.

This input graph is then passed to an algorithm object, such as an object for the DSATUR algorithm shown here (Note: there are more algorithms listed below):

Dsatur* algorithm = new Dsatur(input_graph);

this creates a new DSATUR algorithm object that is loaded with your graph. If you need to update or modify the graph after your algorithm object has been constrcuted, you can do so using the modify_graph(string, vector<string>) function.

vector<string> neighbors = {"Neighbor 1", "Neighbor 2", "Neighbor 3"};
algorithm->modify_graph("New Node", neighbors);

If the input string node already exists in the graph, it will update the neighbors of that node using the input vector<string>. If the input string node doesn't already exist in the graph it is added to the graph with the list of neighbors input via the vector<string>.

You can also replace the entire graph in your algorithm with a new graph by using the set_graph(map<string, vector<string>>) function, which will replace the loaded graph with the newly input graph.

Once your algorithm has been loaded with the proper graph, you simply need to call the color() function on your algorithm object to color it.

algorithm->color();

In order to aid in validating the colorings that are created using these algorithms, we also provide a verify() function that will perform a full check of the graph to ensure that no two adjacent nodes share the same color.

algorithm->verify();

Some of the algorithms that are available here are heuristics with variable conditions. While the algorithm objects are constructed with a reasonable default value, you can modifiy the condition variable of any algorithms that have them with a set_condition(int) function.

algorithm->set_condition(new_value);

The algorithm object has an internal flag to checking if the graph has been colored, and this flag is reset every time the underlying graph is reset or modified. You should check this flag before you call the color() function to make sure that the color map you receive is valid.

algorithm->is_colored();

Once you have colored your graph, there are a few functions for getting important values:

algorithm->print_chromatic(); //prints the number of colors required to color your graph
algorithm->print_coloring(); //prints each node (by name) and it's color (int)
algorithm->find_max_color(); //returns the highest color (numbered from 0, is equal to the chromatic number - 1)

You can also write the entire graph into a .dot file using the write_graph(string filename function, where the file will be named after the input string (if no name is provided it will be named colored_graph.dot)

algorithm->write_graph(string filename); //generates a .dot file named after the input string

This package was refactored to be more easily extended. I encourage you to write new coloring algorithms utilizing this code as a base, and simply ask that you include this repo's LICENSE with any of your code, and cite/acknowledge this repo in any publications. If you do utilize this code in a publication or project, or you would like to contribute a new algorithm please reach out to me ([email protected]).

Available Algorithms:

Five coloring algorithms are currently provided in this package (See reference papers for descriptions):

  • DSATUR (New Methods to Color the Vertices of a Graph - Brelaz et al.) -- --algorithm=dsatur
  • MCS (Register Allocation via Coloring of Chordal Graphs - Magno et al.) -- --algorithm=mcs
  • lmXRLF (Efficient Coloring of a Large Spectrum of Graphs - Kirovski et al.) -- --algorithm=lmxrlf
  • Hybrid DSATUR (Custom, based on Efficient Coloring... - Kirovski et al.) -- --hybrid-dsatur
  • Hybrid lmXRLF (Custom, based on Efficient Coloring... - Kirovski et al.) -- --algorithm=hybrid-lmxrlf

Additionally, there is a k-coloring algorithm that is accessible, and used internally within other algorithms:

  • TabuCol (Using Tabu Search Techniques for Graph Coloring - Hertz et al.) -- Tabucol

Tests:

The system is capable of running tests written in both the edge list (--format=list flag) and the edge matrix (--format=matrix flag) file format. There is a large number of well known tests saved to the Tests/ directory, and you can also add tests to the Tests/ directory. The edge list and edge matrix formats are as follows:

Edge List Input File Format:

c FILE: <filename.col>
c SOURCE: <source>
c DESCRIPTION: <description>

p edge <|#nodes|> <|#edges|>
e <source> <sink>

Edge Matrix Input File Format:

<|#nodes|>
<|#nodes|x|#nodes| matrix>

1 indicates an edge between column node and row node
0 indicates a lack of an edge

graph-coloring's People

Contributors

brrcrites avatar gandreadis avatar hbae003 avatar saurfang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

graph-coloring's Issues

High Color Values on One Node Tabucol Colorings

When the Tabucol algorithm is called with a single node (or any type of call which causes it not to do a tabu iteration) the colors do not have any method for reduction. This is especially problematic when the condition that is set is large compared to the graph size. There are a few remidies, some or all of which could help aleviate this issue.

  • Force a better condition, such that any condition asking for a number of colors > the graph size is ignored and the graph size is instead used (the graph can always be colored with a number of colors = number of nodes)
  • Post-process the colors so that no matter which colors are originally chosen they are down processed into the first N contiguous colors where N is the number of colors needed

Hybrid Algorithm Refactor

The hybrid algorithms that were originally implemented were not implemented correctly, and so they have been refactored to be functional but essentially useless in their current form. Right now, they run either LMXRLF or DSATUR to find an initial coloring, and then use that coloring number as a condition to the Tabucol algorithm. The problem is that when that happens, Tabucol re-colors the entire graph to try and meet (and iteratively beat) the original coloring that was found. Instead, it should use the coloring that is generated from LMXRLF or DSATUR as an input, and then attempt to run tabu iterations on that initial graph rather than the random initialization that tabu would normally provide.

This will require a refactor of the Tabucol algorithm to have a separate initialization step, tabu step, and post-processing step. This way steps can be called when issuing a generic color() function call and a subset of steps can be called within other algorithms. We may want to make the tabu part public in case other people want to perform this process.

Change over to Strategy Pattern

Refactor the code so that the coloring algorithms inherit from an ABC and are set into the graph class as a strategy pattern, with standard color() call and standardized return.

Add bulk analysis method to provided main

The refactored main program for testing different coloring algorithms against input files has on way to designate a directory of files to run. Additionally we may want to switch to a new naming convention (or do some file analysis) to allow for the file type to be detected before running the file rather than having it designated (which would be hard in a mixed file type directory like Benchmarks/).

klmxrlf incorrect coloring

The klmxrlf algorithm colors vertices -1. It also colors vertices that are connected the same color. Each time this algorithm is run on the wheel_8 test it produces a different result, such that two vertices having the error is different every time. Here is some sample error output code of the Vertex colors and the two Vertices with the error:

Running Wheel Test Suite (Default)
Running test_cases/wheel_8.txt
LMXRLF Chromatic Number: 2
v7 is colored: 0
v1 is colored: 1
v2 is colored: 0
v3 is colored: -1
-----Error, these edges have the same color: v3 v8
Graph is not colored correctly

Running Wheel Test Suite (Default)
Running test_cases/wheel_8.txt
LMXRLF Chromatic Number: 2
v7 is colored: -1
v1 is colored: 0
v2 is colored: 1
v3 is colored: 0
v4 is colored: 1
v5 is colored: 0
v6 is colored: 1
v7 is colored: -1
-----Error, these edges have the same color: v7 v8
Graph is not colored correctly

I think the algorithm is not reaching the 8th vertex maybe? I will do more testing with this algorithm on other test cases to see if this is a consistent problem.

Add Benchmarking to Makefile

Allow for a "make benchmark" keyword that cleans, compiles with optimizations, and runs user specified test sets.

LMXRLF Algorithm is Broken

After creating a test that uses the K5 kuratowski subgraph to verify that all the algorithms are able to color it using exactly 5 colors, the LMXRLF algorithms is shown to be generating an incorrect coloring. This is likely an issue where the -1 which is used to represent a blank color is being counted as a correct color (since it isn't equal to any neighbors) and the algorithm is terminating prematurely.

This also lead to an update in the is_valid() function which now catches the case that some nodes are left uncolored but the graph was being counted as correctly colored.

Fix broken split()

split() was updated to run on linux and was inadvertently broken by a contributor because of a lack of testing.

Create Markdown Readme

Need to update the README to be more user friendly, should convert it to a GitHub Markdown during the rewrite

Update Makefile

Make a new phony target that creates a graphColoring share object file

Change -t/-e flags to -m/-l

Remove legacy -t (test, actually matrix parse before edge list existed) and -e (edge list) flags and replace them with the more obvious -m (matrix) and -l (edge list)

More Robust Input Parsing

Need to create a more robust and logical input parser that is better attuned to different input cases and is less likely to break because of small errors in input files.

Cannot install in my Mac... but it is deeper problem with the repo...

Dear,

I'm interested in using your software for a research related problem involving graph coloring. However, when I tried to install it in my Mac with the provided instructions "cmake . ; make" the following happens:

  1. Cmake complains about gflags/ and googletest/ folder as they are empty. Hence, I commented out the corresponding two ADD_SUBDIRECTORY lines in ./CMakeLists.txt
  2. After this, cmake succeeds but now make fails. The source main.cpp includes gflags/gflags.h but that folder is empty, and main.cpp won't compile if the corresponding include directive is commented out.

Please, advice...

Thanks!

Blai Bonet

Rewrite write_graph() without the need for graph_colors.h

Currently write_graph() uses graph_colors.h to choose the colors that each node gets in the .dot output file. This means that we cannot display graphs that require more colors than there are colors in graph_colors.h. Find a way to have write_graph() choose the colors (or some other representation) so we can write graphs with a (near)infinite number of colors.

Implement optimization to mcs.cc

There is an implementation optimization described in the reference paper for MCS algorithm. The optimization description is pasted to the top of mcs.cc.

Hybrid Algorithm is Broken

When testing the algorithms, Hybrid had a single instance of a better coloring than previously known. This is likely an error, so the Hybrid algorithm needs to be hand verified with the paper.

Guard against illegal write_graph() calls

Received the following error when running the test case r1000.5.col with the DSATUR algorithm

graphColoring(72423,0x7fff7824d310) malloc: ***
mach_vm_map(size=8385532581712789504) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
/bin/sh: line 1: 72423 Abort trap: 6           ./graphColoring $test -l

Refactor test_cases.mk

Since the test cases were moved during the initial commit, the test_cases.mk was updated so the Makefile would continue working, but it should be refactored so it references a single directory

Implement lsII and Hybrid

Implement the lsII algorithm as well as the lmxRLF/lsII Hybrid algorithm from the paper Efficient Coloring of a Large Spectrum of Graphs by Kirkovski et al.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.