mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
svn -> git Migration
This commit is contained in:
@@ -0,0 +1,759 @@
|
||||
/*
|
||||
|
||||
Fear Pathing generation utility.
|
||||
(c) 2005 Father Nitwit
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../zone/map.h"
|
||||
#include "../common/rdtsc.h"
|
||||
#include "quadtree.h"
|
||||
#include "apathing.h"
|
||||
#include "boostcrap.h"
|
||||
#include <stdio.h>
|
||||
#include <mysql.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <gd.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
We assume this overwrites the edge array in big
|
||||
and does not free the old edges
|
||||
*/
|
||||
void build_boost_graph(MyGraph &vg, property_map<MyGraph, edge_weight_t>::type &weightmap, map<PathEdge *, EdgeDesc> &em, PathGraph *big, bool set_weights) {
|
||||
|
||||
list<PathEdge*>::iterator cur,end;
|
||||
list<PathNode*>::iterator curn,endn;
|
||||
PathNode *n;
|
||||
PathEdge *e;
|
||||
|
||||
//first we need to number our nodes...
|
||||
curn = big->nodes.begin();
|
||||
endn = big->nodes.end();
|
||||
int r = 0;
|
||||
for(; curn != endn; curn++) {
|
||||
n = *curn;
|
||||
n->node_id = r;
|
||||
r++;
|
||||
}
|
||||
|
||||
typedef std::pair < int, int > E; //our edge type
|
||||
|
||||
weightmap = get(edge_weight, vg);
|
||||
|
||||
//now add all our edges to the graph
|
||||
cur = big->edges.begin();
|
||||
end = big->edges.end();
|
||||
for(r = 0; cur != end; cur++, r++) {
|
||||
e = *cur;
|
||||
if(e->from == e->to)
|
||||
continue;
|
||||
|
||||
// printf("A %d/%d (%.3f,%.3f,%.3f) -> (%.3f,%.3f,%.3f) d=%.3f\n", r, big->edges.size(), e->from->x, e->from->y, e->from->z, e->to->x, e->to->y, e->to->z, e->from->Dist2(e->to));
|
||||
EdgeDesc ed;
|
||||
bool inserted;
|
||||
tie(ed, inserted) = add_edge(e->from->node_id, e->to->node_id, vg);
|
||||
if(set_weights)
|
||||
weightmap[ed] = int(e->from->Dist2(e->to));
|
||||
else
|
||||
weightmap[ed] = 1;
|
||||
em[e] = ed;
|
||||
// e->edge_id = ed;
|
||||
}
|
||||
//now we should have a nice happy undirected graph...
|
||||
}
|
||||
|
||||
void run_min_spanning_tree(MyGraph &vg, property_map<MyGraph, edge_weight_t>::type &weightmap, map<PathEdge *, EdgeDesc> &em, PathGraph *big, int start_node) {
|
||||
int noedge = 0;
|
||||
list<PathEdge *> out_paths;
|
||||
|
||||
vector < EdgeDesc > spanning_tree;
|
||||
|
||||
kruskal_minimum_spanning_tree(vg, back_inserter(spanning_tree));
|
||||
|
||||
vector < EdgeDesc >::iterator cur,end;
|
||||
list<PathEdge*>::iterator cure,ende;
|
||||
cur = spanning_tree.begin();
|
||||
end = spanning_tree.end();
|
||||
for(; cur != end; cur++) {
|
||||
//find the edge
|
||||
cure = big->edges.begin();
|
||||
ende = big->edges.end();
|
||||
for(; cure != ende; cure++) {
|
||||
if(em[*cure] == *cur) {
|
||||
out_paths.push_back(new PathEdge((*cure)->from, (*cure)->to));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
noedge = big->edges.size() - out_paths.size() - 1;
|
||||
printf("Ran Min Spanning Tree: %d paths were eliminated.\n", noedge);
|
||||
|
||||
|
||||
/*
|
||||
//make our results list.
|
||||
vector < VertDesc > p(num_vertices(vg));
|
||||
|
||||
//finally run the stupid algorithm.
|
||||
prim_minimum_spanning_tree(vg, &p[0], root_vertex(start_node));
|
||||
|
||||
|
||||
for (std::size_t i = 0; i != p.size(); ++i) {
|
||||
if (p[i] != i) {
|
||||
out_paths.push_back(new PathEdge(big->nodes[p[i]], big->nodes[i]));
|
||||
} else {
|
||||
//no edge here...
|
||||
noedge++;
|
||||
}
|
||||
}
|
||||
printf("Ran Min Spanning Tree: %d nodes were disconnected.\n", noedge);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//now swap out our edge list to the MST.
|
||||
big->edges = out_paths;
|
||||
}
|
||||
|
||||
void find_disjoint_grids(Map *map, MyGraph &vg, PathGraph *big, const char *fname, vector<int> &start_nodes, vector<PathGraph *> &disjoints) {
|
||||
|
||||
vector< vector<int> > D;
|
||||
vector<int> counts;
|
||||
vector<int> disjoint_counts;
|
||||
vector<int> first_node;
|
||||
|
||||
//color the graph and get us the info we need to do out job
|
||||
color_disjoint_graphs(big, vg, map, fname, D, counts, disjoint_counts, first_node);
|
||||
|
||||
|
||||
//find the biggest grid, that one gets to be included no matter what
|
||||
int best_graph = 0;
|
||||
int best_count = counts[0];
|
||||
unsigned int r;
|
||||
for(r = 1; r < counts.size(); r++) {
|
||||
if(best_count < counts[r]) {
|
||||
best_count = counts[r];
|
||||
best_graph = r;
|
||||
}
|
||||
}
|
||||
disjoint_counts[best_graph] = 1;
|
||||
|
||||
|
||||
//break up the graphs based on color if we want them.
|
||||
vector<int>::iterator ccur,djcur,fcur,cend;
|
||||
list<PathEdge*>::iterator cur,end;
|
||||
PathEdge *e;
|
||||
PathGraph *pg;
|
||||
ccur = counts.begin();
|
||||
djcur = disjoint_counts.begin();
|
||||
fcur = first_node.begin();
|
||||
cend = counts.end();
|
||||
int color = 0;
|
||||
for(; ccur != cend; ccur++, djcur++, fcur++, color++) {
|
||||
int count = *ccur;
|
||||
int dj = *djcur;
|
||||
// int fn = *fcur;
|
||||
|
||||
if(dj < 1)
|
||||
continue; //skip disjoint sets not marked for use.
|
||||
|
||||
if(count < MIN_DISJOINT_NODES)
|
||||
continue; //make sure we have a reasonable node count
|
||||
|
||||
pg = new PathGraph();
|
||||
|
||||
cur = big->edges.begin();
|
||||
end = big->edges.end();
|
||||
for(; cur != end; cur++) {
|
||||
e = *cur;
|
||||
if(e->from->color != e->to->color) {
|
||||
printf("Color Mismatch %d-%d: #%d(%.3f,%.3f,%.3f) -> #%d(%.3f,%.3f,%.3f)\n", e->from->color, e->to->color, e->from->node_id, e->from->x, e->from->y, e->from->z, e->to->node_id, e->to->x, e->to->y, e->to->z);
|
||||
//... what to do...
|
||||
}
|
||||
//just use the color of the from node
|
||||
if(e->from->color == color) {
|
||||
pg->edges.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
//get our list of nodes based on our edge list.
|
||||
rebuild_node_list(pg->edges, pg->nodes, NULL);
|
||||
|
||||
disjoints.push_back(pg);
|
||||
start_nodes.push_back(1); //each graph only contains its own nodes, so any node will work.
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
int best_graph = 0;
|
||||
int best_count = counts[0];
|
||||
unsigned int r;
|
||||
for(r = 1; r < counts.size(); r++) {
|
||||
if(best_count < counts[r]) {
|
||||
best_count = counts[r];
|
||||
best_graph = r;
|
||||
}
|
||||
// printf("Graph %d has %d edges\n", r, counts[r]);
|
||||
}
|
||||
|
||||
start_node = first_node[best_graph];
|
||||
printf("Best sub-graph: chose #%d of %d, has %d nodes, and contains node %d\n", best_graph, counts.size()-1, best_count, start_node);
|
||||
//todo: eliminate other graphs...
|
||||
*/
|
||||
|
||||
/* list<PathEdge*>::iterator cure,ende;
|
||||
PathEdge *e;
|
||||
cure = big->edges.begin();
|
||||
ende = big->edges.end();
|
||||
for(; cure != ende; cure++) {
|
||||
e = *cure;
|
||||
if(e->from->color != e->to->color) {
|
||||
printf("Color Mismatch %d-%d: #%d(%.3f,%.3f,%.3f) -> #%d(%.3f,%.3f,%.3f)\n", e->from->color, e->to->color, e->from->node_id, e->from->x, e->from->y, e->from->z, e->to->node_id, e->to->x, e->to->y, e->to->z);
|
||||
} else if(e->from->color != best_graph) {
|
||||
printf("Color %d: (%.3f,%.3f,%.3f) -> (%.3f,%.3f,%.3f)\n", e->from->color, e->from->x, e->from->y, e->from->z, e->to->x, e->to->y, e->to->z);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const int INT_LIMIT = (std::numeric_limits < int >::max)();
|
||||
|
||||
void color_disjoint_graphs(
|
||||
PathGraph *big,
|
||||
MyGraph &vg,
|
||||
Map *map,
|
||||
const char *fname,
|
||||
|
||||
vector< vector<int> > &D, //output
|
||||
vector<int> &counts, //output
|
||||
vector<int> &disjoint_counts, //output
|
||||
vector<int> &first_node //output
|
||||
) {
|
||||
|
||||
|
||||
int count = big->nodes.size();
|
||||
// int r;
|
||||
|
||||
// vector< vector<int> > D(count, vector<int>(count, INT_LIMIT));
|
||||
// vector<int> counts(1, 0);
|
||||
// vector<int> first_node(1, 0);
|
||||
|
||||
//make sure everything is inited right...
|
||||
D.resize(0);
|
||||
D.resize(count, vector<int>(count, INT_LIMIT));
|
||||
counts.resize(1);
|
||||
counts[0] = 0;
|
||||
disjoint_counts.resize(1);
|
||||
disjoint_counts[0] = 0;
|
||||
first_node.resize(1);
|
||||
first_node[0] = 0;
|
||||
|
||||
//make up a weight map with all 1s, done while building now
|
||||
/* property_map < MyGraph, edge_weight_t >::type w = get(edge_weight, vg);
|
||||
graph_traits < MyGraph >::edge_iterator e, e_end;
|
||||
for (boost::tie(e, e_end) = edges(vg); e != e_end; ++e)
|
||||
w[*e] = 1;*/
|
||||
|
||||
|
||||
johnson_all_pairs_shortest_paths(vg, D);
|
||||
|
||||
list<PathNode*>::iterator cur,end,cur2;
|
||||
PathNode *n,*f;
|
||||
|
||||
int cur_color = 1;
|
||||
int cc,djc;
|
||||
|
||||
//clear node colors
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
n->color = 0;
|
||||
}
|
||||
|
||||
|
||||
//color the graph based on reachability, basically labeling subgraphs
|
||||
//this finds the number of nodes reachable from each node
|
||||
//which is used to pick the best disconnected graph in the tree.
|
||||
//its a series of wrong bullshit that forces us to do this, but it works
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
if(n->color != 0)
|
||||
continue; //allready visited
|
||||
|
||||
//printf("New Color at: (%.3f,%.3f,%.3f)\n", n->x, n->y, n->z);
|
||||
|
||||
cc = 1;
|
||||
djc = 0;
|
||||
|
||||
if(n->disjoint)
|
||||
djc++;
|
||||
|
||||
n->color = cur_color;
|
||||
cur_color++;
|
||||
|
||||
cur2 = cur;
|
||||
for(; cur2 != end; cur2++) {
|
||||
f = *cur2;
|
||||
if(f->color == 0 && D[n->node_id][f->node_id] != INT_LIMIT) {
|
||||
cc++;
|
||||
f->color = n->color;
|
||||
}
|
||||
if(f->disjoint)
|
||||
djc++;
|
||||
}
|
||||
counts.push_back(cc);
|
||||
disjoint_counts.push_back(djc);
|
||||
first_node.push_back(n->node_id);
|
||||
}
|
||||
|
||||
#ifdef DRAW_ALL_COLORS
|
||||
|
||||
if(fname != NULL) {
|
||||
printf("Drawing with %d seperate sub-graphs from %d nodes and %d edges\n", cur_color-1, big->nodes.size(), big->edges.size());
|
||||
|
||||
FILE *pngout;
|
||||
pngout = fopen(fname, "wb");
|
||||
if(pngout == NULL) {
|
||||
printf("Unable to open %s\n", fname);
|
||||
return;
|
||||
}
|
||||
|
||||
gdImagePtr im;
|
||||
int minx = int(map->GetMinX());
|
||||
int maxx = int(map->GetMaxX());
|
||||
int miny = int(map->GetMinY());
|
||||
int maxy = int(map->GetMaxY());
|
||||
|
||||
im = gdImageCreate((maxx - minx)/IMAGE_SCALE, (maxy - miny)/IMAGE_SCALE);
|
||||
// im = gdImageCreate(maxx - minx, maxy - miny);
|
||||
|
||||
//allocate this first, to make it the BG color.
|
||||
/*int black =*/ gdImageColorAllocate(im, 0, 0, 0);
|
||||
|
||||
// int grey = gdImageColorAllocate(im, 100, 100, 100);
|
||||
|
||||
int *clist = new int[cur_color];
|
||||
int r;
|
||||
for(r = 0; r < cur_color; r++) {
|
||||
clist[r] = gdImageColorAllocate(im, rand()%255, rand()%255, rand()%255);
|
||||
}
|
||||
|
||||
{
|
||||
list<PathEdge*>::iterator cur,end;
|
||||
PathEdge *e;
|
||||
|
||||
cur = big->edges.begin();
|
||||
end = big->edges.end();
|
||||
for(; cur != end; cur++) {
|
||||
e = *cur;
|
||||
int x1 = int(e->from->x) - minx;
|
||||
int y1 = int(e->from->y) - miny;
|
||||
int x2 = int(e->to->x) - minx;
|
||||
int y2 = int(e->to->y) - miny;
|
||||
x1 /= IMAGE_SCALE;
|
||||
y1 /= IMAGE_SCALE;
|
||||
x2 /= IMAGE_SCALE;
|
||||
y2 /= IMAGE_SCALE;
|
||||
gdImageLine(im, x1, y1, x2, y2, clist[e->from->color]);
|
||||
}
|
||||
}
|
||||
delete[] clist;
|
||||
|
||||
gdImagePng(im, pngout);
|
||||
gdImageDestroy(im);
|
||||
|
||||
fclose(pngout);
|
||||
|
||||
printf("Wrote image: %s\n", fname);
|
||||
}
|
||||
#endif //DRAW_ALL_COLORS
|
||||
}
|
||||
|
||||
void calc_path_lengths(Map *map, MyGraph &vg, PathGraph *big, map<PathEdge *, EdgeDesc> &em, const char *fname) {
|
||||
|
||||
vector<int> counts;
|
||||
vector<int> disjoint_counts;
|
||||
vector<int> first_node;
|
||||
vector< vector<int> > D;
|
||||
list<PathNode*>::iterator cur,end;
|
||||
PathNode *n;
|
||||
|
||||
/*
|
||||
Node distances:
|
||||
1. find the root node.
|
||||
- find the longest path from each node to any other node
|
||||
- the node with the shortest of these longest paths is the root
|
||||
2. record each node's distance from that root node
|
||||
*/
|
||||
|
||||
//color the graph and get us the info we need to do out job
|
||||
color_disjoint_graphs(big, vg, map, fname, D, counts, disjoint_counts, first_node);
|
||||
|
||||
|
||||
vector<int>::iterator curp,endp;
|
||||
|
||||
int shortest_node = 0;
|
||||
int shortest = 0xFFFFFF;
|
||||
int the_longest = 0;
|
||||
int longest_node = 0;
|
||||
|
||||
//stores the longest path from each node
|
||||
vector<int> longest_dists(D.size(), 0);
|
||||
|
||||
//find the node with the longest path of all, so we know what
|
||||
//tree we are trying to find the root of
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
vector<int> &cv = D[n->node_id];
|
||||
curp = cv.begin();
|
||||
endp = cv.end();
|
||||
int longest = 0;
|
||||
int discount = 0;
|
||||
for(; curp != endp; curp++) {
|
||||
if(*curp == INT_LIMIT) {
|
||||
discount++;
|
||||
continue;
|
||||
}
|
||||
if(*curp > longest)
|
||||
longest = *curp;
|
||||
}
|
||||
|
||||
longest_dists[n->node_id] = longest;
|
||||
|
||||
if(longest > the_longest) {
|
||||
the_longest = longest;
|
||||
longest_node = n->node_id;
|
||||
}
|
||||
}
|
||||
|
||||
//find the node with the shortest, longest path
|
||||
//the idea is to locate the 'root' of the tree.
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
vector<int> &cv = D[n->node_id];
|
||||
if(cv[longest_node] == INT_LIMIT)
|
||||
continue; //this node cannot reach the root
|
||||
|
||||
int longest = longest_dists[n->node_id];
|
||||
//n->longest_path = longest;
|
||||
//printf("Node %d's longest path is %d\n", n->node_id, longest);
|
||||
|
||||
if(longest < shortest) {
|
||||
shortest = longest;
|
||||
shortest_node = n->node_id;
|
||||
}
|
||||
}
|
||||
|
||||
//now we have our root, set each node to their distance from the root
|
||||
vector<int> &root_dists = D[shortest_node];
|
||||
printf("The tree's root is %d\n", shortest_node);
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
if(n->node_id == shortest_node)
|
||||
n->longest_path = 0;
|
||||
else
|
||||
n->longest_path = root_dists[n->node_id];
|
||||
//printf("Node %d's distance from root is %d\n", n->node_id, root_dists[n->node_id]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
the reachability is the number of nodes which we could possibly get to
|
||||
by traveling each direction across an edge.
|
||||
|
||||
to find reachability:
|
||||
loop through each edge e
|
||||
Remove that edge from the graph
|
||||
color_disjoint_graphs
|
||||
fc = count number of nodes with the same color as 'e->from'
|
||||
tc = count number of nodes with the same color as 'e->to'
|
||||
e->normal_reach = tc;
|
||||
e->reverse_reach = fc;
|
||||
*/
|
||||
property_map<MyGraph, edge_weight_t>::type weightmap;
|
||||
weightmap = get(edge_weight, vg);
|
||||
|
||||
int tc,fc;
|
||||
int from_color, to_color;
|
||||
|
||||
printf("Finding lengths (%d dots)", 1+big->edges.size()/10);
|
||||
int pos = 0;
|
||||
|
||||
PathEdge *e;
|
||||
list<PathEdge*>::iterator cur4,end4;
|
||||
cur4 = big->edges.begin();
|
||||
end4 = big->edges.end();
|
||||
for(; cur4 != end4; cur4++, pos++) {
|
||||
if(pos % 10 == 0) {
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
e = *cur4;
|
||||
|
||||
//remove this edge from the boost graph..
|
||||
remove_edge(em[e], vg);
|
||||
|
||||
//color the graph and get us the info we need to do our job
|
||||
//char out[64];
|
||||
//sprintf(out, "lengraph-%d.png", pos);
|
||||
color_disjoint_graphs(big, vg, map,
|
||||
NULL,
|
||||
D, counts, disjoint_counts, first_node);
|
||||
|
||||
//add the edge back in
|
||||
EdgeDesc ed;
|
||||
bool inserted;
|
||||
tie(ed, inserted) = add_edge(e->from->node_id, e->to->node_id, vg);
|
||||
em[e] = ed;
|
||||
weightmap[em[e]] = int(e->from->Dist2(e->to)); //cause its a new edge
|
||||
|
||||
//make sure this stupid thing worked.
|
||||
if(e->from->color == e->to->color) {
|
||||
printf("Cycle detected in MST... WTF?\n");
|
||||
e->normal_reach = -1;
|
||||
e->reverse_reach = -1;
|
||||
continue;
|
||||
}
|
||||
from_color = e->from->color;
|
||||
to_color = e->to->color;
|
||||
|
||||
//count our crap.
|
||||
tc = 0;
|
||||
fc = 0;
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
if(n->color == to_color)
|
||||
tc++;
|
||||
else if(n->color == from_color)
|
||||
fc++;
|
||||
}
|
||||
|
||||
//put it on our edge
|
||||
e->normal_reach = tc;
|
||||
e->reverse_reach = fc;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
//re-color the graph, since we dicked with it above
|
||||
color_disjoint_graphs(big, vg, map, fname, D, counts, disjoint_counts, first_node);
|
||||
choose_biggest_graph(big, counts, first_node);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void just_color_the_damned_thing(Map *map, PathGraph *big, const char *fname) {
|
||||
MyGraph vg(big->nodes.size());
|
||||
property_map<MyGraph, edge_weight_t>::type weightlist_mst;
|
||||
std::map<PathEdge *, EdgeDesc> edgemap_mst;
|
||||
build_boost_graph(vg, weightlist_mst, edgemap_mst, big, true);
|
||||
|
||||
vector<int> counts;
|
||||
vector<int> disjoint_counts;
|
||||
vector<int> first_node;
|
||||
vector< vector<int> > D;
|
||||
list<PathNode*>::iterator cur,end;
|
||||
|
||||
color_disjoint_graphs(big, vg, map, fname, D, counts, disjoint_counts, first_node);
|
||||
}
|
||||
|
||||
/*
|
||||
void calc_path_lengths(Map *map, MyGraph &vg, PathGraph *big, vector< vector<int> > &D, const char *fname) {
|
||||
|
||||
// vector< vector<int> > D;
|
||||
vector<int> counts;
|
||||
vector<int> first_node;
|
||||
|
||||
|
||||
choose_biggest_graph(big, counts, first_node);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//assumes that the graph is freshly colored disjoint, and counts/first_node are results from it
|
||||
void choose_biggest_graph(PathGraph *big, vector<int> &counts, vector<int> &first_node) {
|
||||
int best_graph = 0;
|
||||
int best_count = counts[0];
|
||||
unsigned int r;
|
||||
for(r = 1; r < counts.size(); r++) {
|
||||
if(best_count < counts[r]) {
|
||||
best_count = counts[r];
|
||||
best_graph = r;
|
||||
}
|
||||
printf("Graph %d has %d edges\n", r, counts[r]);
|
||||
}
|
||||
|
||||
printf("Best Tree: Detected %d graphs in the MST, selected #%d\n", counts.size(), best_graph);
|
||||
|
||||
list<PathNode*> new_nodes;
|
||||
list<PathEdge*> new_edges;
|
||||
|
||||
//rebuild the node list to include only nodes which are in
|
||||
//the best graph, also only keeping the edges which connect them.
|
||||
std::map<PathNode *, int> havenodelist;
|
||||
list<PathEdge*>::iterator cur4,end4;
|
||||
cur4 = big->edges.begin();
|
||||
end4 = big->edges.end();
|
||||
for(; cur4 != end4; cur4++) {
|
||||
PathEdge *e = *cur4;
|
||||
|
||||
//remove the edge if it is not the main color
|
||||
//this also causes the removal of the nodes if they
|
||||
//are not used in any other edges.
|
||||
if(e->from->color != e->to->color) {
|
||||
printf("Miscolor.\n");
|
||||
continue;
|
||||
}
|
||||
if(e->from->color != best_graph) {
|
||||
continue;
|
||||
}
|
||||
if(e->to->color != best_graph) {
|
||||
continue;
|
||||
}
|
||||
|
||||
new_edges.push_back(e);
|
||||
|
||||
if(havenodelist.count(e->from) != 1) {
|
||||
e->from->final_id = new_nodes.size();
|
||||
new_nodes.push_back(e->from);
|
||||
havenodelist[e->from] = 1;
|
||||
}
|
||||
if(havenodelist.count(e->to) != 1) {
|
||||
e->to->final_id = new_nodes.size();
|
||||
new_nodes.push_back(e->to);
|
||||
havenodelist[e->to] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Best Tree: Removed %d nodes and %d edges which were disconnected.\n",
|
||||
big->nodes.size() - new_nodes.size(), big->edges.size() - new_edges.size());
|
||||
big->nodes = new_nodes;
|
||||
big->edges = new_edges;
|
||||
}
|
||||
|
||||
void consolidate_cross_graphs(Map *map, PathGraph *big, PathGraph *excess, MyGraph &cross_graph, const char *fname) {
|
||||
|
||||
vector< vector<int> > D;
|
||||
vector<int> counts;
|
||||
vector<int> disjoint_counts;
|
||||
vector<int> first_node;
|
||||
|
||||
//color the graph and get us the info we need to do our job
|
||||
color_disjoint_graphs(big, cross_graph, map, fname, D, counts, disjoint_counts, first_node);
|
||||
}
|
||||
|
||||
void find_path_info(Map *map, MyGraph &vg, vector< vector<PathEdge*> > &path_finding, PathGraph *big) {
|
||||
//make sure our path finding vector is big enough.
|
||||
{
|
||||
int size = big->nodes.size();
|
||||
vector<PathEdge*> tmp(size, (PathEdge*)NULL);
|
||||
path_finding.resize(0);
|
||||
path_finding.resize(size, tmp);
|
||||
}
|
||||
|
||||
vector< vector<int> > D;
|
||||
vector<int> counts;
|
||||
vector<int> disjoint_counts;
|
||||
vector<int> first_node;
|
||||
|
||||
//color the graph and get us the info we need to do our job
|
||||
color_disjoint_graphs(big, vg, map, NULL, D, counts, disjoint_counts, first_node);
|
||||
|
||||
//figure out what edges link to each node.
|
||||
std::map<PathNode*, vector<PathEdge*> > node_edges;
|
||||
find_node_edges(big, node_edges);
|
||||
|
||||
|
||||
//for each node, find best edge to reach each other node.
|
||||
list<PathNode*>::iterator cur,end;
|
||||
PathNode *n;
|
||||
vector<int>::iterator curp,endp;
|
||||
vector<PathEdge *>::iterator cure,ende;
|
||||
int r;
|
||||
cur = big->nodes.begin();
|
||||
end = big->nodes.end();
|
||||
for(; cur != end; cur++) {
|
||||
n = *cur;
|
||||
//get all our vector refs that we need since this is kinda expensive
|
||||
vector<int> &cv = D[n->node_id]; //distance array
|
||||
vector<PathEdge *> &pf = path_finding[n->node_id]; //result
|
||||
vector<PathEdge *> &el = node_edges[n]; //our edges
|
||||
curp = cv.begin();
|
||||
endp = cv.end();
|
||||
for(r = 0; curp != endp; curp++, r++) {
|
||||
if(n->node_id == r) {
|
||||
//this is the end of the path, we cannot take an edge to reach ourself
|
||||
pf[r] = NULL;
|
||||
continue;
|
||||
}
|
||||
int my_dist = *curp;
|
||||
if(my_dist == INT_MAX) {
|
||||
//this node is unreachable.
|
||||
pf[r] = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
//else, node r reachable from us, find best edge.
|
||||
cure = el.begin();
|
||||
ende = el.end();
|
||||
// int shortest;
|
||||
PathEdge *ce;
|
||||
PathNode *cn;
|
||||
//for each edge
|
||||
for(; cure != ende; cure++) {
|
||||
ce = *cure;
|
||||
//find the node other than ourself on the edge
|
||||
if(ce->from == n)
|
||||
cn = ce->to;
|
||||
else
|
||||
cn = ce->from;
|
||||
//see how far away this node is
|
||||
int cdist = D[cn->node_id][r];
|
||||
if(cdist < my_dist) {
|
||||
//found one which is closer... due to min span tree, there
|
||||
//should only be one path possible so just go with it.
|
||||
pf[r] = ce;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//assume that this node got assigned.. next
|
||||
if(pf[r] == NULL) {
|
||||
printf("Node id %d was not able to find a good path to node %d\n", n->node_id, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user