Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pgr_minCostMaxFlow #1022

Merged
merged 30 commits into from
May 20, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6e52cca
Create .c & _driver.cpp files for mcmf
XJTUmg May 15, 2018
5fc68ca
fix minCostMaxFlow.c
XJTUmg May 15, 2018
70a5d34
modified minCostMaxFlow_driver.cpp
XJTUmg May 15, 2018
eac69db
fix license in minCostMaxFlow.c
XJTUmg May 16, 2018
a13a993
fix license in _driver.cpp file
XJTUmg May 16, 2018
623578c
fix CMakeLists & configuration
XJTUmg May 16, 2018
130eba0
Create drivers/mcmf/minCostMaxFlow_driver.h
XJTUmg May 16, 2018
4389425
Create pgr_mcmf_t.h
XJTUmg May 16, 2018
38ca280
create .sql file
XJTUmg May 18, 2018
7630a95
fix pgr_mcmf_t.h
XJTUmg May 18, 2018
1281731
change signature
XJTUmg May 18, 2018
8036d55
fix _driver.cpp file
XJTUmg May 18, 2018
801cb51
fix pgr_mcmf_t.h
XJTUmg May 18, 2018
e5cd472
fixed minCostMaxFlow.c
XJTUmg May 18, 2018
0168f62
change pgr_mcmf_t to pgr_costFlow_t, for input
XJTUmg May 18, 2018
c8e4041
change to costFlow & fixminCostMaxFlow.c
XJTUmg May 18, 2018
0b353d4
modify _driver.h
XJTUmg May 18, 2018
8216d08
fix _driver.h _driver.cpp .c files
XJTUmg May 18, 2018
3110be8
change mcmf to costFlow
XJTUmg May 18, 2018
fee2d4e
modify minCostMaxFlow.sql
XJTUmg May 18, 2018
0688910
create sql files
XJTUmg May 18, 2018
9382f18
fix cmake
XJTUmg May 18, 2018
58425e2
fix .c file
XJTUmg May 18, 2018
7a5a463
create new input function in edges_input.h
XJTUmg May 19, 2018
048c568
implement cost flow input function & compiled
XJTUmg May 19, 2018
41e0c45
.hpp is ready, but not implemented
XJTUmg May 19, 2018
bde3068
copy hpp files from boost 1.58.0
XJTUmg May 19, 2018
4a510f3
trying to fix travis
XJTUmg May 19, 2018
886d606
trying to fix travis
XJTUmg May 19, 2018
5bd0d8a
fix warnings, change to double
XJTUmg May 19, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/c_types/pgr_costFlow_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


typedef struct {
int64_t edge;
int64_t id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer edge_id or vertex_id
otherwise is id of what?

int64_t source;
int64_t target;
int64_t capacity;
Expand Down
154 changes: 154 additions & 0 deletions src/common/edges_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,50 @@ void fetch_edge(
*valid_edges = edge->reverse_cost < 0? *valid_edges: *valid_edges + 1;
}

static
void fetch_costFlow_edge(
HeapTuple *tuple,
TupleDesc *tupdesc,
Column_info_t info[7],
int64_t *default_id,
int64_t default_rcapacity,
float8 default_rcost,
pgr_costFlow_t *edge,
size_t *valid_edges,
bool normal) {
if (column_found(info[0].colNumber)) {
edge->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]);
} else {
edge->id = *default_id;
++(*default_id);
}

if (normal) {
edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
} else {
edge->target = pgr_SPI_getBigInt(tuple, tupdesc, info[1]);
edge->source = pgr_SPI_getBigInt(tuple, tupdesc, info[2]);
}

edge->capacity = pgr_SPI_getBigInt(tuple, tupdesc, info[3]);
if (column_found(info[4].colNumber)) {
edge->reverse_capacity = pgr_SPI_getBigInt(tuple, tupdesc, info[4]);
} else {
edge->reverse_capacity = default_rcapacity;
}

edge->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[5]);
if (column_found(info[6].colNumber)) {
edge->reverse_cost = pgr_SPI_getFloat8(tuple, tupdesc, info[6]);
} else {
edge->reverse_cost = default_rcost;
}

*valid_edges = edge->capacity < 0? *valid_edges: *valid_edges + 1;
*valid_edges = edge->reverse_capacity < 0? *valid_edges: *valid_edges + 1;
}

static
void fetch_edge_with_xy(
HeapTuple *tuple,
Expand Down Expand Up @@ -433,6 +477,106 @@ get_edges_flow(
time_msg("reading edges", start_t, clock());
}

static
void
get_edges_costFlow(
char *sql,
pgr_costFlow_t **edges,
size_t *totalTuples,
bool ignore_id) {
clock_t start_t = clock();

const int tuple_limit = 1000000;

size_t ntuples;
size_t total_tuples;
size_t valid_edges;

Column_info_t info[7];

int i;
for (i = 0; i < 5; ++i) {
info[i].colNumber = -1;
info[i].type = 0;
info[i].strict = true;
info[i].eType = ANY_INTEGER;
}
info[0].name = "id";
info[1].name = "source";
info[2].name = "target";
info[3].name = "capacity";
info[4].name = "reverse_capacity";
info[5].name = "cost";
info[6].name = "reverse_cost";

info[0].strict = !ignore_id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it valid to ignore or not ignore the id?

info[4].strict = false;
info[6].strict = false;

info[5].eType = ANY_NUMERICAL;
info[6].eType = ANY_NUMERICAL;

void *SPIplan;
SPIplan = pgr_SPI_prepare(sql);

Portal SPIportal;
SPIportal = pgr_SPI_cursor_open(SPIplan);


bool moredata = true;
(*totalTuples) = total_tuples = valid_edges = 0;


int64_t default_id = 0;
while (moredata == true) {
SPI_cursor_fetch(SPIportal, true, tuple_limit);
if (total_tuples == 0)
pgr_fetch_column_info(info, 7);

ntuples = SPI_processed;
total_tuples += ntuples;

if (ntuples > 0) {
if ((*edges) == NULL)
(*edges) = (pgr_costFlow_t *)
palloc0(total_tuples * sizeof(pgr_costFlow_t));
else
(*edges) = (pgr_costFlow_t *)
repalloc((*edges), total_tuples * sizeof(pgr_costFlow_t));

if ((*edges) == NULL) {
elog(ERROR, "Out of memory");
}

size_t t;
SPITupleTable *tuptable = SPI_tuptable;
TupleDesc tupdesc = SPI_tuptable->tupdesc;

for (t = 0; t < ntuples; t++) {
HeapTuple tuple = tuptable->vals[t];
fetch_costFlow_edge(&tuple, &tupdesc, info,
&default_id, -1, 0,
&(*edges)[total_tuples - ntuples + t],
&valid_edges,
true);
}
SPI_freetuptable(tuptable);
} else {
moredata = false;
}
}

SPI_cursor_close(SPIportal);

if (total_tuples == 0 || valid_edges == 0) {
PGR_DBG("No edges found");
}

(*totalTuples) = total_tuples;
PGR_DBG("Reading %ld edges", total_tuples);
time_msg("reading edges", start_t, clock());
}

static
void
get_edges_basic(
Expand Down Expand Up @@ -540,6 +684,16 @@ pgr_get_flow_edges(
get_edges_flow(sql, edges, total_edges, ignore_id);
}

/* select id, source, target, capacity, reverse_capacity, cost, reverse_cost */
void
pgr_get_costFlow_edges(
char *sql,
pgr_costFlow_t **edges,
size_t *total_edges) {
bool ignore_id = false;
get_edges_costFlow(sql, edges, total_edges, ignore_id);
}

/* select id, source, target, cost, reverse_cost */
void
pgr_get_edges(
Expand Down
4 changes: 2 additions & 2 deletions src/costFlow/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ADD_LIBRARY(costFlow OBJECT
minCostMaxFlow.c
minCostMaxFlow.c)

minCostMaxFlow_driver.cpp)
#minCostMaxFlow_driver.cpp)