-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpareto.cc
145 lines (126 loc) · 3.81 KB
/
pareto.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//////////////////////////////////////////////////////////////
// PARETO: computes the pareto frontier given a set of points
//////////////////////////////////////////////////////////////
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "Datapoint.h"
#include "ParetoAlgo.h"
#include "StablesortAlgo.h"
#include "BruteforceAlgo.h"
#include "NondominatedsortAlgo.h"
void usage(){
std::cerr << "[usage] pareto (-a algorithmName) -l file1 -l file2 ... -l fileK \n \
Computes pareto frontier given N K-dimensional datapoints. \n \
There are K>1 files, each consisting of a column of N numbers. \n \
The flag -l indicates larger number is better (maximize); \n \
alternatively, the -s flag means smaller is better (minimize). \n \
The output consists of N labels, where 1=pareto and 0=not. \n\n \
Flag -a specifies the algorithm to use. \n \
Supported algorithms: \n \
-a bruteforce (default for K>2) \n \
-a stablesort (default for K=2) \n \
-a nondominatedsort (generates ranking, with higher number meaning higher level of pareto front)\n \
" << std::endl;
exit(1);
}
int main(int argc, char* argv[]){
/////////////////////////////////
// Command line parameters
std::vector< std::pair<char*,int> > files;
std::string algoName; // name of specific paretro algorithm to use
int c;
while ((c=getopt(argc,argv,":l:s:a:")) !=-1) {
switch (c){
case 'l':
files.push_back(std::make_pair(optarg,1));
break;
case 's':
files.push_back(std::make_pair(optarg,-1));
break;
case 'a':
algoName=std::string(optarg);
break;
case '?':
usage();
break;
}
}
////////////////////////////////////
// Read data
int K = files.size(); // # of files, i.e. K-dimensional problem
if (K<2){
std::cerr << "[error] Insufficient dimension (2 or more input files needed). " << std::endl;
usage();
}
std::vector<Datapoint*> dataset; //dataset will contain N K-dim datapoints
size_t idmax_file1; // for sanity check to ensure equal file lengths
for (size_t f=0; f<files.size(); ++f){
std::ifstream infile(files[f].first);
if (!infile){
std::cerr << "[error] Unable to open file: " << files[f].first << std::endl;
exit(1);
}
size_t id=0;
float num;
float m=files[f].second;
while (infile >> num){
if (f==0){
Datapoint *d = new Datapoint(id);
dataset.push_back(d);
}
else {
if (id >= idmax_file1){
std::cerr << "[error] unequal #datapoints in " << files[0].first << " vs " << files[f].first << std::endl;
exit(1);
}
}
dataset[id]->addNumber(m*num);
++id;
}
infile.close();
if (f == 0){
idmax_file1 = id;
}
else {
if (id != idmax_file1){
std::cerr << "[error] unequal #datapoints in " << files[0].first << " vs " << files[f].first << std::endl;
exit(1);
}
}
}
//////////////////////////////////////
// Choose the Pareto Algorithm to use
if (algoName.empty()){
if (K==2){
algoName="stablesort";
}
else {
algoName="bruteforce";
}
}
ParetoAlgo* algo = NULL;
if (algoName == "stablesort"){
algo = new StablesortAlgo();
}
else if (algoName == "bruteforce") {
algo = new BruteforceAlgo();
}
else if (algoName == "nondominatedsort"){
algo = new NondominatedsortAlgo();
}
else {
std::cout << "[error] Unknown AlgoName: " << algoName << std::endl;
}
////////////////////////////////////
// Compute the Pareto Frontier!
int numPareto = algo->computeFrontier(dataset);
std::cerr << "#pareto: " << numPareto << " of " << dataset.size() << " total, by the " << algoName << " algorithm " << std::endl;
for (size_t d=0; d<dataset.size(); ++d){
//dataset[d]->print();
std::cout << dataset[d]->getParetoStatus() << std::endl;
}
return 0;
}