bouh
This commit is contained in:
parent
a7f31fec2c
commit
002224cc84
|
@ -1,924 +0,0 @@
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
### -------------------------------------------------- ###
|
|
||||||
$Author: hcl $
|
|
||||||
$Date: 2002/03/22 16:04:02 $
|
|
||||||
$Log: ocrAstar.c,v $
|
|
||||||
Revision 1.3 2002/03/22 16:04:02 hcl
|
|
||||||
speedups
|
|
||||||
|
|
||||||
Revision 1.2 2002/03/20 13:25:50 hcl
|
|
||||||
SymX bug.
|
|
||||||
|
|
||||||
Revision 1.1 2002/03/15 14:37:19 hcl
|
|
||||||
Ca roule.
|
|
||||||
|
|
||||||
Revision 1.1 2002/03/15 09:54:16 hcl
|
|
||||||
First commit in the new tree.
|
|
||||||
|
|
||||||
Revision 1.5 2002/02/25 11:41:13 hcl
|
|
||||||
A la chasse au bug bug bug
|
|
||||||
|
|
||||||
Revision 1.4 2002/02/22 15:20:49 hcl
|
|
||||||
A* is ready
|
|
||||||
|
|
||||||
Revision 1.3 2002/02/21 13:17:57 hcl
|
|
||||||
Introducing a new algo (A*, dont yet work...)
|
|
||||||
|
|
||||||
Revision 1.2 2002/02/15 12:06:31 hcl
|
|
||||||
First attempt
|
|
||||||
|
|
||||||
Revision 1.1 2002/02/12 15:14:14 hcl
|
|
||||||
New algo.
|
|
||||||
|
|
||||||
### -------------------------------------------------- ###
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "mut.h"
|
|
||||||
#include "mlo.h"
|
|
||||||
#include "mlu.h"
|
|
||||||
#include "mph.h"
|
|
||||||
#include "mpu.h"
|
|
||||||
#include "ocr.h"
|
|
||||||
#include "ocrUtil.h"
|
|
||||||
#include "ocrWRoutingDataBase.h"
|
|
||||||
#include "ocrWindow.h"
|
|
||||||
#include "mbk_tree.h"
|
|
||||||
#include "ocrWRoutingUtil.h"
|
|
||||||
#include "ocrWRouting.h"
|
|
||||||
#include "display.h"
|
|
||||||
#include "ocrAstar.h"
|
|
||||||
|
|
||||||
extern ocrOption *g_pOption;
|
|
||||||
#define LEVEL (g_pOption->LEVEL)
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
#define TAG_UNDEF 0
|
|
||||||
#define TAG_KEEP 1
|
|
||||||
#define TAG_CLEAN 2
|
|
||||||
#define TAG_FREED 4
|
|
||||||
#define TAG_TERRA 8
|
|
||||||
#define TAG_VISITED 16
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variables globales
|
|
||||||
**/
|
|
||||||
ocrWRoutingGrid *grid = NULL;
|
|
||||||
ocrRoutingParameters *param = NULL;
|
|
||||||
|
|
||||||
ocrNaturalInt xs = 0, ys = 0, zs = 0;
|
|
||||||
ocrNaturalInt CUR_SIG_INDEX = 0;
|
|
||||||
|
|
||||||
//ocrNaturalInt (*kost)(ocrWSegment *, ocrWSegment *);
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Local data structures
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Cost function (Manhattan distance) */
|
|
||||||
ocrNaturalInt eval (ocrWSegment *segment_source, ocrWSegment *segment_dest) {
|
|
||||||
|
|
||||||
ocrNaturalInt x1s, x2s, y1s, y2s, x1d, x2d, y1d, y2d, dx, dy, dz;
|
|
||||||
|
|
||||||
x1s = getWSegXCoord (param, segment_source, segment_source->P_MIN);
|
|
||||||
y1s = getWSegYCoord (param, segment_source, segment_source->P_MIN);
|
|
||||||
x2s = getWSegXCoord (param, segment_source, segment_source->P_MAX);
|
|
||||||
y2s = getWSegYCoord (param, segment_source, segment_source->P_MAX);
|
|
||||||
|
|
||||||
x1d = getWSegXCoord (param, segment_dest, segment_dest->P_MIN);
|
|
||||||
y1d = getWSegYCoord (param, segment_dest, segment_dest->P_MIN);
|
|
||||||
x2d = getWSegXCoord (param, segment_dest, segment_dest->P_MAX);
|
|
||||||
y2d = getWSegYCoord (param, segment_dest, segment_dest->P_MAX);
|
|
||||||
|
|
||||||
dx = ( (x2s < x1d)? (x1d - x2s) : ( (x1s > x2d) ? (x1s - x2d) : 0 ) );
|
|
||||||
dy = ( (y2s < y1d)? (y1d - y2s) : ( (y1s > y2d) ? (y1s - y2d) : 0 ) );
|
|
||||||
|
|
||||||
dz = (
|
|
||||||
(segment_dest->LAYER > segment_source->LAYER) ?
|
|
||||||
segment_dest->LAYER - segment_source->LAYER :
|
|
||||||
segment_source->LAYER - segment_dest->LAYER
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
return (dx + dy) + dz /* param->VIA_COST*/;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Distance between segment and nearest segment of an equi */
|
|
||||||
ocrNaturalInt eval_equi (ocrWSegment *segment_source, ocrWSegment *equi) {
|
|
||||||
ocrNaturalInt res = OCRNATURALINT_MAX;
|
|
||||||
ocrNaturalInt aux;
|
|
||||||
|
|
||||||
/*return 0;*/
|
|
||||||
while (equi) {
|
|
||||||
aux = eval (segment_source, equi);
|
|
||||||
if (aux < res) {
|
|
||||||
res = aux;
|
|
||||||
}
|
|
||||||
equi = equi->NEXT;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* kost of the path from segment_source to segment_dest */
|
|
||||||
ocrNaturalInt kost (ocrWSegment *segment_source, ocrWSegment *segment_dest) {
|
|
||||||
|
|
||||||
ocrWSegment *ps;
|
|
||||||
ocrNaturalInt dest_offset, p;
|
|
||||||
ocrNaturalInt res;
|
|
||||||
|
|
||||||
ps = segment_source->ROOT;
|
|
||||||
dest_offset = segment_dest->OFFSET;
|
|
||||||
|
|
||||||
if (
|
|
||||||
getWSegDirection (param, segment_source)
|
|
||||||
==
|
|
||||||
getWSegDirection (param, segment_dest)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
} else if (ps) {
|
|
||||||
res = (
|
|
||||||
(ps->OFFSET > dest_offset) ?
|
|
||||||
(ps->OFFSET - dest_offset) :
|
|
||||||
(dest_offset - ps->OFFSET)
|
|
||||||
)
|
|
||||||
;
|
|
||||||
res += (
|
|
||||||
(segment_dest->LAYER > segment_source->LAYER) ?
|
|
||||||
100 + segment_dest->LAYER - segment_source->LAYER :
|
|
||||||
segment_source->LAYER - segment_dest->LAYER
|
|
||||||
)
|
|
||||||
/* param->VIA_COST*/
|
|
||||||
;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
p = (getWSegDirection (param, segment_source) == ocrHorizontal) ?
|
|
||||||
xs : ys;
|
|
||||||
|
|
||||||
return
|
|
||||||
(
|
|
||||||
(p > dest_offset) ?
|
|
||||||
(p - dest_offset) :
|
|
||||||
(dest_offset - p)
|
|
||||||
)
|
|
||||||
+
|
|
||||||
(
|
|
||||||
(zs > segment_source->LAYER) ?
|
|
||||||
(zs - segment_source->LAYER) :
|
|
||||||
(segment_source->LAYER - zs)
|
|
||||||
)
|
|
||||||
/*
|
|
||||||
param->VIA_COST*/
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void tag_keep (ocrWSegment *path) {
|
|
||||||
|
|
||||||
while (path) {
|
|
||||||
path->TAG = TAG_KEEP;
|
|
||||||
path = path->ROOT;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stack
|
|
||||||
**/
|
|
||||||
|
|
||||||
ocrWSegment *pop (ocrWSegment **list) {
|
|
||||||
ocrWSegment *res;
|
|
||||||
|
|
||||||
assert (*list);
|
|
||||||
|
|
||||||
res = (*list);
|
|
||||||
(*list) = ( (*list)->AUX );
|
|
||||||
res->AUX = NULL;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push (ocrWSegment **list, ocrWSegment *elem) {
|
|
||||||
|
|
||||||
assert (elem);
|
|
||||||
|
|
||||||
elem->AUX = (*list);
|
|
||||||
(*list) = elem;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* clean_mem
|
|
||||||
**/
|
|
||||||
void clean_tag () {
|
|
||||||
ocrWSegment *seg;
|
|
||||||
int i, j, k;
|
|
||||||
|
|
||||||
for (k = 0 ; k < grid->NB_OF_LAYERS ; k += 2)
|
|
||||||
for (j = 0 ; j < grid->SIZE_V ; j++)
|
|
||||||
for (i = 0 ; i < grid->SIZE_H ; i++) {
|
|
||||||
seg = getWSegment (grid, i, j, k);
|
|
||||||
seg->TAG = TAG_UNDEF;
|
|
||||||
i = seg->P_MAX;
|
|
||||||
#if 0
|
|
||||||
if (
|
|
||||||
(seg->SIGNAL_INDEX != WSEGMENT_FREE)
|
|
||||||
&&
|
|
||||||
(seg->SIGNAL_INDEX != WSEGMENT_OBSTACLE)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (seg->AUX) {
|
|
||||||
display (LEVEL, DEBUG, "AUX not NULL for free or obstacle segment\n");
|
|
||||||
seg->AUX = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
for (k = 1 ; k < grid->NB_OF_LAYERS ; k += 2)
|
|
||||||
for (i = 0 ; i < grid->SIZE_H ; i++)
|
|
||||||
for (j = 0 ; j < grid->SIZE_V ; j++) {
|
|
||||||
seg = getWSegment (grid, i, j, k);
|
|
||||||
seg->TAG = TAG_UNDEF;
|
|
||||||
j = seg->P_MAX;
|
|
||||||
#if 0
|
|
||||||
if (
|
|
||||||
(seg->SIGNAL_INDEX != WSEGMENT_FREE)
|
|
||||||
&&
|
|
||||||
(seg->SIGNAL_INDEX != WSEGMENT_OBSTACLE)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (seg->AUX) {
|
|
||||||
display (LEVEL, DEBUG, "AUX not NULL for free or obstacle segment\n");
|
|
||||||
seg->AUX = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clean_tag_list (ocrWSegment *list) {
|
|
||||||
|
|
||||||
while (list) {
|
|
||||||
list->TAG = TAG_UNDEF;
|
|
||||||
list = list->AUX;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* insert elem keeping the list sorted by increasing cost+h
|
|
||||||
**/
|
|
||||||
ocrWSegment *insert (ocrWSegment *list, ocrWSegment *elem) {
|
|
||||||
ocrWSegment *prec, *rval;
|
|
||||||
|
|
||||||
assert (elem);
|
|
||||||
|
|
||||||
if (!list) {
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return elem;
|
|
||||||
} else if (!(list->AUX)) {
|
|
||||||
if ( elem->HCOST < list->HCOST ) {
|
|
||||||
elem->AUX = list;
|
|
||||||
return elem;
|
|
||||||
} else if ( elem->HCOST == list->HCOST ) {
|
|
||||||
if ( elem->COST < list->COST ) {
|
|
||||||
elem->AUX = list;
|
|
||||||
return elem;
|
|
||||||
} else {
|
|
||||||
list->AUX = elem;
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
list->AUX = elem;
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rval = list;
|
|
||||||
prec = list;
|
|
||||||
list = list->AUX;
|
|
||||||
|
|
||||||
while (list) {
|
|
||||||
|
|
||||||
if ( elem->HCOST < list->HCOST ) {
|
|
||||||
elem->AUX = list;
|
|
||||||
prec->AUX = elem;
|
|
||||||
return rval;
|
|
||||||
} else if ( elem->HCOST == list->HCOST ) {
|
|
||||||
if ( elem->COST < list->COST ) {
|
|
||||||
prec->AUX = elem;
|
|
||||||
elem->AUX = list;
|
|
||||||
return rval;
|
|
||||||
} else {
|
|
||||||
prec = list;
|
|
||||||
list = list->AUX;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
prec = list;
|
|
||||||
list = list->AUX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
prec->AUX = elem;
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ocrWSegment *_remove (ocrWSegment *list, ocrWSegment *elem) {
|
|
||||||
ocrWSegment *prec;
|
|
||||||
ocrWSegment *orig;
|
|
||||||
|
|
||||||
assert (elem);
|
|
||||||
|
|
||||||
if (!list)
|
|
||||||
return list;
|
|
||||||
if (elem == list) {
|
|
||||||
ocrWSegment *res = elem->AUX;
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
orig = list;
|
|
||||||
do {
|
|
||||||
prec = list;
|
|
||||||
list = list->AUX;
|
|
||||||
if (elem == list) {
|
|
||||||
prec->AUX = list->AUX;
|
|
||||||
elem->AUX = NULL;
|
|
||||||
return orig;
|
|
||||||
}
|
|
||||||
} while (list);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
list->AUX = _remove (list->AUX, elem);
|
|
||||||
return list;
|
|
||||||
#endif
|
|
||||||
return orig;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define XPLORE \
|
|
||||||
{\
|
|
||||||
if (isObstructed (seg))\
|
|
||||||
if (seg->SIGNAL_INDEX != CUR_SIG_INDEX)\
|
|
||||||
continue;\
|
|
||||||
\
|
|
||||||
cost = node->COST + kost (node, seg); /* XXX cout du chemin parcouru ??? */\
|
|
||||||
\
|
|
||||||
switch (seg->TAG) {\
|
|
||||||
case TAG_UNDEF: /* not yet seen segment */\
|
|
||||||
seg->ROOT = node;\
|
|
||||||
seg->COST = cost;\
|
|
||||||
seg->H = eval_equi (seg, segment_target);\
|
|
||||||
seg->HCOST = seg->H + cost;\
|
|
||||||
seg->TAG = TAG_TERRA;\
|
|
||||||
terra_incognita = insert (terra_incognita, seg);\
|
|
||||||
break;\
|
|
||||||
case TAG_TERRA:\
|
|
||||||
if (cost < seg->COST) {\
|
|
||||||
seg->COST = cost;\
|
|
||||||
seg->HCOST = seg->H + cost;\
|
|
||||||
seg->ROOT = node;\
|
|
||||||
terra_incognita = _remove (terra_incognita, seg);\
|
|
||||||
terra_incognita = insert (terra_incognita, seg);\
|
|
||||||
} else {\
|
|
||||||
/* rien */\
|
|
||||||
}\
|
|
||||||
break;\
|
|
||||||
case TAG_VISITED:\
|
|
||||||
if (cost < seg->COST) {\
|
|
||||||
seg->COST = cost;\
|
|
||||||
seg->HCOST = seg->H + cost;\
|
|
||||||
seg->ROOT = node;\
|
|
||||||
visited = _remove (visited, seg);\
|
|
||||||
seg->TAG = TAG_TERRA;\
|
|
||||||
terra_incognita = insert (terra_incognita, seg);\
|
|
||||||
} else {\
|
|
||||||
/* rien */\
|
|
||||||
}\
|
|
||||||
break;\
|
|
||||||
default:\
|
|
||||||
display (LEVEL, ERROR, "*** unexpected TAG !!!\n");\
|
|
||||||
abort ();\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ocrWSegment *explore (ocrWSegment *segment_source, ocrWSegment *segment_target) {
|
|
||||||
|
|
||||||
ocrWSegment *visited = NULL;
|
|
||||||
ocrWSegment *terra_incognita = NULL;
|
|
||||||
ocrNaturalInt p, cost;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert (segment_source != segment_target);
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "d starting exploration\n");
|
|
||||||
|
|
||||||
terra_incognita = segment_source;
|
|
||||||
terra_incognita->COST = 0;
|
|
||||||
terra_incognita->H = eval (segment_source, segment_target);
|
|
||||||
terra_incognita->HCOST = terra_incognita->H;
|
|
||||||
terra_incognita->TAG = TAG_TERRA;
|
|
||||||
terra_incognita->ROOT = NULL;
|
|
||||||
terra_incognita->AUX = NULL;
|
|
||||||
|
|
||||||
while (terra_incognita) {
|
|
||||||
ocrWSegment *node = NULL;
|
|
||||||
ocrWSegment *seg = NULL;
|
|
||||||
|
|
||||||
node = pop (&terra_incognita);
|
|
||||||
|
|
||||||
if (node == segment_target) {
|
|
||||||
/* bingo ! */
|
|
||||||
clean_tag_list (visited);
|
|
||||||
clean_tag_list (terra_incognita);
|
|
||||||
node->TAG = TAG_UNDEF;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->TAG = TAG_VISITED;
|
|
||||||
push (&visited, node);
|
|
||||||
|
|
||||||
/* expansion */
|
|
||||||
for (i = -1 ; i <= 1 ; i += 2) {
|
|
||||||
switch (i) {
|
|
||||||
|
|
||||||
case -1: if ( ((node->LAYER) ) == 0 )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case 1: if ( ((node->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
for (p = node->P_MIN ; p <= node->P_MAX ; p++) {
|
|
||||||
|
|
||||||
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
|
|
||||||
seg = getWSegment(grid,
|
|
||||||
getWSegXCoord (param, node, p),
|
|
||||||
getWSegYCoord (param, node, p),
|
|
||||||
node->LAYER + i
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!seg) {
|
|
||||||
display (LEVEL, DEBUG, "oddity: null seg at (%ld, %ld, %ld)\n", getWSegXCoord(param, node, p), getWSegXCoord(param, node, p), node->LAYER + i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (isObstructed (seg))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cost = node->COST + kost (node, seg); /* XXX cout du chemin parcouru ??? */
|
|
||||||
|
|
||||||
switch (seg->TAG) {
|
|
||||||
case TAG_UNDEF: /* not yet seen segment */
|
|
||||||
seg->ROOT = node;
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->H = eval (seg, segment_target);
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->TAG = TAG_TERRA;
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
break;
|
|
||||||
case TAG_TERRA:
|
|
||||||
if (cost < seg->COST) {
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->ROOT = node;
|
|
||||||
terra_incognita = _remove (terra_incognita, seg);
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
} else {
|
|
||||||
/* rien */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TAG_VISITED:
|
|
||||||
if (cost < seg->COST) {
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->ROOT = node;
|
|
||||||
visited = _remove (visited, seg);
|
|
||||||
seg->TAG = TAG_TERRA;
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
} else {
|
|
||||||
/* rien */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
display (LEVEL, ERROR, "*** unexpected TAG !!!\n");
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* end for i */
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
/* Failed */
|
|
||||||
clean_tag ();
|
|
||||||
|
|
||||||
/*isplay (LEVEL, DEBUG, "d exploration failed\n");*/
|
|
||||||
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void addseglist (ocrSignal *s, ocrWSegment *l2) {
|
|
||||||
ocrWSegment *l1;
|
|
||||||
|
|
||||||
if (!(s->SEGMENT))
|
|
||||||
s->SEGMENT = l2;
|
|
||||||
else {
|
|
||||||
l1 = s->SEGMENT;
|
|
||||||
while (l1->NEXT)
|
|
||||||
l1 = l1->NEXT;
|
|
||||||
l1->NEXT = l2;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_target) {
|
|
||||||
|
|
||||||
ocrWSegment *visited = NULL;
|
|
||||||
ocrWSegment *terra_incognita = NULL;
|
|
||||||
ocrNaturalInt p, cost;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert (segment_source != segment_target);
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "d starting exploration\n");
|
|
||||||
|
|
||||||
terra_incognita = segment_source;
|
|
||||||
terra_incognita->COST = 0;
|
|
||||||
terra_incognita->H = eval_equi (segment_source, segment_target);
|
|
||||||
terra_incognita->HCOST = terra_incognita->H;
|
|
||||||
terra_incognita->TAG = TAG_TERRA;
|
|
||||||
terra_incognita->ROOT = NULL;
|
|
||||||
terra_incognita->AUX = NULL;
|
|
||||||
|
|
||||||
while (terra_incognita) {
|
|
||||||
ocrWSegment *node = NULL;
|
|
||||||
ocrWSegment *seg = NULL;
|
|
||||||
|
|
||||||
node = pop (&terra_incognita);
|
|
||||||
|
|
||||||
if (node->SIGNAL_INDEX == CUR_SIG_INDEX) {
|
|
||||||
/* on a gagne */
|
|
||||||
clean_tag_list (visited);
|
|
||||||
clean_tag_list (terra_incognita);
|
|
||||||
node->TAG = TAG_UNDEF;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->TAG = TAG_VISITED;
|
|
||||||
push (&visited, node);
|
|
||||||
|
|
||||||
/* expansion */
|
|
||||||
if (getWSegDirection (param, node) == ocrHorizontal) {
|
|
||||||
if ( (node->P_MIN) > 0 ) {
|
|
||||||
seg = getWSegment (grid, node->P_MIN - 1, node->OFFSET, node->LAYER);
|
|
||||||
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
|
|
||||||
XPLORE
|
|
||||||
}
|
|
||||||
if ( (node->P_MAX) < (grid->SIZE_H - 2) ) {
|
|
||||||
seg = getWSegment (grid, node->P_MAX + 1, node->OFFSET, node->LAYER);
|
|
||||||
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
|
|
||||||
XPLORE
|
|
||||||
}
|
|
||||||
} else { /* vertical */
|
|
||||||
if ( (node->P_MIN) > 0 ) {
|
|
||||||
seg = getWSegment (grid, node->OFFSET, node->P_MIN - 1, node->LAYER);
|
|
||||||
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
|
|
||||||
XPLORE
|
|
||||||
}
|
|
||||||
if ( (node->P_MAX) < (grid->SIZE_V - 2) ) {
|
|
||||||
seg = getWSegment (grid, node->OFFSET, node->P_MAX + 1, node->LAYER);
|
|
||||||
if (seg->SIGNAL_INDEX == CUR_SIG_INDEX)
|
|
||||||
XPLORE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = -1 ; i <= 1 ; i += 2) {
|
|
||||||
switch (i) {
|
|
||||||
|
|
||||||
case -1: if ( ((node->LAYER) ) == 0 )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case 1: if ( ((node->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
for (p = node->P_MIN ; p <= node->P_MAX ; p++) {
|
|
||||||
|
|
||||||
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
|
|
||||||
seg = getWSegment(grid,
|
|
||||||
getWSegXCoord (param, node, p),
|
|
||||||
getWSegYCoord (param, node, p),
|
|
||||||
node->LAYER + i
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!seg) {
|
|
||||||
display (LEVEL, DEBUG, "oddity: null seg at (%ld, %ld, %ld)\n", getWSegXCoord(param, node, p), getWSegXCoord(param, node, p), node->LAYER + i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
XPLORE
|
|
||||||
}
|
|
||||||
} /* end for i */
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
/* Failed */
|
|
||||||
clean_tag ();
|
|
||||||
|
|
||||||
/*isplay (LEVEL, DEBUG, "d exploration failed\n");*/
|
|
||||||
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ocrNaturalInt make_segments (ocrWSegment *segment_dest,
|
|
||||||
ocrWSegment *segment_source,
|
|
||||||
ocrNaturalInt xdest,
|
|
||||||
ocrNaturalInt ydest,
|
|
||||||
ocrNaturalInt zdest,
|
|
||||||
ocrNaturalInt signal_index,
|
|
||||||
ocrSignal * i_pSignal
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ocrWSegment *seg, *nseg, *root, *aux;
|
|
||||||
ocrNaturalInt xp, yp, xn, yn;
|
|
||||||
ocrNaturalInt p1, p2, pp1, pp2;
|
|
||||||
/*ocrNaturalInt pi;*/
|
|
||||||
ocrNaturalInt distance = 0;
|
|
||||||
ocrNaturalInt nb_segs = 0;
|
|
||||||
|
|
||||||
/* initialisation */
|
|
||||||
|
|
||||||
aux = i_pSignal->SEGMENT;
|
|
||||||
|
|
||||||
seg = segment_dest;
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "c dest (%ld, %ld, %ld)\n", xdest, ydest, zdest);
|
|
||||||
xp = xdest;
|
|
||||||
yp = ydest;
|
|
||||||
|
|
||||||
if (seg->SIGNAL_INDEX == signal_index) {
|
|
||||||
display (LEVEL, DEBUG, "c joining equi at seg (off=%ld, p_min=%ld, p_max=%ld)\n", seg->OFFSET, seg->P_MIN, seg->P_MAX);
|
|
||||||
|
|
||||||
if (
|
|
||||||
getWSegDirection (param, seg)
|
|
||||||
==
|
|
||||||
getWSegDirection (param, seg->ROOT)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
xp = getWSegXCoord (param, seg, seg->P_MIN);
|
|
||||||
yp = getWSegYCoord (param, seg, seg->P_MIN);
|
|
||||||
} else {
|
|
||||||
xp = getWSegXCoord (param, seg, seg->ROOT->OFFSET);
|
|
||||||
yp = getWSegYCoord (param, seg, seg->ROOT->OFFSET);
|
|
||||||
}
|
|
||||||
nseg = seg->ROOT;
|
|
||||||
seg->ROOT = NULL;
|
|
||||||
seg = nseg;
|
|
||||||
}
|
|
||||||
nseg = NULL;
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
seg, seg->ROOT
|
|
||||||
nseg <= split (seg)
|
|
||||||
|
|
||||||
nseg -> NEXT = prevseg;
|
|
||||||
prevseg = nseg;
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (seg->ROOT) {
|
|
||||||
root = seg->ROOT;
|
|
||||||
xn = getWSegXCoord (param, root, xp);
|
|
||||||
yn = getWSegYCoord (param, root, yp);
|
|
||||||
display (LEVEL, DEBUG, "p (%ld, %ld, %ld) -> (%ld, %ld, %ld) : d=%ld, c=%ld, h=%ld, hc=%ld\n", xp, yp, seg->LAYER, xn, yn, seg->LAYER, distance, seg->COST, seg->H, seg->HCOST);
|
|
||||||
((getWSegDirection(param, seg) == ocrHorizontal) ? (p1 = xp, p2 = xn) : (p1 = yp, p2 = yn) );
|
|
||||||
( (p1 < p2) ? (pp1 = p1, pp2 = p2) : (pp1 = p2, pp2 = p1) );
|
|
||||||
nseg = splitWSegment (param, grid, seg,
|
|
||||||
pp1, pp2,
|
|
||||||
signal_index
|
|
||||||
);
|
|
||||||
nseg->NEXT = aux;
|
|
||||||
aux = nseg;
|
|
||||||
distance += (pp2 - pp1);
|
|
||||||
nb_segs ++;
|
|
||||||
xp = xn;
|
|
||||||
yp = yn;
|
|
||||||
/*seg->SIGNAL_INDEX = signal_index;*/
|
|
||||||
seg = root;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*assert (nseg == segment_source);*/
|
|
||||||
xn = xs;
|
|
||||||
yn = ys;
|
|
||||||
/*root = seg->ROOT;*/
|
|
||||||
((getWSegDirection(param, seg) == ocrHorizontal) ? (p1 = xp, p2 = xn) : (p1 = yp, p2 = yn) );
|
|
||||||
( (p1 < p2) ? (pp1 = p1, pp2 = p2) : (pp1 = p2, pp2 = p1) );
|
|
||||||
nseg = splitWSegment (param, grid, seg,
|
|
||||||
pp1, pp2,
|
|
||||||
signal_index
|
|
||||||
);
|
|
||||||
nseg->NEXT = aux;
|
|
||||||
i_pSignal->SEGMENT = nseg;
|
|
||||||
|
|
||||||
distance += (pp2 - pp1);
|
|
||||||
nb_segs ++;
|
|
||||||
display (LEVEL, DEBUG, "p (%ld, %ld, %ld) -> (%ld, %ld, %ld) : %ld\n", xp, yp, seg->LAYER, xn, yn, zs, distance);
|
|
||||||
display (LEVEL, DEBUG, "c source (%ld, %ld, %ld)\n", xs, ys, zs);
|
|
||||||
display (LEVEL, DEBUG, "p num of segments : %ld\n", nb_segs);
|
|
||||||
/*seg->SIGNAL_INDEX = signal_index;*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "i path length : %ld\n", distance);
|
|
||||||
|
|
||||||
return distance * 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ocrNaturalInt check_path (ocrSignal *i_pSignal) {
|
|
||||||
|
|
||||||
ocrWSegment *seg;
|
|
||||||
ocrNaturalInt dist;
|
|
||||||
|
|
||||||
seg = i_pSignal->SEGMENT;
|
|
||||||
|
|
||||||
dist = 0;
|
|
||||||
|
|
||||||
while (seg) {
|
|
||||||
if ( (seg->SIGNAL_INDEX) != (i_pSignal->INDEX) ) {
|
|
||||||
display (LEVEL, ERROR, " ---INVALID Segment->SIGNAL_INDEX\n");
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "(%ld, %ld, %ld, %ld)\n", seg->OFFSET, seg->P_MIN, seg->P_MAX, seg->LAYER);
|
|
||||||
|
|
||||||
dist += seg->P_MAX - seg->P_MIN;
|
|
||||||
|
|
||||||
seg = seg->NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "DIST CHECK --- %ld\n", dist);
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
|
||||||
ocrWRoutingGrid * p_grid,
|
|
||||||
ocrNaturalInt xsource,
|
|
||||||
ocrNaturalInt ysource,
|
|
||||||
ocrNaturalInt zsource,
|
|
||||||
ocrNaturalInt xtarget,
|
|
||||||
ocrNaturalInt ytarget,
|
|
||||||
ocrNaturalInt ztarget,
|
|
||||||
ocrNaturalInt signal_index,
|
|
||||||
ocrSignal * i_pSignal,
|
|
||||||
ocrNaturalInt mode)
|
|
||||||
{
|
|
||||||
ocrWSegment *path = NULL;
|
|
||||||
ocrWSegment *segment_source = NULL;
|
|
||||||
ocrWSegment *segment_dest = NULL;
|
|
||||||
ocrNaturalInt dist, check_dist;
|
|
||||||
|
|
||||||
grid = p_grid;
|
|
||||||
param = p_param;
|
|
||||||
|
|
||||||
xs = xsource;
|
|
||||||
ys = ysource;
|
|
||||||
zs = zsource;
|
|
||||||
|
|
||||||
CUR_SIG_INDEX = signal_index;
|
|
||||||
/*clean_tag ();*/
|
|
||||||
|
|
||||||
/*kost = (
|
|
||||||
(mode == AS_K_EQUI) ?
|
|
||||||
&eval :
|
|
||||||
&eval_equi
|
|
||||||
)
|
|
||||||
;*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
segment_source = getWSegment (grid,
|
|
||||||
xsource,
|
|
||||||
ysource,
|
|
||||||
zsource
|
|
||||||
);
|
|
||||||
/* display (LEVEL, DEBUG, "d source : %p\n", segment_source); */
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case AS_K_SEG:
|
|
||||||
segment_dest = getWSegment (grid,
|
|
||||||
xtarget,
|
|
||||||
ytarget,
|
|
||||||
ztarget
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case AS_K_EQUI:
|
|
||||||
segment_dest = i_pSignal->SEGMENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*display (LEVEL, DEBUG, "d dest : %p\n", segment_dest);*/
|
|
||||||
|
|
||||||
if ((segment_source != segment_dest) && (!isObstructed(segment_source))) {
|
|
||||||
switch (mode) {
|
|
||||||
case AS_K_SEG: path = explore (segment_source, segment_dest);
|
|
||||||
break;
|
|
||||||
case AS_K_EQUI: assert (i_pSignal->SEGMENT);
|
|
||||||
path = explore_equi (segment_source, segment_dest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
path = segment_source;
|
|
||||||
path->ROOT = NULL;
|
|
||||||
path->NEXT = NULL;
|
|
||||||
/*display (LEVEL, DEBUG, "o direct link\n");*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!path) {
|
|
||||||
display (LEVEL, DEBUG, "o A* failed\n");
|
|
||||||
return OCRNATURALINT_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "o A* succeeded\n");
|
|
||||||
|
|
||||||
/*clean_tag ();*/
|
|
||||||
|
|
||||||
dist = make_segments (
|
|
||||||
path,
|
|
||||||
segment_source,
|
|
||||||
xtarget,
|
|
||||||
ytarget,
|
|
||||||
ztarget,
|
|
||||||
signal_index,
|
|
||||||
i_pSignal
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*assert (((check_dist = check_path (i_pSignal)), dist == check_dist));*/
|
|
||||||
|
|
||||||
return dist;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
/*void init_Astar (ocrRoutingDataBase *db) {
|
|
||||||
assert (db);
|
|
||||||
|
|
||||||
grid = db->GRID;
|
|
||||||
param = db->PARAM;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,3 +1,16 @@
|
||||||
|
/*
|
||||||
|
### -------------------------------------------------- ###
|
||||||
|
$Author: hcl $
|
||||||
|
$Date: 2002/04/10 12:56:54 $
|
||||||
|
|
||||||
|
$Log: ocrAstar.cpp,v $
|
||||||
|
Revision 1.2 2002/04/10 12:56:54 hcl
|
||||||
|
bouh
|
||||||
|
|
||||||
|
|
||||||
|
### -------------------------------------------------- ###
|
||||||
|
*/
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -13,6 +26,7 @@ extern "C" {
|
||||||
#include "mbk_tree.h"
|
#include "mbk_tree.h"
|
||||||
#include "ocrWRoutingUtil.h"
|
#include "ocrWRoutingUtil.h"
|
||||||
#include "ocrWRouting.h"
|
#include "ocrWRouting.h"
|
||||||
|
#include "ocrNpoints.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "ocrAstar.h"
|
#include "ocrAstar.h"
|
||||||
}
|
}
|
||||||
|
@ -65,6 +79,8 @@ typedef set<ocrWSegment *> ocrSegmentAdrSet;
|
||||||
/**
|
/**
|
||||||
* Variables globales
|
* Variables globales
|
||||||
**/
|
**/
|
||||||
|
ocrRoutingDataBase *ocr_db = NULL;
|
||||||
|
|
||||||
ocrWRoutingGrid *grid = NULL;
|
ocrWRoutingGrid *grid = NULL;
|
||||||
ocrRoutingParameters *param = NULL;
|
ocrRoutingParameters *param = NULL;
|
||||||
|
|
||||||
|
@ -72,6 +88,7 @@ ocrNaturalInt xs = 0, ys = 0, zs = 0;
|
||||||
ocrNaturalInt CUR_SIG_INDEX = 0;
|
ocrNaturalInt CUR_SIG_INDEX = 0;
|
||||||
|
|
||||||
ocrWSegment *ze_best = NULL;
|
ocrWSegment *ze_best = NULL;
|
||||||
|
ocrWSegment *ze_target = NULL;
|
||||||
|
|
||||||
//ocrNaturalInt (*kost)(ocrWSegment *, ocrWSegment *);
|
//ocrNaturalInt (*kost)(ocrWSegment *, ocrWSegment *);
|
||||||
|
|
||||||
|
@ -174,14 +191,15 @@ ocrNaturalInt kost (ocrWSegment *segment_source, ocrWSegment *segment_dest) {
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#if 1
|
||||||
p = (getWSegDirection (param, segment_source) == ocrHorizontal) ?
|
p = (getWSegDirection (param, segment_source) == ocrHorizontal) ?
|
||||||
xs : ys;
|
xs : ys;
|
||||||
#endif
|
#else
|
||||||
/* perf optim... */
|
/* perf optim... */
|
||||||
p = ( !(segment_source->LAYER & ((ocrNaturalInt) 1)) ) ?
|
p = ( (segment_source->LAYER & ((ocrNaturalInt) 1)) ) ?
|
||||||
xs : ys
|
xs : ys
|
||||||
;
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
return
|
return
|
||||||
(
|
(
|
||||||
|
@ -360,145 +378,6 @@ void clean_tag_set (ocrSegmentKeySet &set) {
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
ocrWSegment *explore (ocrWSegment *segment_source, ocrWSegment *segment_target) {
|
|
||||||
|
|
||||||
ocrWSegment *visited = NULL;
|
|
||||||
ocrWSegment *terra_incognita = NULL;
|
|
||||||
ocrNaturalInt p, cost;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert (segment_source != segment_target);
|
|
||||||
|
|
||||||
display (LEVEL, DEBUG, "d starting exploration\n");
|
|
||||||
|
|
||||||
terra_incognita = segment_source;
|
|
||||||
terra_incognita->COST = 0;
|
|
||||||
terra_incognita->H = eval (segment_source, segment_target);
|
|
||||||
terra_incognita->HCOST = terra_incognita->H;
|
|
||||||
terra_incognita->TAG = TAG_TERRA;
|
|
||||||
terra_incognita->ROOT = NULL;
|
|
||||||
terra_incognita->AUX = NULL;
|
|
||||||
|
|
||||||
while (terra_incognita) {
|
|
||||||
ocrWSegment *node = NULL;
|
|
||||||
ocrWSegment *seg = NULL;
|
|
||||||
|
|
||||||
node = pop (&terra_incognita);
|
|
||||||
|
|
||||||
if (node == segment_target) {
|
|
||||||
/* bingo ! */
|
|
||||||
clean_tag_list (visited);
|
|
||||||
clean_tag_list (terra_incognita);
|
|
||||||
node->TAG = TAG_UNDEF;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
node->TAG = TAG_VISITED;
|
|
||||||
push (&visited, node);
|
|
||||||
|
|
||||||
/* expansion */
|
|
||||||
for (i = -1 ; i <= 1 ; i += 2) {
|
|
||||||
switch (i) {
|
|
||||||
|
|
||||||
case -1: if ( ((node->LAYER) ) == 0 )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
case 1: if ( ((node->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
|
|
||||||
continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
for (p = node->P_MIN ; p <= node->P_MAX ; p++) {
|
|
||||||
|
|
||||||
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
|
|
||||||
seg = getWSegment(grid,
|
|
||||||
getWSegXCoord (param, node, p),
|
|
||||||
getWSegYCoord (param, node, p),
|
|
||||||
node->LAYER + i
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!seg) {
|
|
||||||
display (LEVEL, DEBUG, "oddity: null seg at (%ld, %ld, %ld)\n", getWSegXCoord(param, node, p), getWSegXCoord(param, node, p), node->LAYER + i);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (isObstructed (seg))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cost = node->COST + kost (node, seg); /* XXX cout du chemin parcouru ??? */
|
|
||||||
|
|
||||||
switch (seg->TAG) {
|
|
||||||
case TAG_UNDEF: /* not yet seen segment */
|
|
||||||
seg->ROOT = node;
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->H = eval (seg, segment_target);
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->TAG = TAG_TERRA;
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
break;
|
|
||||||
case TAG_TERRA:
|
|
||||||
if (cost < seg->COST) {
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->ROOT = node;
|
|
||||||
terra_incognita = _remove (terra_incognita, seg);
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
} else {
|
|
||||||
/* rien */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TAG_VISITED:
|
|
||||||
if (cost < seg->COST) {
|
|
||||||
seg->COST = cost;
|
|
||||||
seg->HCOST = seg->H + cost;
|
|
||||||
seg->ROOT = node;
|
|
||||||
visited = _remove (visited, seg);
|
|
||||||
seg->TAG = TAG_TERRA;
|
|
||||||
terra_incognita = insert (terra_incognita, seg);
|
|
||||||
} else {
|
|
||||||
/* rien */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
display (LEVEL, ERROR, "*** unexpected TAG !!!\n");
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* end for i */
|
|
||||||
} /* while */
|
|
||||||
|
|
||||||
/* Failed */
|
|
||||||
clean_tag ();
|
|
||||||
|
|
||||||
/*isplay (LEVEL, DEBUG, "d exploration failed\n");*/
|
|
||||||
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void addseglist (ocrSignal *s, ocrWSegment *l2) {
|
|
||||||
ocrWSegment *l1;
|
|
||||||
|
|
||||||
if (!(s->SEGMENT))
|
|
||||||
s->SEGMENT = l2;
|
|
||||||
else {
|
|
||||||
l1 = s->SEGMENT;
|
|
||||||
while (l1->NEXT)
|
|
||||||
l1 = l1->NEXT;
|
|
||||||
l1->NEXT = l2;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_target) {
|
ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_target) {
|
||||||
|
|
||||||
ocrNaturalInt cost;
|
ocrNaturalInt cost;
|
||||||
|
@ -511,10 +390,11 @@ ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_tar
|
||||||
|
|
||||||
segment_source->COST = 0;
|
segment_source->COST = 0;
|
||||||
segment_source->H = eval_equi (segment_source, segment_target);
|
segment_source->H = eval_equi (segment_source, segment_target);
|
||||||
segment_source->HCOST = segment_source->H;
|
segment_source->HCOST = segment_source->H + 1000000;
|
||||||
segment_source->TAG = TAG_TERRA;
|
segment_source->TAG = TAG_TERRA;
|
||||||
segment_source->ROOT = NULL;
|
segment_source->ROOT = NULL;
|
||||||
segment_source->AUX = NULL;
|
segment_source->AUX = NULL;
|
||||||
|
ze_best = segment_source;
|
||||||
|
|
||||||
terra_incognita.insert(segment_source);
|
terra_incognita.insert(segment_source);
|
||||||
|
|
||||||
|
@ -531,7 +411,6 @@ ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_tar
|
||||||
if (node->SIGNAL_INDEX == CUR_SIG_INDEX) {
|
if (node->SIGNAL_INDEX == CUR_SIG_INDEX) {
|
||||||
/* on a gagne */
|
/* on a gagne */
|
||||||
|
|
||||||
// XXX FIXME
|
|
||||||
clean_tag_list (visited);
|
clean_tag_list (visited);
|
||||||
clean_tag_set (terra_incognita);
|
clean_tag_set (terra_incognita);
|
||||||
node->TAG = TAG_UNDEF;
|
node->TAG = TAG_UNDEF;
|
||||||
|
@ -541,6 +420,10 @@ ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_tar
|
||||||
node->TAG = TAG_VISITED;
|
node->TAG = TAG_VISITED;
|
||||||
visited.insert(node);
|
visited.insert(node);
|
||||||
|
|
||||||
|
/* enregistrement */
|
||||||
|
if (node->H < ze_best->H)
|
||||||
|
ze_best = node;
|
||||||
|
|
||||||
/* expansion */
|
/* expansion */
|
||||||
if (getWSegDirection (param, node) == ocrHorizontal) {
|
if (getWSegDirection (param, node) == ocrHorizontal) {
|
||||||
if ( (node->P_MIN) > 0 ) {
|
if ( (node->P_MIN) > 0 ) {
|
||||||
|
@ -609,7 +492,127 @@ ocrWSegment *explore_equi (ocrWSegment *segment_source, ocrWSegment *segment_tar
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ocrSignal *findSignal(ocrNaturalInt i_uIndex)
|
||||||
|
{
|
||||||
|
ocrNaturalInt i;
|
||||||
|
|
||||||
|
if (i_uIndex == OCRNATURALINT_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < ocr_db->NB_GSIGNAL - 1; i++) {
|
||||||
|
if (ocr_db->GSIGNAL[i]->INDEX == i_uIndex)
|
||||||
|
return ocr_db->GSIGNAL[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define INTERROGE if ( \
|
||||||
|
(suspect->SIGNAL_INDEX != CUR_SIG_INDEX) \
|
||||||
|
&& \
|
||||||
|
(suspect->SIGNAL_INDEX != WSEGMENT_OBSTACLE) \
|
||||||
|
&& \
|
||||||
|
(suspect->SIGNAL_INDEX != WSEGMENT_FREE) \
|
||||||
|
&& \
|
||||||
|
(suspect->TAG != TAG_TERRA) \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
suspect->TAG = TAG_TERRA; \
|
||||||
|
suspect->COST = ze_best->COST + kost (ze_best, suspect); \
|
||||||
|
suspect->H = eval_equi (suspect, ze_target); \
|
||||||
|
suspects.insert (suspect); \
|
||||||
|
}
|
||||||
|
|
||||||
|
void dig_around () {
|
||||||
|
ocrWSegment *suspect;
|
||||||
|
ocrSignal *victime;
|
||||||
|
|
||||||
|
ocrSegmentKeySet suspects;
|
||||||
|
|
||||||
|
/* expansion */
|
||||||
|
if (getWSegDirection (param, ze_best) == ocrHorizontal) {
|
||||||
|
if ( (ze_best->P_MIN) > 0 ) {
|
||||||
|
suspect = getWSegment (grid, ze_best->P_MIN - 1, ze_best->OFFSET, ze_best->LAYER);
|
||||||
|
INTERROGE
|
||||||
|
}
|
||||||
|
if ( (ze_best->P_MAX) < (grid->SIZE_H - 2) ) {
|
||||||
|
suspect = getWSegment (grid, ze_best->P_MAX + 1, ze_best->OFFSET, ze_best->LAYER);
|
||||||
|
INTERROGE
|
||||||
|
}
|
||||||
|
} else { /* vertical */
|
||||||
|
if ( (ze_best->P_MIN) > 0 ) {
|
||||||
|
suspect = getWSegment (grid, ze_best->OFFSET, ze_best->P_MIN - 1, ze_best->LAYER);
|
||||||
|
INTERROGE
|
||||||
|
}
|
||||||
|
if ( (ze_best->P_MAX) < (grid->SIZE_V - 2) ) {
|
||||||
|
suspect = getWSegment (grid, ze_best->OFFSET, ze_best->P_MAX + 1, ze_best->LAYER);
|
||||||
|
INTERROGE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = -1 ; i <= 1 ; i += 2) {
|
||||||
|
switch (i) {
|
||||||
|
|
||||||
|
case -1: if ( ((ze_best->LAYER) ) == 0 )
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case 1: if ( ((ze_best->LAYER) + 1) >= (grid->NB_OF_LAYERS) )
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*display (LEVEL, ERROR, __FILE__ ":" __LINE__ "exand_eval Oops\n");*/
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
for (ocrNaturalInt p = ze_best->P_MIN ; p <= ze_best->P_MAX ; p++) {
|
||||||
|
|
||||||
|
/*display (LEVEL, DEBUG, "d expanding %ld\n", i);*/
|
||||||
|
suspect = getWSegment(grid,
|
||||||
|
getWSegXCoord (param, ze_best, p),
|
||||||
|
getWSegYCoord (param, ze_best, p),
|
||||||
|
ze_best->LAYER + i
|
||||||
|
);
|
||||||
|
INTERROGE
|
||||||
|
}
|
||||||
|
} /* end for i */
|
||||||
|
|
||||||
|
if (suspects.empty()) {
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
victime = findSignal((*suspects.begin())->SIGNAL_INDEX);
|
||||||
|
suspects.erase (suspects.begin());
|
||||||
|
|
||||||
|
deleteEquipotentielle(param, grid, victime);
|
||||||
|
|
||||||
|
if (victime) {
|
||||||
|
ocr_db->RIPUP = addchain (ocr_db->RIPUP, (void *) victime);
|
||||||
|
deleteEquipotentielle(param, grid, victime);
|
||||||
|
victime->SEGMENT = NULL;
|
||||||
|
victime->ROUTED = 0;
|
||||||
|
ocr_db->NB_ROUTED--;
|
||||||
|
//unMarkSegmentAsFree(ocr_db, victime, victime->INDEX);
|
||||||
|
}
|
||||||
|
//countFreeVC (ocr_db);
|
||||||
|
|
||||||
|
/*
|
||||||
|
detruire equipotentielle victime
|
||||||
|
relancer la recherche de chemin du signal a router ---> si nouvel echec ?
|
||||||
|
relancer le routage du signal occi ----> ???
|
||||||
|
*/
|
||||||
|
} while ( !(suspects.empty()) );
|
||||||
|
|
||||||
|
clean_tag_set (suspects);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
/* stocker le chemin dans la structure */
|
||||||
|
|
||||||
ocrNaturalInt make_segments (ocrWSegment *segment_dest,
|
ocrNaturalInt make_segments (ocrWSegment *segment_dest,
|
||||||
ocrWSegment *segment_source,
|
ocrWSegment *segment_source,
|
||||||
|
@ -623,7 +626,6 @@ ocrNaturalInt make_segments (ocrWSegment *segment_dest,
|
||||||
ocrWSegment *seg, *nseg, *root, *aux;
|
ocrWSegment *seg, *nseg, *root, *aux;
|
||||||
ocrNaturalInt xp, yp, xn, yn;
|
ocrNaturalInt xp, yp, xn, yn;
|
||||||
ocrNaturalInt p1, p2, pp1, pp2;
|
ocrNaturalInt p1, p2, pp1, pp2;
|
||||||
/*ocrNaturalInt pi;*/
|
|
||||||
ocrNaturalInt distance = 0;
|
ocrNaturalInt distance = 0;
|
||||||
ocrNaturalInt nb_segs = 0;
|
ocrNaturalInt nb_segs = 0;
|
||||||
|
|
||||||
|
@ -746,9 +748,6 @@ ocrNaturalInt check_path (ocrSignal *i_pSignal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
||||||
ocrWRoutingGrid * p_grid,
|
ocrWRoutingGrid * p_grid,
|
||||||
ocrNaturalInt xsource,
|
ocrNaturalInt xsource,
|
||||||
|
@ -812,7 +811,7 @@ ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
||||||
case AS_K_SEG: //path = explore (segment_source, segment_dest);
|
case AS_K_SEG: //path = explore (segment_source, segment_dest);
|
||||||
break;
|
break;
|
||||||
case AS_K_EQUI: assert (i_pSignal->SEGMENT);
|
case AS_K_EQUI: assert (i_pSignal->SEGMENT);
|
||||||
ze_best = NULL;
|
//ze_best = NULL;
|
||||||
path = explore_equi (segment_source, segment_dest);
|
path = explore_equi (segment_source, segment_dest);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -824,6 +823,8 @@ ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path) {
|
if (!path) {
|
||||||
|
ze_target = segment_dest;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (g_pOption->RIPUP) {
|
if (g_pOption->RIPUP) {
|
||||||
|
|
||||||
|
@ -859,12 +860,10 @@ ocrNaturalInt find_path_astar (ocrRoutingParameters * p_param,
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
/*void init_Astar (ocrRoutingDataBase *db) {
|
void init_Astar (ocrRoutingDataBase *db) {
|
||||||
assert (db);
|
assert (db);
|
||||||
|
|
||||||
grid = db->GRID;
|
ocr_db = db;
|
||||||
param = db->PARAM;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
/*
|
/*
|
||||||
### -------------------------------------------------- ###
|
### -------------------------------------------------- ###
|
||||||
$Author: hcl $
|
$Author: hcl $
|
||||||
$Date: 2002/04/03 09:52:19 $
|
$Date: 2002/04/10 12:56:55 $
|
||||||
$Log: ocrRouter.c,v $
|
$Log: ocrRouter.c,v $
|
||||||
|
Revision 1.5 2002/04/10 12:56:55 hcl
|
||||||
|
bouh
|
||||||
|
|
||||||
Revision 1.4 2002/04/03 09:52:19 hcl
|
Revision 1.4 2002/04/03 09:52:19 hcl
|
||||||
A little bit of C++.
|
A little bit of C++.
|
||||||
|
|
||||||
|
@ -977,6 +980,7 @@ routingWindow(ocrRoutingDataBase * i_pDataBase, phfig_list * i_pPhFig)
|
||||||
ocrNaturalInt i, l_uWin, wire_len;
|
ocrNaturalInt i, l_uWin, wire_len;
|
||||||
//ocrNaturalInt l_uNbf = sqrt (i_pDataBase->NB_F);
|
//ocrNaturalInt l_uNbf = sqrt (i_pDataBase->NB_F);
|
||||||
|
|
||||||
|
init_Astar (i_pDataBase);
|
||||||
|
|
||||||
wire_len = 0;
|
wire_len = 0;
|
||||||
|
|
||||||
|
@ -1100,7 +1104,10 @@ routingWindow(ocrRoutingDataBase * i_pDataBase, phfig_list * i_pPhFig)
|
||||||
i, l_pSignal->NB_CON, l_pSignal->INDEX,
|
i, l_pSignal->NB_CON, l_pSignal->INDEX,
|
||||||
l_pSignal->PRIORITY);
|
l_pSignal->PRIORITY);
|
||||||
|
|
||||||
ripUp3(i_pDataBase, i_pDataBase->PARAM, l_pSignal);
|
dig_around ();
|
||||||
|
countFreeVC (i_pDataBase);
|
||||||
|
|
||||||
|
/*ripUp3(i_pDataBase, i_pDataBase->PARAM, l_pSignal);*/
|
||||||
|
|
||||||
reRoute(i_pDataBase, i_pDataBase->PARAM, l_pSignal);
|
reRoute(i_pDataBase, i_pDataBase->PARAM, l_pSignal);
|
||||||
// if (reRoute (i_pDataBase, i_pDataBase->PARAM, l_pSignal) == 0)
|
// if (reRoute (i_pDataBase, i_pDataBase->PARAM, l_pSignal) == 0)
|
||||||
|
|
Loading…
Reference in New Issue