Skip to content

Commit

Permalink
Replace the graph with boost graph
Browse files Browse the repository at this point in the history
txt-files replaced with dot-files.
Balancing logic moved to a separate class.
Added algorithm phases.
  • Loading branch information
AntonChern committed Dec 23, 2022
1 parent 8bc931a commit fb42c03
Show file tree
Hide file tree
Showing 30 changed files with 837 additions and 1,034 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ endif()

# configuring boost
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost 1.72.0 REQUIRED COMPONENTS container program_options thread)
find_package(Boost 1.72.0 REQUIRED COMPONENTS container program_options thread graph)
include_directories(${Boost_INCLUDE_DIRS})
message(${Boost_INCLUDE_DIRS})

Expand Down
3 changes: 1 addition & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,4 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
add_executable(${BINARY}_run ${run_sources})
target_link_libraries(${BINARY}_run PUBLIC ${CMAKE_PROJECT_NAME}_lib)
target_link_libraries(${BINARY}_run LINK_PUBLIC ${Boost_LIBRARIES} Threads::Threads easyloggingpp)

target_link_libraries(${BINARY}_run LINK_PUBLIC ${Boost_LIBRARIES} Threads::Threads easyloggingpp Boost::graph)
6 changes: 4 additions & 2 deletions src/algorithms/algo_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,16 @@ std::unique_ptr<Primitive> CreateGFDValidationInstance(ParamsMap&& params) {
auto graph_path = std::filesystem::current_path() / "input_data" /
ExtractOptionValue<std::string>(params, onam::kData);
std::ifstream f(graph_path);
Graph graph = GFDtools::Parser::parse_graph(f);
graph_t graph;
GFDtools::Parser::read_graph(f, graph);
f.close();
std::vector<GFD> gfds = {};
auto gfd_paths = ExtractOptionValue<std::vector<std::string>>(params, onam::kGFDData);
for (const auto& path : gfd_paths) {
auto gfd_path = std::filesystem::current_path() / "input_data" / path;
f.open(gfd_path);
GFD gfd = GFDtools::Parser::parse_gfd(f);
GFD gfd = GFD();
GFDtools::Parser::read_gfd(f, gfd);
f.close();
gfds.push_back(gfd);
}
Expand Down
164 changes: 164 additions & 0 deletions src/algorithms/gfd/balancer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <map>
#include <numeric>
#include <algorithm>
#include <vector>

#include "balancer.h"

std::vector<std::vector<int>>
Balancer::balance(const std::vector<int>& weights, const int& processors_num) {
int m = std::min(processors_num, (int)weights.size());
std::vector<std::vector<int>> result = {};
if (weights.begin() == weights.end()) {
for (int i = 0; i < processors_num; ++i) {
std::vector<int> temp = {};
result.push_back(temp);
}
return result;
}
for (int i = 0; i < m; ++i) {
// the first value is index
std::vector<int> temp = { i };
result.push_back(temp);
}
// fill processors initially
// count optimal
double optimal = 0;
int i = 0;
for (const int& weight : weights) {
result.at(i++).push_back(weight);
i = i == m ? 0 : i;
optimal += weight;
}
optimal /= m;
// sort processors (for convenience)
for (std::vector<int>& processor : result) {
std::sort(processor.begin() + 1, processor.end());
}
// ALGORITHM
// 1st step
std::vector<int> deleted_large = {};
std::vector<int> deleted_small = {};
for (std::vector<int>& processor : result) {
auto border = processor.end();
for (auto it = --processor.end(); it != processor.begin() + 1; --it) {
if (*(it - 1) > optimal / 2) {
deleted_large.push_back(*it);
border = it;
}
else {
break;
}
}
processor.erase(border, processor.end());
}
// 2nd step
std::map<int, std::tuple<int, int, int>> quality;
for (int i = 0; i < m; ++i) {
quality.emplace(i, std::tuple<int, int, int>(0, 0, 0));
}
for (const std::vector<int>& processor : result) {
auto last_small = processor.end();
auto last = processor.end();
if (*(--processor.end()) > optimal / 2) {
--last_small;
}
if (processor.begin() + 1 == last_small) {
continue;
}
int a = 0;
int b = 0;
float sum_small =
std::accumulate(processor.begin() + 1, last_small, 0, std::plus<int>());
float sum =
std::accumulate(processor.begin() + 1, last, 0, std::plus<int>());
while (sum_small > optimal / 2) {
++a;
--last_small;
sum_small -= *last_small;
}
while (sum > optimal) {
++b;
--last;
sum -= *last;
}
std::get<0>(quality.at(processor.at(0))) = a;
std::get<1>(quality.at(processor.at(0))) = b;
std::get<2>(quality.at(processor.at(0))) = a - b;
}
// 3rd step
// sort for convenience
std::vector<std::vector<int>> small_processors = {};
std::vector<std::vector<int>> large_processors = {};
for (const std::vector<int>& processor : result) {
if (*(--processor.end()) > optimal / 2) {
large_processors.push_back(processor);
}
else {
small_processors.push_back(processor);
}
}
auto cGreater = [&quality](std::vector<int> a, std::vector<int> b) {
return std::get<2>(quality.at(a.at(0))) > std::get<2>(quality.at(b.at(0)));
};
sort(small_processors.begin(), small_processors.end(), cGreater);
sort(large_processors.begin(), large_processors.end(), cGreater);
result.clear();
result.insert(result.end(), small_processors.begin(), small_processors.end());
result.insert(result.end(), large_processors.begin(), large_processors.end());
int numOfLarges = large_processors.size() + deleted_large.size();
// work
auto border = numOfLarges < m ? result.end() - numOfLarges : result.begin();
for (auto it = border; it != result.end(); ++it) {
auto last = it->end();
if (*(last - 1) > optimal / 2) {
--last;
}
for (auto cur = last - std::get<0>(quality.at(*it->begin())); cur != last; ++cur) {
deleted_small.push_back(*cur);
}
it->erase(last - std::get<0>(quality.at(*it->begin())), last);
}
// 4th step
for (auto it = result.begin(); it != border; ++it) {
auto last = it->end();
for (auto cur = last - std::get<1>(quality.at(*it->begin())); cur != last; ++cur) {
deleted_small.push_back(*cur);
}
it->erase(last - std::get<1>(quality.at(*it->begin())), last);
}
// 5th step
i = 0;
for (const int& weight : deleted_large) {
if (i < m - large_processors.size()) {
(result.begin() + i)->push_back(weight);
}
else {
sort(result.begin(), result.end(),
[](std::vector<int> a, std::vector<int> b) {
return std::accumulate(a.begin(), a.end(), 0, std::plus<int>()) <
std::accumulate(b.begin(), b.end(), 0, std::plus<int>());
});
result.begin()->push_back(weight);
}
++i;
}
// 6th step
for (const int& weight : deleted_small) {
sort(result.begin(), result.end(),
[](std::vector<int> a, std::vector<int> b) {
return std::accumulate(a.begin(), a.end(), 0, std::plus<int>()) <
std::accumulate(b.begin(), b.end(), 0, std::plus<int>());
});
result.begin()->push_back(weight);
}
// delete indices
for (std::vector<int>& processor : result) {
processor.erase(processor.begin());
}
for (int i = 0; i < processors_num - m; ++i) {
std::vector<int> empty = {};
result.push_back(empty);
}
return result;
}
8 changes: 8 additions & 0 deletions src/algorithms/gfd/balancer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once
#include <vector>

class Balancer {
public:
static std::vector<std::vector<int>> balance(const std::vector<int>& weights, const int& processors_num);
};

26 changes: 0 additions & 26 deletions src/algorithms/gfd/gfd.cpp

This file was deleted.

29 changes: 14 additions & 15 deletions src/algorithms/gfd/gfd.h
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
#pragma once
#include <vector>
#include <string>

#include "pattern.h"
#include "graph_descriptor.h"

typedef std::pair<int, std::string> Token;
typedef std::pair<Token, Token> Literal;

class GFD {

private:
Pattern pattern;
std::vector<Literal> premises;
std::vector<Literal> conclusion;
void print(std::vector<Literal>) const;

graph_t pattern;
std::vector<Literal> premises;
std::vector<Literal> conclusion;
public:
GFD() {};
GFD(Pattern &pattern_, std::vector<Literal> &premises_,
std::vector<Literal> &conclusion_)
: pattern(pattern_), premises(premises_), conclusion(conclusion_) {}
GFD() = default;
GFD(graph_t &pattern_, std::vector<Literal> &premises_, std::vector<Literal> &conclusion_)
: pattern(pattern_), premises(premises_), conclusion(conclusion_) {}

Pattern getPattern() const { return this->pattern; }
std::vector<Literal> getPremises() const { return this->premises; }
std::vector<Literal> getConclusion() const { return this->conclusion; }
graph_t getPattern() const { return this->pattern; }
std::vector<Literal> getPremises() const { return this->premises; }
std::vector<Literal> getConclusion() const { return this->conclusion; }

void print() const;
void setPattern(graph_t& pattern_) { this->pattern = pattern_; }
void setPremises(std::vector<Literal>& premises_) { this->premises = premises_; }
void setConclusion(std::vector<Literal>& conclusion_) { this->conclusion = conclusion_; }
};
Loading

0 comments on commit fb42c03

Please sign in to comment.