#include<iostream>
#include<fstream>
#include<vector>
#include <sstream>
#include<assert.h>
#include<unordered_map>
#include<map>
#include<algorithm>
#include<string>
#include<set>
#include <chrono>
#include <thread>
#include<future>
#include<mutex>
#include<sys/mman.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
using namespace std;
#define TEST
#define THREAD_NUM 4
typedef unsigned int uint;
class Timer
{
public:
Timer() : beg_(clock_::now()) {}
void reset() { beg_ = clock_::now(); }
double elapsed() const {
return std::chrono::duration_cast<second_>
(clock_::now() - beg_).count();
}
void out(std::string message = "") {
double t = elapsed();
std::cout << message << " elasped time:" << t << "s\n";
reset();
}
private:
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
};
struct MyContainer
{
int base[7] = { 0 };
int rear = 0;
void push_back(int& i)
{
base[rear] = i;
++rear;
}
};
struct ArcTNode
{
int arc;
unsigned int money;
bool operator<(ArcTNode& ms2)const
{
return arc < ms2.arc;
}
};
struct VerTNode
{
unsigned int vex;
char id_char[12];
vector<ArcTNode> arcs;
vector<ArcTNode> arcs_reverse;
};
struct vector_3
{
unsigned int value[3];
};
struct m_answer {
char c[80] = {};
};
class AdjListGraph
{
public:
vector<vector_3> tmp_arcs;
VerTNode* vexs;
int node_set_size;
vector<m_answer> result[THREAD_NUM][5];
vector<uint> result_stat[THREAD_NUM][5];
uint answer_len[THREAD_NUM];
vector<unsigned int> node_set;
unordered_map<unsigned int, int> node_map;
MyContainer tmp_ms[THREAD_NUM];
void my_itoa(char* buf, unsigned int val)
{
unsigned int vals[10] = {};
int len = 0;
do
{
vals[len] = val % 10;
val /= 10;
++len;
} while (val > 0);
--len;
char* p = buf;
do
{
*p = vals[len] + '0';
++p;
--len;
} while (len >= 0);
*p = ',';
++p;
*p = '\0';
}
inline void ui2S(MyContainer& a, vector<m_answer>& b, vector<uint>& c, const uint& thread_index)
{
c.push_back(a.base[0]);
m_answer s_temp;
char* p1 = s_temp.c;
char* p2 = NULL;
for (unsigned int i = 0; i < a.rear; ++i)
{
p2 = vexs[a.base[i]].id_char;
while (*p2 != '\0')
{
*p1 = *p2;
++p1;
++p2;
}
}
*p1 = '\0';
--p1;
*p1 = '\n';
answer_len[thread_index] += strlen(s_temp.c);
b.push_back(s_temp);
}
inline bool check(unsigned int& x, unsigned int& y)const
{
return x <= 5ll * y && y <= 3ll * x;
}
void FC(const int& NUM)
{
int pp1 = 0, pp2 = 0, pp3 = 0, pp4 = 0, pp5 = 0, pp6 = 0, pp7 = 0;
unsigned int m1 = 0, m2 = 0, m3 = 0, m4 = 0, m5 = 0, m6 = 0, m7 = 0;
bool* Visited = new bool[node_set_size];
bool* Neighborhood_3 = new bool[node_set_size];
for (int i = NUM; i < node_set_size; i += THREAD_NUM)
{
for (int ip = 0; ip < node_set_size; ++ip)
{
{
Neighborhood_3[ip] = false;
}
}
Visited[i] = true;
Neighborhood_3[i] = true;
for (int j1 = 0; j1 < vexs[i].arcs_reverse.size(); ++j1)
{
pp1 = vexs[i].arcs_reverse[j1].arc;
if (pp1 <= i)
{
continue;
}
Visited[pp1] = true;
Neighborhood_3[pp1] = true;
for (int j2 = 0; j2 < vexs[pp1].arcs_reverse.size(); ++j2)
{
pp2 = vexs[pp1].arcs_reverse[j2].arc;
if (pp2 <= i)
{
continue;
}
Visited[pp2] = true;
Neighborhood_3[pp2] = true;
for (int j3 = 0; j3 < vexs[pp2].arcs_reverse.size(); ++j3)
{
pp3 = vexs[pp2].arcs_reverse[j3].arc;
if (Visited[pp3] || pp3 <= i)
{
continue;
}
Neighborhood_3[pp3] = true;
}
Visited[pp2] = false;
}
Visited[pp1] = false;
}
Visited[i] = false;
tmp_ms[NUM].push_back(i);
Visited[i] = true;
for (int j1 = 0; j1 < vexs[i].arcs.size(); ++j1)
{
pp1 = vexs[i].arcs[j1].arc;
if (pp1 <= i)
{
continue;
}
m1 = vexs[i].arcs[j1].money;
tmp_ms[NUM].push_back(pp1);
Visited[pp1] = true;
for (int j2 = 0; j2 < vexs[pp1].arcs.size(); ++j2)
{
pp2 = vexs[pp1].arcs[j2].arc;
if (pp2 <= i)
{
continue;
}
m2 = vexs[pp1].arcs[j2].money;
if (!check(m1, m2))
{
continue;
}
tmp_ms[NUM].push_back(pp2);
Visited[pp2] = true;
for (int j3 = 0; j3 < vexs[pp2].arcs.size(); ++j3)
{
pp3 = vexs[pp2].arcs[j3].arc;
if (pp3 < i)
{
continue;
}
m3 = vexs[pp2].arcs[j3].money;
if (pp3 == i)
{
if (!check(m2, m3))
{
continue;
}
if (!check(m3, m1))
{
continue;
}
ui2S(tmp_ms[NUM], result[NUM][0], result_stat[NUM][0], NUM);
continue;
}
if (Visited[pp3])
{
continue;
}
if (!check(m2, m3))
{
continue;
}
tmp_ms[NUM].push_back(pp3);
Visited[pp3] = true;
for (int j4 = 0; j4 < vexs[pp3].arcs.size(); ++j4)
{
pp4 = vexs[pp3].arcs[j4].arc;
if (pp4 < i || !Neighborhood_3[pp4])
{
continue;
}
m4 = vexs[pp3].arcs[j4].money;
if (pp4 == i)
{
if (!check(m3, m4))
{
continue;
}
if (!check(m4, m1))
{
continue;
}
ui2S(tmp_ms[NUM], result[NUM][1], result_stat[NUM][1], NUM);
continue;
}
if (Visited[pp4])
{
continue;
}
if (!check(m3, m4))
{
continue;
}
tmp_ms[NUM].push_back(pp4);
Visited[pp4] = true;
for (int j5 = 0; j5 < vexs[pp4].arcs.size(); ++j5)
{
pp5 = vexs[pp4].arcs[j5].arc;
if (pp5 < i || !Neighborhood_3[pp5])
{
continue;
}
m5 = vexs[pp4].arcs[j5].money;
if (pp5 == i)
{
if (!check(m4, m5))
{
continue;
}
if (!check(m5, m1))
{
continue;
}
ui2S(tmp_ms[NUM], result[NUM][2], result_stat[NUM][2], NUM);
continue;
}
if (Visited[pp5])
{
continue;
}
if (!check(m4, m5))
{
continue;
}
tmp_ms[NUM].push_back(pp5);
Visited[pp5] = true;
for (int j6 = 0; j6 < vexs[pp5].arcs.size(); ++j6)
{
pp6 = vexs[pp5].arcs[j6].arc;
if (pp6 < i || !Neighborhood_3[pp6])
{
continue;
}
m6 = vexs[pp5].arcs[j6].money;
if (pp6 == i)
{
if (!check(m5, m6))
{
continue;
}
if (!check(m6, m1))
{
continue;
}
ui2S(tmp_ms[NUM], result[NUM][3], result_stat[NUM][3], NUM);
continue;
}
if (Visited[pp6])
{
continue;
}
if (!check(m5, m6))
{
continue;
}
tmp_ms[NUM].push_back(pp6);
Visited[pp6] = true;
for (int j7 = 0; j7 < vexs[pp6].arcs.size(); ++j7)
{
pp7 = vexs[pp6].arcs[j7].arc;
if (pp7 < i || !Neighborhood_3[pp7])
{
continue;
}
m7 = vexs[pp6].arcs[j7].money;
if (pp7 == i)
{
if (!check(m6, m7))
{
continue;
}
if (!check(m7, m1))
{
continue;
}
ui2S(tmp_ms[NUM], result[NUM][4], result_stat[NUM][4], NUM);
continue;
}
}
tmp_ms[NUM].rear -= 1;
Visited[pp6] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[pp5] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[pp4] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[pp3] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[pp2] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[pp1] = false;
}
tmp_ms[NUM].rear -= 1;
Visited[i] = false;
}
delete[] Visited;
delete[] Neighborhood_3;
}
AdjListGraph()
{
for (size_t i = 0; i < THREAD_NUM; i++)
{
answer_len[i] = 0;
}
}
~AdjListGraph()
{
delete[]vexs;
}
void CreateFromFile(string& FileName)
{
int fd = open(FileName.c_str(), O_RDONLY);
int len = lseek(fd, 0, SEEK_END);
char* data = (char*)mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
auto p_end = data;
vector_3 value;
tmp_arcs.reserve(2000000);
node_set.reserve(4000000);
while (*p_end != '\0')
{
for (short int i = 0; i < 3; ++i)
{
value.value[i] = strtoul(p_end, &p_end, 10);
++p_end;
if (i < 2)
{
node_set.push_back(value.value[i]);
}
}
tmp_arcs.push_back(value);
}
munmap(data, len);
sort(node_set.begin(), node_set.end());
node_set.erase(unique(node_set.begin(), node_set.end()), node_set.end());
node_set_size = node_set.size();
vexs = new VerTNode[node_set_size];
size_t i;
for (i = 0; i < node_set_size; ++i)
{
vexs[i].vex = node_set[i];
my_itoa(vexs[i].id_char, node_set[i]);
node_map[node_set[i]] = i;
}
int j, k;
ArcTNode aa;
for (i = 0; i < tmp_arcs.size(); ++i)
{
k = node_map[tmp_arcs[i].value[0]];
j = node_map[tmp_arcs[i].value[1]];
aa.money = tmp_arcs[i].value[2];
aa.arc = j;
vexs[k].arcs.push_back(aa);
aa.arc = k;
vexs[j].arcs_reverse.push_back(aa);
}
for (i = 0; i < node_set_size; i++)
{
sort(vexs[i].arcs.begin(), vexs[i].arcs.end());
}
}
void PrintResult(string& outFileName)
{
uint size[5] = { 0,0,0,0,0 };
uint total_size = 0;
for (uint i = 0; i < THREAD_NUM; ++i)
{
for (uint j = 0; j < 5; ++j)
{
size[j] += result[i][j].size();
total_size += result[i][j].size();
}
}
#ifdef TEST
cout << "Cycle Total " << total_size << "\n";
for (int j = 0; j < THREAD_NUM; ++j)
{
for (int i = 0; i < 5; ++i)
{
cout << result[i][j].size() << "\t";
}
cout << "\n";
}
#endif
string total_size_s = to_string(total_size) + "\n";
int len = total_size_s.size() + 1;
for (int i = 0; i < THREAD_NUM; ++i)
{
len += answer_len[i];
}
int fd = open(outFileName.c_str(), O_RDWR | O_CREAT, 0666);
lseek(fd, len - 1, 0);
write(fd, "h", 1);
char* addr = (char*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
auto iter = addr;
memcpy(addr, total_size_s.c_str(), total_size_s.size());
addr += total_size_s.size();
uint t[THREAD_NUM];
uint process_id = 0;
for (uint i = 0; i < 5; ++i)
{
for (uint j = 0; j < THREAD_NUM; ++j)
t[j] = 0;
process_id = 0;
while (size[i])
{
for (uint j = 0; j < THREAD_NUM; ++j)
{
while (t[j] < result_stat[j][i].size() && result_stat[j][i][t[j]] == process_id)
{
memcpy(addr, result[j][i][t[j]].c, strlen(result[j][i][t[j]].c));
addr += strlen(result[j][i][t[j]].c);
++t[j];
--size[i];
}
++process_id;
}
}
}
memcpy(addr, "\n", 1);
munmap(iter, len);
}
};
int main()
{
#ifdef TEST
Timer timer;
Timer timer1;
#endif
AdjListGraph g;
#ifdef TEST
string s = "test_data_196.txt";
string outFileName = "result.txt";
g.CreateFromFile(s);
#endif
#ifndef TEST
string s = "//data//test_data.txt";
g.CreateFromFile(s);
string outFileName = "//projects//student//result.txt";
#endif
#ifdef TEST
timer1.out("CreateGraph");
Timer timer2;
#endif
#if THREAD_NUM==1
g.FC(THREAD_NUM - 1);
#endif
#if THREAD_NUM!=1
size_t i;
std::future <void> m[THREAD_NUM - 1];
for (i = 0; i < THREAD_NUM - 1; ++i)
{
m[i] = std::async(&AdjListGraph::FC, &g, i);
}
g.FC(THREAD_NUM - 1);
for (i = 0; i < THREAD_NUM - 1; ++i)
{
m[i].wait();
}
#endif
#ifdef TEST
timer2.out("FindCycle");
Timer timer3;
#endif
g.PrintResult(outFileName);
#ifdef TEST
timer3.out("SaveFile");
timer.out("Total");
#endif
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)