示例#1
0
/* spanning_tree:
 * Construct spanning forest of g as subgraph
 */
static Agraph_t *spanning_tree(Agraph_t * g)
{
    Agnode_t *n;
    Agraph_t *tree;
    char gname[SMALLBUF];
    static int id = 0;

    sprintf(gname, "_span_%d", id++);
    tree = agsubg(g, gname);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	aginsert(tree, n);
	DISTONE(n) = 0;
	DISTTWO(n) = 0;
	UNSET_VISITED(n);
    }

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (!VISITED(n)) {
	    TPARENT(n) = NULL;
	    dfs(g, n, tree);
	}
    }

    return tree;
}
示例#2
0
static inline int VisitSegment (short nSegment, int bAutomap)
{
if (nSegment < 0)
	return 0;
if (bAutomap) {
	if (automap.m_bDisplay) {
		if (!(automap.m_bFull || automap.m_visible [nSegment]))
			return 0;
		if (!gameOpts->render.automap.bSkybox && (SEGMENTS [nSegment].m_nType == SEGMENT_IS_SKYBOX))
			return 0;
		}
	else
		automap.m_visited [0][nSegment] = gameData.render.mine.bSetAutomapVisited;
	}
if (VISITED (nSegment))
	return 0;
VISIT (nSegment);
return 1;
}
示例#3
0
/* dfs:
 * Simple depth first search, adding traversed edges to tree.
 */
static void dfs(Agraph_t * g, Agnode_t * n, Agraph_t * tree)
{
    Agedge_t *e;
    Agnode_t *neighbor;

    SET_VISITED(n);
    for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
	neighbor = e->head;
	if (neighbor == n)
	    neighbor = e->tail;

	if (!VISITED(neighbor)) {
	    /* add the edge to the dfs tree */
	    aginsert(tree, e);
	    TPARENT(neighbor) = n;
	    dfs(g, neighbor, tree);
	}
    }
}
示例#4
0
/* findUnvisited:
 * Look for unvisited node n in visited block (i.e., some nodes in
 * the block have been visited) with neighbor not in block. Note
 * that therefore neighbor is unvisited. Set neighbor's parent to n
 * and return neighbor.
 * Guaranteed blp is non-empty.
 * 
 */
static Agnode_t *findUnvisited(blocklist_t * blp)
{
    Agnode_t *retn = NULL;
  FIX:finish Agnode_t * n;
    Agnode_t *newn;
    graph_t *clust_subg;
    edge_t *e;
    block_t *bp;
    block_t *prev = NULL;

    for (bp = blp->first; prev != blp->last; bp = bp->next) {
	prev = bp;
	clust = bp->sub_graph;

	if (DONE(bp))
	    continue;
	if (PARTIAL(bp)) {
	    for (n = agfstnode(clust); n; n = agnxtnode(clust, n)) {
		if (!VISITED(n)) {
		    for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
			newn = e->head;
			if (newn == n)
			    newn = e->tail;
			if ((BLOCK(newn) != bp)) {
			    retn = newn;
			    return;
			}
		    }
		    /* mark n visited */
		}
	    }
	    /* mark bp done */
	} else {
	}
    }
    return retn;
}
示例#5
0
文件: smartdisperse.c 项目: rlutz/pcb
/* %start-doc actions SmartDisperse

The @code{SmartDisperse([All|Selected])} action is a special-purpose
optimization for dispersing elements.

Run with @code{:SmartDisperse()} or @code{:SmartDisperse(Selected)}
(you can also say @code{:SmartDisperse(All)}, but that's the default).

%end-doc */
static int
smartdisperse (int argc, char **argv, Coord x, Coord y)
{
  char *function = ARG(0);
  NetListType *Nets;
  char *visited;
//  PointerListType stack = { 0, 0, NULL };
  int all;
//  int changed = 0;
//  int i;

  if (! function)
  {
    all = 1;
  }
  else if (strcmp(function, "All") == 0)
  {
    all = 1;
  }
  else if (strcmp(function, "Selected") == 0)
  {
    all = 0;
  }
  else
  {
    AFAIL (smartdisperse);
  }

  Nets = ProcNetlist (&PCB->NetlistLib);
  if (! Nets)
  {
    Message (_("Can't use SmartDisperse because no netlist is loaded.\n"));
    return 0;
  }

  /* remember which elements we finish with */
  visited = calloc (PCB->Data->ElementN, sizeof(*visited));

  /* if we're not doing all, mark the unselected elements as "visited" */
  ELEMENT_LOOP (PCB->Data);
  {
    if (! (all || TEST_FLAG (SELECTEDFLAG, element)))
    {
      visited[n] = 1;
    }
  }
  END_LOOP;

  /* initialize variables for place() */
  minx = GAP;
  miny = GAP;
  maxx = GAP;
  maxy = GAP;

  /*
   * Pick nets with two connections.  This is the start of a more
   * elaborate algorithm to walk serial nets, but the datastructures
   * are too gross so I'm going with the 80% solution.
   */
  NET_LOOP (Nets);
  {
    ConnectionType *conna, *connb;
    ElementType *ea, *eb;
//    ElementType *epp;

    if (net->ConnectionN != 2)
      continue;

    conna = &net->Connection[0];
    connb = &net->Connection[1];
    if (!IS_ELEMENT(conna) || !IS_ELEMENT(conna))
      continue;

    ea = (ElementType *) conna->ptr1;
    eb = (ElementType *) connb->ptr1;

    /* place this pair if possible */
    if (VISITED((GList *)ea) || VISITED((GList *)eb))
      continue;
    VISITED ((GList *)ea) = 1;
    VISITED ((GList *)eb) = 1;

    /* a weak attempt to get the linked pads side-by-side */
    if (padorder(conna, connb))
    {
      place ((ElementType *) ea);
      place ((ElementType *) eb);
    }
    else
    {
      place (eb);
      place (ea);
    }
  }
  END_LOOP;

  /* Place larger nets, still grouping by net */
  NET_LOOP (Nets);
  {
    CONNECTION_LOOP (net);
    {
      ElementType *element;

      if (! IS_ELEMENT(connection))
        continue;

      element = (ElementType *) connection->ptr1;

      /* place this one if needed */
      if (VISITED ((GList *) element))
        continue;
      VISITED ((GList *) element) = 1;
      place (element);
    }
    END_LOOP;
  }
  END_LOOP;

  /* Place up anything else */
  ELEMENT_LOOP (PCB->Data);
  {
    if (! visited[n])
    {
      place (element);
    }
  }
  END_LOOP;

  free (visited);

  IncrementUndoSerialNumber ();
  Redraw ();
  SetChangedFlag (1);

  return 0;
}
示例#6
0
文件: ejsJSON.c 项目: coordcn/ejs
static EjsString *serialize(Ejs *ejs, EjsAny *vp, Json *json)
{
    EjsName     qname;
    EjsFunction *fn;
    EjsString   *result, *sv;
    EjsTrait    *trait;
    EjsObj      *pp, *obj, *replacerArgs[2];
    wchar       *cp;
    cchar       *key;
    int         c, isArray, i, count, slotNum, quotes;

    /*
        The main code below can handle Arrays, Objects, objects derrived from Object and also native classes with properties.
        All others just use toString.
     */
    count = ejsIsPot(ejs, vp) ? ejsGetLength(ejs, vp) : 0;
    if (count == 0 && TYPE(vp) != ESV(Object) && TYPE(vp) != ESV(Array)) {
        //  OPT - need some flag for this test.
        if (!ejsIsDefined(ejs, vp) || ejsIs(ejs, vp, Boolean) || ejsIs(ejs, vp, Number)) {
            return ejsToString(ejs, vp);
        } else if (json->regexp) {
            return ejsToString(ejs, vp);
        } else {
            return ejsToLiteralString(ejs, vp);
        }
    }
    obj = vp;
    json->nest++;
    if (json->buf == 0) {
        json->buf = mprCreateBuf(0, 0);
        mprAddRoot(json->buf);
    }
    isArray = ejsIs(ejs, vp, Array);
    mprPutCharToWideBuf(json->buf, isArray ? '[' : '{');
    if (json->pretty) {
        mprPutCharToWideBuf(json->buf, '\n');
    }
    if (++ejs->serializeDepth <= json->depth && !VISITED(obj)) {
        SET_VISITED(obj, 1);
        for (slotNum = 0; slotNum < count && !ejs->exception; slotNum++) {
            trait = ejsGetPropertyTraits(ejs, obj, slotNum);
            if (trait && (trait->attributes & (EJS_TRAIT_HIDDEN | EJS_TRAIT_DELETED | EJS_FUN_INITIALIZER | 
                    EJS_FUN_MODULE_INITIALIZER)) && !json->hidden) {
                continue;
            }
            pp = ejsGetProperty(ejs, obj, slotNum);
            if (ejs->exception) {
                SET_VISITED(obj, 0);
                json->nest--;
                return 0;
            }
            if (pp == 0) {
                continue;
            }
            if (isArray) {
                key = itos(slotNum);
                qname.name = ejsCreateStringFromAsc(ejs, key);
                qname.space = ESV(empty);
            } else {
                qname = ejsGetPropertyName(ejs, vp, slotNum);
            }

            quotes = json->quotes;
            if (!quotes) {
                //  UNICODE
                for (cp = qname.name->value; cp < &qname.name->value[qname.name->length]; cp++) {
                    if (!isalnum((uchar) *cp) && *cp != '_') {
                        quotes = 1;
                        break;
                    }
                }
            }
            if (json->pretty) {
                for (i = 0; i < ejs->serializeDepth; i++) {
                    mprPutStringToWideBuf(json->buf, json->indent);
                }
            }
            if (!isArray) {
                if (json->namespaces) {
                    if (qname.space != ESV(empty)) {
                        mprPutToBuf(json->buf, "\"%@\"::", qname.space);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                for (cp = qname.name->value; cp && *cp; cp++) {
                    c = *cp;
                    if (c == '"' || c == '\\') {
                        mprPutCharToWideBuf(json->buf, '\\');
                        mprPutCharToWideBuf(json->buf, c);
                    } else {
                        mprPutCharToWideBuf(json->buf, c);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                mprPutCharToWideBuf(json->buf, ':');
                if (json->pretty) {
                    mprPutCharToWideBuf(json->buf, ' ');
                }
            }
            fn = (EjsFunction*) ejsGetPropertyByName(ejs, TYPE(pp)->prototype, N(NULL, "toJSON"));
            // OPT - check that this is going directly to serialize most of the time
            if (!ejsIsFunction(ejs, fn) || (fn->isNativeProc && fn->body.proc == (EjsProc) ejsObjToJSON)) {
                sv = serialize(ejs, pp, json);
            } else {
                sv = (EjsString*) ejsRunFunction(ejs, fn, pp, 1, &json->options);
            }
            if (sv == 0 || !ejsIs(ejs, sv, String)) {
                if (ejs->exception) {
                    ejsThrowTypeError(ejs, "Cannot serialize property %@", qname.name);
                    SET_VISITED(obj, 0);
                    return 0;
                }
            } else {
                if (json->replacer) {
                    replacerArgs[0] = (EjsObj*) qname.name; 
                    replacerArgs[1] = (EjsObj*) sv; 

                    /* function replacer(key: String, value: String): String */
                    sv = ejsRunFunction(ejs, json->replacer, obj, 2, (EjsObj**) replacerArgs);
                }
                mprPutBlockToBuf(json->buf, sv->value, sv->length * sizeof(wchar));
            }
            if ((slotNum + 1) < count || json->commas) {
                mprPutCharToWideBuf(json->buf, ',');
            }
            if (json->pretty) {
                mprPutCharToWideBuf(json->buf, '\n');
            }
        }
        SET_VISITED(obj, 0);
    }
    --ejs->serializeDepth; 
    if (json->pretty) {
        for (i = ejs->serializeDepth; i > 0; i--) {
            mprPutStringToWideBuf(json->buf, json->indent);
        }
    }
    mprPutCharToWideBuf(json->buf, isArray ? ']' : '}');
    mprAddNullToWideBuf(json->buf);

    if (--json->nest == 0) {
        result = ejsCreateString(ejs, mprGetBufStart(json->buf), mprGetBufLength(json->buf) / sizeof(wchar));
        mprRemoveRoot(json->buf);
    } else {
        result = 0;
    }
    return result;
}
示例#7
0
/*
 * Prim's approximated TSP tour
 * See also [Cristophides'92]
 */
static
int findEulerianPath(TSP *tsp) {
    int *mst, *arc;
    int i, j, k, l, a;
    int n, *iorder, *jorder;
    DTYPE d;
    DTYPE maxd;
    DTYPE *dist;
    DTYPE *dis;

    jorder = tsp->jorder;
    iorder = tsp->iorder;
    dist   = tsp->dist;
    maxd   = tsp->maxd;
    n      = tsp->n;

    if (!(mst =(int*) palloc((size_t) n * sizeof(int))) ||
        !(arc =(int*) palloc((size_t) n * sizeof(int))) ||
        !(dis =(DTYPE*) palloc((size_t) n * sizeof(DTYPE))) ) {
        elog(ERROR, "Failed to allocate memory!");
        return -1;
    }
    // PGR_DBG("findEulerianPath: 1");

    k = -1;
    j = -1;
    d = maxd;
    dis[0] = -1;
    for (i = 1; i < n; i++) {
        dis[i] = D(i, 0);
        arc[i] = 0;
        if (d > dis[i]) {
            d = dis[i];
            j = i;
        }
    }
    // PGR_DBG("findEulerianPath: j=%d", j);

    if (j == -1)
        elog(ERROR, "Error TSP fail to findEulerianPath, check your distance matrix is valid.");

    /*
     * O(n^2) Minimum Spanning Trees by Prim and Jarnick
     * for graphs with adjacency matrix.
     */
    for (a = 0; a < n - 1; a++) {
        mst[a] = j * n + arc[j]; /* join fragment j with MST */
        dis[j] = -1;
        d = maxd;
        for (i = 0; i < n; i++) {
            if (dis[i] >= 0) {
                /* not connected yet */
                if (dis[i] > D(i, j)) {
                    dis[i] = D(i, j);
                    arc[i] = j;
                }
                if (d > dis[i]) {
                    d = dis[i];
                    k = i;
                }
            }
        }
        j = k;
    }
    // PGR_DBG("findEulerianPath: 3");

    /*
     * Preorder Tour of MST
     */
#define VISITED(x) jorder[x]
#define NQ(x) arc[l++] = x
#define DQ()  arc[--l]
#define EMPTY (l == 0)

    for (i = 0; i < n; i++) VISITED(i) = 0;
    k = 0; l = 0; d = 0; NQ(0);
    while (!EMPTY) {
        i = DQ();
        if (!VISITED(i)) {
            iorder[k++] = i;
            VISITED(i)  = 1;
            for (j = 0; j < n - 1; j++) /* push all kids of i */ {
                if (i == mst[j]%n) NQ(mst[j]/n);
            }
        }
    }
    // PGR_DBG("findEulerianPath: 4");

    return 0;
}
示例#8
0
/*
 * Prim's approximated TSP tour
 * See also [Cristophides'92]
 */
bool
TSP::findEulerianPath() {
    Ids iorder(n);
    Ids mst(n);
    Ids arc(n);
    std::vector < double > dis(n);
    double d;
#if 0
    int n, *iorder, *jorder;
    DTYPE d;
    DTYPE maxd;
    DTYPE *dist;
    DTYPE *dis;

    jorder = tsp->jorder;
    iorder = tsp->iorder;
    dist   = tsp->dist;
    maxd   = tsp->maxd;
    n      = tsp->n;

    if (!(mst = (int*) palloc(n * sizeof(int))) ||
            !(arc = (int*) palloc(n * sizeof(int))) ||
            !(dis = (DTYPE*) palloc(n * sizeof(DTYPE))) )
    {
        elog(ERROR, "Failed to allocate memory!");
        return -1;
    }
#endif
    // PGR_DBG("findEulerianPath: 1");

    size_t j(0);
    double curr_maxd = maxd;
    dis[0] = -1;

    for (size_t i = 1; i < n; ++i) {
        dis[i] = dist[i][0];
        arc[i] = 0;
        if (curr_maxd > dis[i]) {
            curr_maxd = dis[i];
            j = i;
        }
    }
    //PGR_DBG("findEulerianPath: j=%d", j);

    if (curr_maxd == maxd) {
        // PGR_DBG("Error TSP fail to findEulerianPath, check your distance matrix is valid.");
        return false;
    }

    /*
     * O(n^2) Minimum Spanning Trees by Prim and Jarnick 
     * for graphs with adjacency matrix. 
     */
    for (size_t a = 0; a < n - 1; a++) {
        size_t k(0);
        mst[a] = j * n + arc[j]; /* join fragment j with MST */
        dis[j] = -1; 
        d = maxd;
        for (size_t i = 0; i < n; i++)
        {
            if (dis[i] >= 0) /* not connected yet */
            {
                if (dis[i] > dist[i][j])
                {
                    dis[i] = dist[i][j];
                    arc[i] = j;
                }
                if (d > dis[i])
                {
                    d = dis[i];
                    k = i;
                }
            }
        }
        j = k;
    }
    //PGR_DBG("findEulerianPath: 3");

    /*
     * Preorder Tour of MST
     */
#if 0
#define VISITED(x) jorder[x]
#define NQ(x) arc[l++] = x
#define DQ()  arc[--l]
#define EMPTY (l==0)
#endif
    for (auto &val : jorder) {
        val = 0;
    }

#if 0
    for (i = 0; i < n; i++) VISITED(i) = 0;
#endif

    size_t l = 0;
    size_t k = 0;
    d = 0;
    arc[l++] = 0;
    while (!(l == 0)) {
        size_t i = arc[--l];

        if (!jorder[i]) {
            iorder[k++] = i;
            jorder[i]  = 1;            
            /* push all kids of i */
            for (size_t j = 0; j < n - 1; j++) {
                if (i == mst[j] % n)
                    arc[l++] = mst[j] % n; 
            }
        }
    }

#if 0
    k = 0; l = 0; d = 0; NQ(0);
    while (!EMPTY)
    {
        i = DQ();
        if (!VISITED(i))
        {
            iorder[k++] = i;
            VISITED(i)  = 1;            
            for (j = 0; j < n - 1; j++) /* push all kids of i */
            {
                if (i == mst[j]%n) NQ(mst[j]/n); 
            }    
        }
    }
#endif
    //PGR_DBG("findEulerianPath: 4");

    update(iorder);
    return true;
}
示例#9
0
文件: listing.c 项目: varphone/ejs-2
/*
    List the various property slot assignments
 */
static void lstSlotAssignments(EjsMod *mp, EjsModule *module, EjsObj *parent, int slotNum, EjsObj *obj)
{
    Ejs             *ejs;
    EjsTrait        *trait;
    EjsType         *type;
    EjsObj          *vp;
    EjsPot          *prototype;
    EjsFunction     *fun;
    EjsBlock        *block;
    EjsName         qname;
    int             i, numInherited, count;

    mprAssert(obj);
    mprAssert(module);

    ejs = mp->ejs;
    if (VISITED(obj)) {
        return;
    }
    SET_VISITED(obj, 1);

    if (obj == ejs->global) {
        mprFprintf(mp->file,  "\n#\n"
            "#  Global slot assignments (Num prop %d)\n"
            "#\n", ejsGetLength(ejs, obj));

        /*
            List slots for global
         */
        for (i = module->firstGlobal; i < module->lastGlobal; i++) {
            trait = ejsGetPropertyTraits(ejs, ejs->global, i);
            qname = ejsGetPropertyName(ejs, ejs->global, i);
            if (qname.name == 0) {
                continue;
            }
            lstVarSlot(mp, module, &qname, trait, i);
        }

        /*
            List slots for the initializer
         */
        fun = (EjsFunction*) module->initializer;
        if (fun) {
            mprFprintf(mp->file,  "\n#\n"
                "#  Initializer slot assignments (Num prop %d)\n"
                "#\n", ejsGetLength(ejs, (EjsObj*) fun));

            count = ejsGetLength(ejs, (EjsObj*) fun);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, (EjsObj*) fun, i);
                qname = ejsGetPropertyName(ejs, (EjsObj*) fun, i);
                if (qname.name == 0) {
                    continue;
                }
                mprAssert(trait);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }

    } else if (ejsIsFunction(ejs, obj)) {
        fun = (EjsFunction*) obj;
        count = ejsGetLength(ejs, (EjsObj*) obj);
        if (count > 0) {
            mprFprintf(mp->file,  "\n#\n"
                "#  Local slot assignments for the \"%@\" function (Num slots %d)\n"
                "#\n", fun->name, count);

            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, obj, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, obj, i);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }

    } else if (ejsIsType(ejs, obj)) {
        /*
            Types
         */
        type = (EjsType*) obj;
        mprFprintf(mp->file,  "\n#\n"
            "#  Class slot assignments for the \"%@\" class (Num slots %d)\n"
            "#\n", type->qname.name,
            ejsGetLength(ejs, (EjsObj*) type));

        count = ejsGetLength(ejs, (EjsObj*) type);
        for (i = 0; i < count; i++) {
            trait = ejsGetPropertyTraits(ejs, (EjsObj*) type, i);
            mprAssert(trait);
            qname = ejsGetPropertyName(ejs, obj, i);
            lstVarSlot(mp, module, &qname, trait, i);
        }

        prototype = type->prototype;
        if (type->baseType && type->baseType->prototype) {
            numInherited = ejsGetLength(ejs, type->baseType->prototype);
        } else {
            numInherited = 0;
        }
        mprFprintf(mp->file,  "\n#\n"
            "#  Instance slot assignments for the \"%@\" class (Num prop %d, num inherited %d)\n"
            "#\n", type->qname.name,
            prototype ? ejsGetLength(ejs, prototype): 0, numInherited);

        if (prototype) {
            count = ejsGetLength(ejs, prototype);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, prototype, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, prototype, i);
                if (qname.name) {
                    lstVarSlot(mp, module, &qname, trait, i);
                }
            }
        }

    } else if (ejsIsBlock(ejs, obj)) {
        qname = ejsGetPropertyName(ejs, parent, slotNum);
        block = (EjsBlock*) obj;
        count = ejsGetLength(ejs, (EjsObj*) block);
        if (count > 0) {
            mprFprintf(mp->file,  
                "\n#\n"
                "#  Block slot assignments for the \"%@\" (Num slots %d)\n"
                "#\n", qname.name, ejsGetLength(ejs, obj));
            
            count = ejsGetLength(ejs, obj);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, obj, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, obj, i);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }
    }

    /*
        Now recurse on types, functions and blocks
     */
    if (obj == ejs->global) {
        i = module->firstGlobal;
        count = module->lastGlobal;
    } else {
        i = 0;
        count = ejsGetLength(ejs, obj);
    }
    for (; i < count; i++) {
        qname = ejsGetPropertyName(ejs, obj, i);
        vp = ejsGetProperty(ejs, obj, i);
        if (vp == 0) {
            continue;
        }
        if (ejsIsType(ejs, vp) || ejsIsFunction(ejs, vp) || ejsIsBlock(ejs, vp)) {
            lstSlotAssignments(mp, module, obj, i, vp);
        }
    }
    SET_VISITED(obj, 0);
}