-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
61 changed files
with
177,487 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
cmake_minimum_required(VERSION 3.13.4) | ||
project(Quantum_BnP) | ||
|
||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) | ||
set(CMAKE_CXX_STANDARD 20) | ||
set(CMAKE_CXX_FLAGS "-DIL_STD") | ||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") | ||
|
||
################################################################################################################################### | ||
###################################################### Path Library settings ###################################################### | ||
################################################################################################################################### | ||
|
||
set(NLopt_INSTALL_DIR "${PROJECT_SOURCE_DIR}/nlopt_install") | ||
option(QB_ENABLE_SCIP "Use of SCIP library" OFF) | ||
set(SCIP_DIR YOU_PATH_TO_SCIP) | ||
|
||
|
||
option(QP_ENABLE_CPLEX "Use of CPLEX solver" OFF) | ||
set(ENV{CPLEX_ROOT} YOU_PATH_TO_CPLEX) | ||
|
||
|
||
############################################################################################################ | ||
############################################################################################################ | ||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) | ||
|
||
|
||
if (QB_ENABLE_SCIP) | ||
find_package(SCIP REQUIRED) | ||
endif() | ||
|
||
if(QP_ENABLE_CPLEX) | ||
|
||
add_library(CPLEX INTERFACE IMPORTED) | ||
FIND_PACKAGE(CPLEX REQUIRED) | ||
set(ADDITIONAL_LIBRARIES | ||
${CPLEX_LIBRARY} | ||
${CPLEX_LIBRARY_CONCERT}) | ||
|
||
link_directories(${CPLEX_INCLUDE_DIRS}) | ||
link_directories(${CPLEX_LIBRARIES}) | ||
endif() | ||
|
||
|
||
|
||
|
||
|
||
|
||
list(APPEND COLORING coloring/Branching.cpp coloring/Branching.h coloring/coloring.cpp coloring/coloring.h coloring/ConstraintHandler.cpp coloring/ConstraintHandler.h coloring/Pricer.cpp coloring/Pricer.h coloring/Probdata.cpp coloring/Probdata.h coloring/Vardata.cpp coloring/Vardata.h) | ||
list(APPEND MWIS mwis/greedy.cpp mwis/LocalSearch.cpp mwis/LocalSearch.h mwis/mwis.h mwis/cplex.cpp) | ||
list(APPEND BASICS Graph.h Graph.cpp) | ||
list(APPEND QUANTUM quantum/Hamiltonian.h quantum/Hamiltonian.cpp) | ||
file(GLOB SOURCE coloring/*) | ||
|
||
|
||
|
||
find_package(OpenMP) | ||
find_library(OPENBLAS openblas) | ||
find_package(NLopt REQUIRED) | ||
|
||
set(PROJECT_INCLUDE_DIRS | ||
${CMAKE_CURRENT_SOURCE_DIR}/mwis | ||
${CMAKE_CURRENT_SOURCE_DIR}/coloring | ||
${CMAKE_CURRENT_SOURCE_DIR}/quantum | ||
${CPLEX_INCLUDE_DIR} | ||
${CPLEX_INCLUDE_DIR}/ilcplex | ||
${CONCERT_INCLUDE_DIR} | ||
${CONCERT_INCLUDE_DIR}/ilconcert | ||
${NLOPT_INCLUDE_DIRS}) | ||
|
||
foreach(include_dir ${PROJECT_INCLUDE_DIRS}) | ||
include_directories(${include_dir}) | ||
file(GLOB tmp_headers | ||
${include_dir}/*.hpp | ||
${include_dir}/*.hx | ||
${include_dir}/*.h) | ||
list(APPEND header_files ${tmp_headers}) | ||
endforeach() | ||
|
||
|
||
link_directories(${NLOPT_LIBRARY_DIRS}) | ||
link_directories(${NLopt_INSTALL_DIR}/lib) | ||
|
||
|
||
add_executable(Quantum_BnP main.cpp ${BASICS} ${MWIS} ${QUANTUM} ${COLORING} ${CPLEX_INCLUDE_DIRS} ${ADDITIONAL_LIBRARIES} ) | ||
target_compile_definitions(Quantum_BnP INTERFACE -DIL_STD) | ||
target_link_libraries(Quantum_BnP PUBLIC ${CMAKE_DL_LIBS} ${ADDITIONAL_LIBRARIES}) | ||
|
||
target_link_libraries(Quantum_BnP PUBLIC nlopt) | ||
|
||
|
||
if(QP_ENABLE_CPLEX) | ||
target_link_libraries(Quantum_BnP INTERFACE ${CPLEX_LIBRARIES} pthread) | ||
target_include_directories(Quantum_BnP INTERFACE ${CPLEX_INCLUDE_DIRS}) | ||
target_link_libraries(Quantum_BnP PUBLIC ${CPLEX_LIBRARIES}) | ||
endif() | ||
|
||
if(QP_ENABLE_SCP) | ||
target_link_libraries(Quantum_BnP PUBLIC ${SCIP_LIBRARIES}) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// | ||
// Created by margarita on 11/10/22. | ||
// | ||
|
||
#include <fstream> | ||
#include <iostream> | ||
#include "Graph.h" | ||
#include <algorithm> | ||
|
||
#define LINE_SIZE 255 | ||
|
||
void Graph::init_empty(const int &size) { | ||
weights.resize(size, 0); | ||
node_number = size; | ||
for(int i = 0; i < size; i++) { | ||
representors[i] = i; | ||
active_nodes.insert(i); | ||
} | ||
} | ||
|
||
WTYPE Graph::get_max_weight() const { | ||
if(! weighted) | ||
return 1; | ||
|
||
auto it = active_nodes.begin(); | ||
WTYPE max_weight = abs(weights.at(*it)); | ||
it++; | ||
|
||
while (it != active_nodes.end()) { | ||
max_weight = max(max_weight, abs(weights.at(*it))); | ||
it++; | ||
} | ||
return max_weight; | ||
} | ||
|
||
void Graph::add_node_weight(const N_ID& u, const WTYPE& weight){ | ||
N_ID u_rep = representors[u]; | ||
weights[u_rep] += weight; | ||
}; | ||
|
||
|
||
void Graph::add_edge(const N_ID& u, const N_ID& v) { | ||
if (!active_nodes.count(u) || !active_nodes.count(v)) | ||
throw invalid_argument("One of the nodes isn't active"); | ||
else if (u != v) { | ||
adj_list[u].insert(v); | ||
adj_list[v].insert(u); | ||
} | ||
}; | ||
bool Graph::has_edge(const N_ID &u, const N_ID& v) const { | ||
if (!active_nodes.count(u) || !active_nodes.count(v)) | ||
throw invalid_argument("One of the nodes isn't active"); | ||
if (adj_list.find(u)==adj_list.end()) | ||
return false; | ||
else return adj_list.at(u).count(v); | ||
}; | ||
|
||
void Graph::merge_nodes(const N_ID &u, const N_ID& v) { | ||
N_ID rep_u = representors.at(u); | ||
N_ID rep_v = representors.at(v); | ||
|
||
if(has_edge(rep_u, rep_v)) | ||
throw "Connected nodes can't be merged"; | ||
|
||
active_nodes.erase(rep_v); | ||
for( auto& p: representors ) | ||
if (p.second == rep_v) | ||
p.second = rep_u; | ||
|
||
adj_list[rep_u].insert(adj_list[rep_v].begin(), adj_list[rep_v].end()); | ||
|
||
//Modify the adjacency list of rep_v's neighbors | ||
for(const auto& v_neighbor : adj_list[rep_v]){ | ||
adj_list[v_neighbor].insert(rep_u); | ||
adj_list[v_neighbor].erase(rep_v); | ||
} | ||
|
||
adj_list.erase(rep_v); | ||
return; | ||
}; | ||
|
||
void Graph::split_nodes(const N_ID &u, const N_ID& v){ | ||
N_ID rep_u = representors.at(u); | ||
N_ID rep_v = representors.at(v); | ||
|
||
add_edge(rep_u, rep_v); | ||
return; | ||
}; | ||
|
||
N_CONTAINER Graph::recover_all_merged_to(const N_CONTAINER &set) { | ||
N_CONTAINER result = set; | ||
for(int i = 0; i < node_number; i++){ | ||
if (set.count(representors[i])) | ||
result.insert(i); | ||
} | ||
return result; | ||
} | ||
|
||
void Graph::init_node_weights(const vector<WTYPE>& new_weights) { | ||
if (new_weights.size() != node_number) | ||
throw invalid_argument("The size of the vector with weights doesn't match the number of nodes"); | ||
for(auto i: active_nodes) | ||
set_node_weight(i, new_weights[i]); | ||
for(int i = 0; i < node_number; i++) | ||
if(!active_nodes.count(i)) | ||
add_node_weight(i, new_weights[i]); | ||
}; | ||
|
||
void Graph::read_dimacs(const string& filename) { | ||
ifstream file; | ||
file.open(filename); | ||
|
||
char c, comment[LINE_SIZE]; | ||
N_ID u, v; | ||
WTYPE weight; | ||
int n_nodes, n_edges; | ||
weighted = false; | ||
|
||
while (file) | ||
{ | ||
file >> c; | ||
switch (c) { | ||
case 'c': | ||
file.getline(comment, LINE_SIZE); | ||
break; | ||
case 'p': { | ||
file >> comment >> n_nodes >> n_edges; | ||
init_empty(n_nodes); | ||
edge_number = n_edges; | ||
break; | ||
} | ||
case 'e': { | ||
file >> u >> v ; | ||
if (n_edges >= 0) { | ||
add_edge(u-1, v-1); | ||
n_edges--; | ||
} else { | ||
file.close(); | ||
cerr << "No more edges to add.\n"; | ||
} | ||
break; | ||
} | ||
case 'n': { | ||
weighted = true; | ||
file >> u >> weight ; | ||
set_node_weight(u-1, weight); | ||
break; | ||
} | ||
default : | ||
{ | ||
cerr << "Unknown command. Reading aborted." << std::endl; | ||
file.close(); | ||
break; | ||
} | ||
} | ||
} | ||
if(!weighted){ | ||
for(int u = 0; u < n_nodes; u++) | ||
weights[u] = 1; | ||
} | ||
file.close(); | ||
}; | ||
|
||
bool is_independent_set(const Graph& G, const N_CONTAINER& IS){ | ||
for(const auto & u: IS) | ||
for( const auto & v: IS) | ||
if (u!=v & G.has_edge(u, v)) | ||
return false; | ||
return true; | ||
} |
Oops, something went wrong.