コード例 #1
0
//-----------------------------------------------------------------------
//Summary:
//		find shortest path from entry point to exit point
//Parameters:
//		entryPos[in]: start point
//		pStartResource[in]: start landside traffic object
//		exitPos[in]: end point
//		pEndResource[in]: end landside traffic object
//		_shortestPath[out]: shortest path from start to end
//Return:
//		true: find the path
//		false: failed
//-----------------------------------------------------------------------
bool CLandsideGraph::getShortestPath( const CPoint2008& entryPos,LandsideResourceInSim* pStartLandsideResource,CLandsideWalkTrafficObjectInSim* pStartResource,const CPoint2008& exitPos,LandsideResourceInSim* pEndLandsideResource,CLandsideWalkTrafficObjectInSim* pEndResource,LandsideTrafficGraphVertexList& _shortestPath )
{
	CPoint2008 startPos;
	CPoint2008 endPos;
	if (pStartResource->GetShortestProjectPoint(pStartLandsideResource,entryPos,startPos) && pEndResource->GetShortestProjectPoint(pEndLandsideResource,exitPos,endPos))
	{
		LandsideTrafficGraphVertex startVertex, endVertex;

		pStartResource->GetWalkwayVertex(startVertex,startPos);
		pEndResource->GetWalkwayVertex(endVertex,endPos);

		LandsideTrafficGraphVertex entryVertex1, entryVertex2, exitVertex1, exitVertex2;
		pStartResource->GetNearestVertex(startPos, entryVertex1, entryVertex2);
		pEndResource->GetNearestVertex(endPos, exitVertex1, exitVertex2);

		LandsideTrafficGraphVertexList path[4];
		findShortestPath(entryVertex1, exitVertex1, path[0]);
		findShortestPath(entryVertex1, exitVertex2, path[1]);
		findShortestPath(entryVertex2, exitVertex1, path[2]);
		findShortestPath(entryVertex2, exitVertex2, path[3]);

		double exDistance[4];
		exDistance[0] = startPos.distance(entryVertex1.GetPointDist()) + endPos.distance(exitVertex1.GetPointDist());
		exDistance[1] = startPos.distance(entryVertex1.GetPointDist()) + endPos.distance(exitVertex2.GetPointDist());
		exDistance[2] = startPos.distance(entryVertex2.GetPointDist()) + endPos.distance(exitVertex1.GetPointDist());
		exDistance[3] = startPos.distance(entryVertex2.GetPointDist()) + endPos.distance(exitVertex2.GetPointDist());

		int shortestIndex = 0;
		for (int i = 1; i < 4; i++)
		{
			if (GetLength(path[i]) + exDistance[i] < GetLength(path[shortestIndex]) + exDistance[shortestIndex])
			{
				shortestIndex = i;
			}
		}

		_shortestPath = path[shortestIndex];
	
		_shortestPath.insert(_shortestPath.begin(), startVertex);
		_shortestPath.push_back(endVertex);
	}
	// add the source point and dest point
	LandsideTrafficGraphVertex sourceVertex;
	sourceVertex.SetPoint(entryPos);

	LandsideTrafficGraphVertex destVertex;
	destVertex.SetPoint(exitPos);

	_shortestPath.push_back(destVertex);
	_shortestPath.insert(_shortestPath.begin(), sourceVertex);
	return true;
}
コード例 #2
0
ファイル: ditch-backup.c プロジェクト: laysent/onlineJudge
int doSearch(int source, int sink) {
  int path[M];
  int max, previous, i;
  int ret = 0;

  if (source == sink) {
    printf("source == sink == %d\n", source);
    return INFINITY;
  }

  while( findShortestPath(source, sink, path) ) {
    previous = path[sink];
    max = map[previous][sink];
    while (previous != source) {
      max = min(max, map[path[previous]][previous]);
      previous = path[previous];
    }

    previous = path[sink];
    map[previous][sink] -= max;
    map[sink][previous] += max;
    while (previous != source) {
      map[path[previous]][previous] -= max;
      map[previous][path[previous]] += max;
      previous = path[previous];
    }
    ret += max;
  }
  return ret;
}
コード例 #3
0
ファイル: strongAi.cpp プロジェクト: nbajiaoshi/Lota
void fighting(const PUnit* a, const PUnit* b, PCommand &cmd) //单位a对单位b发起进攻
{
    Operation op;
    op.id = a->id;

    vector<const PSkill*> useSkill;
    for (int i = 0; i < a->skills.size(); ++i)
    {
        const PSkill* ptr = &a->skills[i];
        if (ptr->isHeroSkill() && a->canUseSkill(ptr->typeId))
        {
            PUnits ptr_foe;
            infectedBySkill(*INFO, a->id, ptr->typeId, ptr_foe); //寻找可用技能
            if (belongs(b->id, ptr_foe) || !strcmp(ptr->name,"Hide") || !strcmp(ptr->name,"PowerUp"))
                useSkill.push_back(ptr);
        }
    }
    if (useSkill.size()) //策略:优先使用技能
    {
        const PSkill* ptr = useSkill[rand()%useSkill.size()];
        op.type = ptr->name;
        if (ptr->needTarget())
            op.targets.push_back(b->pos);
    } else
        if (dis2(a->pos, b->pos) <= a->range) //判断单位b是否在攻击范围内
        {
            op.type = "Attack";
            op.targets.push_back(b->pos);
        } else
        {
            op.type = "Move";
            findShortestPath(*MAP, a->pos, b->pos, blocks, op.targets);
        }
    cmd.cmds.push_back(op);
}
コード例 #4
0
ファイル: strongAi.cpp プロジェクト: nbajiaoshi/Lota
void findFoes(const PUnit* a, PCommand &cmd) //单位a寻找对手
{
    if ((*a)["Exp"]->val[3]) //优先升级技能
    {
        levelUp(a, cmd);
    } else
    {
        if (fixPos[a->id] == EMPTYPOS)
        {
            vector<Pos> atk_tar;
            atk_tar.clear();
            getFoes(atk_tar, a->level > HIGHLEVEL ? HIGHLEVEL : 0, a->level); //策略:达到一定强度开始攻击防御塔
            if (atk_tar.size()) //寻找固定点的弱小对手
            {
                fixPos[a->id] = atk_tar[rand()%atk_tar.size()]; //锁定目标
            } else
            {
                fixPos[a->id] = DEFAULFPOS;
            }
        }
        Operation op;
        op.id = a->id;
        op.type = "Move";
        findShortestPath(*MAP, a->pos, fixPos[a->id], blocks, op.targets); //向弱小对手移动
        cmd.cmds.push_back(op);
    }
}
コード例 #5
0
ファイル: smartpath.c プロジェクト: pd0wm/epo2
/**
 * Creates odd paths
 */
void createOddPaths() {
	// Find odd paths
	oddPaths = malloc(sizeof (int) *MAX_PATH_LENGTH * oddNodesSize / 2);
	oddPathsSizes = malloc(sizeof (int) *oddNodesSize / 2);
	oddPathsSize = 0;
	int i;

	for (i = 0; i < oddNodesSize; i += 2) {
		Path_element *path = findShortestPath(
				getNodeById(oddNodes[i])->positionGrid.x,
				getNodeById(oddNodes[i])->positionGrid.y,
				1,
				getNodeById(oddNodes[i + 1])->positionGrid.x,
				getNodeById(oddNodes[i + 1])->positionGrid.y
				);

		oddPaths[oddPathsSize] = malloc(sizeof (int) *MAX_PATH_LENGTH);
		oddPathsSizes[oddPathsSize] = 0;

		while (path) {
			oddPaths[oddPathsSize][oddPathsSizes[oddPathsSize]++] = path->id;
			path = path->next;
		}

//		printf("Path found, size: %d\n", oddPathsSizes[oddPathsSize]);
		oddPathsSize++;
	}
}
コード例 #6
0
ファイル: testHunter.c プロジェクト: haydenvr/furydracula
void testGraph(void) {
    printf("Testing graph 1...\n");
    Location path[NUM_MAP_LOCATIONS];
    int a = findShortestPath(NANTES, MARSEILLES, path, ANY,0);
    assert(a == 3);
    assert(path[0] == NANTES);
    assert(path[1] == CLERMONT_FERRAND);
    assert(path[2] == MARSEILLES);
    printf("Test passed!\n");
    printf("Testing graph 2...\n");
    a = findShortestPath(NANTES, MARSEILLES, path, ANY,0);
    assert(a == 3);
    assert(path[0] == NANTES);
    assert(path[1] == CLERMONT_FERRAND);
    assert(path[2] == MARSEILLES);
    printf("Test passed!\n");
    printf("Testing graph by rail...\n");
    a = findShortestPath(MADRID, BARCELONA, path, ANY,2);
    assert(a == 2);
    assert(path[0] == MADRID);
    assert(path[1] == BARCELONA);
    printf("Passed by rail test\n");
    a = findShortestPath(MARSEILLES, COLOGNE, path, ANY,3);
    assert(a == 2);
    assert(path[0] == MARSEILLES);
    assert(path[1] == COLOGNE);
    printf("Passed second rail test\n");
    a = findShortestPath(MARSEILLES, AMSTERDAM, path, ANY,3);
    assert(a == 3);
    assert(path[0] == MARSEILLES);
    assert(path[1] == COLOGNE);
    assert(path[2] == AMSTERDAM);
    printf("Passed final rail test\n");
    printf("Testing fail cases\n");
    printf("Testing Strassburg to CD\n");
    a = findShortestPath(STRASBOURG, CASTLE_DRACULA, path, ANY, 3);
    int i = 0;
    int correct[5] = {51,6,10,21,13};
    for (i = 0; i < a; i++) {
        assert(path[i] == correct[i]);
    }
    printf("Passed\nNow testing same path but without rail (ie round rem 4 equal to 0 )");
    printf("Passed\nNow testing same path but without rail");
    a = findShortestPath(STRASBOURG, CASTLE_DRACULA, path, ANY, 0);
    int correct2[6] = {51,38,58,10,28,13};
    for (i = 0; i < a; i++) {
        assert(path[i] == correct2[i]);
    }
    printf("\nTest Passed\nNow to test the results of connected locs Klaus (expecting CD to be there)\n");
    Graph g = newGraph();
    LocationID *b = connectedLocations(&a, KLAUSENBURG, 0, 0, ANY, g);
    for (i=0; i<a; i++) {
        printf("[%d]",b[i]);
    }
    free(b);
    destroyGraph(g);
    printf("\nDone\n");
}
コード例 #7
0
ファイル: DIJIKSTR.C プロジェクト: sara-02/code_dump
void main()
{
	int i,j,n,weight[10][10],s,d,len,count,path[20];
	char ch1,ch2;
	FILE*f;

	f=fopen("vertex.txt","r+");
	fscanf(f,"%d",&n);

	clrscr();

	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			fscanf(f,"%d",&weight[i][j]);
		}
	}

	printf("\nWeight Matrix\n");
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
		{
			printf("\t%d",weight[i][j]);
		}
		printf("\n");
	}

	printf("Enter ther source node : ");
	scanf("%c",&ch1);
	s=ch1-'a'+1;
	fflush(stdin);
	printf("Enter the destination node : ");
	scanf("%c",&ch2);
	d=ch2-'a'+1;

	count=findShortestPath(s,d,path,weight,&len,n);

	if(len>0)
	{
		printf("\n\nShortest Path between %c (SOURCE) and %c (DESTINATION) is : ",s+'a'-1,d+'a'-1);
		for(i=count;i>=1;i--)
		{
			printf(" %c",path[i]+'a'-1);
		}
		printf("\n\nLength of the shortest path is : %d",len);
	}
	else
	 printf("\n\nNo Path exists between the nodes %c and %c",s+'a'-1,d+'a'-1);
	getch();
}
コード例 #8
0
ファイル: astar.c プロジェクト: pd0wm/epo2
Path* getPathDetails(int start_x, int start_y, int facing_direction, int destination_x, int destination_y) {
	Path *path = malloc(sizeof (Path));
	int shortest_path_weight, end_facing_direction = -1;

	// Calculate shortest path
	Path_element *shortest_path = shortest_path = findShortestPath(start_x, start_y, facing_direction, destination_x, destination_y);

	// Set variable
	shortest_path_weight = 0;

	// Walk through the pad, adding all the step weights and determining that way the total weight of the path
	while (shortest_path) {
		shortest_path_weight += shortest_path->step_weight;
		end_facing_direction = shortest_path->facing_direction;
		shortest_path = shortest_path->next;
	}

	path->length = shortest_path_weight;
	path->facing_direction = end_facing_direction;

	return path;
}
コード例 #9
0
ファイル: smartpath.c プロジェクト: pd0wm/epo2
/**
 * Determines the total path length between two nodes
 * @param  node1
 * @param  node2
 * @return
 */
int getLengthBetweenNodes(int node1, int node2) {
	Node* from = getNodeById(node1);
	Node* to = getNodeById(node2);

	Path_element *path = findShortestPath(
			from->positionGrid.x,
			from->positionGrid.y,
			1,
			to->positionGrid.x,
			to->positionGrid.y
			);

	int length = 0;

	while (path) {
		length += path->step_weight;
		path = path->next;
	}

	//free(path);
	return length;
}
コード例 #10
0
//---------------------------------------------------------
// actual call (called by all variations of call)
//   crossing of generalizations is forbidden if forbidCrossingGens = true
//   edge costs are obeyed if costOrig != 0
//
Module::ReturnType FixedEmbeddingInserter::doCall(
	PlanRep &PG,
	const List<edge> &origEdges,
	bool forbidCrossingGens,
	const EdgeArray<int>  *costOrig,
	const EdgeArray<bool> *forbiddenEdgeOrig,
	const EdgeArray<unsigned int> *edgeSubGraph)
{
  
	double T;
	usedTime(T);
	
	ReturnType retValue = retFeasible;
	m_runsPostprocessing = 0;

	PG.embed(); 
	OGDF_ASSERT(PG.representsCombEmbedding() == true);

	if (origEdges.size() == 0)
		return retOptimal;  // nothing to do

	// initialization
	CombinatorialEmbedding E(PG);  // embedding of PG

	m_dual.clear();
	m_primalAdj.init(m_dual);
	m_nodeOf.init(E);

	// construct dual graph
	m_primalIsGen.init(m_dual,false);

	OGDF_ASSERT(forbidCrossingGens == false || forbiddenEdgeOrig == 0);

	if(forbidCrossingGens)
		constructDualForbidCrossingGens((const PlanRepUML&)PG,E);
	else
		constructDual(PG,E,forbiddenEdgeOrig);

	// m_delFaces and m_newFaces are used by removeEdge()
	// if we can't allocate memory for them, we throw an exception
	if (removeReinsert() != rrNone) {
		m_delFaces = new FaceSetSimple(E);
		if (m_delFaces == 0)
			OGDF_THROW(InsufficientMemoryException);

		m_newFaces = new FaceSetPure(E);
		if (m_newFaces == 0) {
			delete m_delFaces;
			OGDF_THROW(InsufficientMemoryException);
		}

	// no postprocessing -> no removeEdge()
	} else {
		m_delFaces = 0;
		m_newFaces = 0;
	}

	SListPure<edge> currentOrigEdges;
	if(removeReinsert() == rrIncremental) {
		edge e;
		forall_edges(e,PG)
			currentOrigEdges.pushBack(PG.original(e));
	}

	// insertion of edges
	ListConstIterator<edge> it;
	for(it = origEdges.begin(); it.valid(); ++it)
	{
		edge eOrig = *it;

		int eSubGraph = 0;  // edgeSubGraph-data of eOrig
		if(edgeSubGraph!=0) eSubGraph = (*edgeSubGraph)[eOrig];

		SList<adjEntry> crossed;
		if(costOrig != 0) {
			findShortestPath(PG, E, *costOrig,
				PG.copy(eOrig->source()),PG.copy(eOrig->target()),
				forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrig) : Graph::association,
				crossed, edgeSubGraph, eSubGraph);
		} else {
			findShortestPath(E,
				PG.copy(eOrig->source()),PG.copy(eOrig->target()),
				forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrig) : Graph::association,
				crossed);
		}

		insertEdge(PG,E,eOrig,crossed,forbidCrossingGens,forbiddenEdgeOrig);
		
		if(removeReinsert() == rrIncremental) {
			currentOrigEdges.pushBack(eOrig);

			bool improved;
			do {
				++m_runsPostprocessing;
				improved = false;
				
				SListConstIterator<edge> itRR;
				for(itRR = currentOrigEdges.begin(); itRR.valid(); ++itRR)
				{
					edge eOrigRR = *itRR;
		
					int pathLength;
					if(costOrig != 0)
						pathLength = costCrossed(eOrigRR,PG,*costOrig,edgeSubGraph);
					else
						pathLength = PG.chain(eOrigRR).size() - 1;
					if (pathLength == 0) continue; // cannot improve
		
					removeEdge(PG,E,eOrigRR,forbidCrossingGens,forbiddenEdgeOrig);
		
					// try to find a better insertion path
					SList<adjEntry> crossed;
					if(costOrig != 0) {
						int eSubGraph = 0;  // edgeSubGraph-data of eOrig
						if(edgeSubGraph!=0) eSubGraph = (*edgeSubGraph)[eOrigRR];

						findShortestPath(PG, E, *costOrig,
							PG.copy(eOrigRR->source()),PG.copy(eOrigRR->target()),
							forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrigRR) : Graph::association,
							crossed, edgeSubGraph, eSubGraph);
					} else {
						findShortestPath(E,
							PG.copy(eOrigRR->source()),PG.copy(eOrigRR->target()),
							forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrigRR) : Graph::association,
							crossed);
					}
					
					// re-insert edge (insertion path cannot be longer)
					insertEdge(PG,E,eOrigRR,crossed,forbidCrossingGens,forbiddenEdgeOrig);
		
					int newPathLength = (costOrig != 0) ? costCrossed(eOrigRR,PG,*costOrig,edgeSubGraph) : (PG.chain(eOrigRR).size() - 1);
					OGDF_ASSERT(newPathLength <= pathLength);
					
					if(newPathLength < pathLength)
						improved = true;
				}
			} while (improved);
		}
	}

	const Graph &G = PG.original();
	if(removeReinsert() != rrIncremental) {
		// postprocessing (remove-reinsert heuristc)
		SListPure<edge> rrEdges;
	
		switch(removeReinsert())
		{
		case rrAll:
		case rrMostCrossed: {
				const List<node> &origInCC = PG.nodesInCC();
				ListConstIterator<node> itV;
	
				for(itV = origInCC.begin(); itV.valid(); ++itV) {
					node vG = *itV;
					adjEntry adj;
					forall_adj(adj,vG) {
						if ((adj->index() & 1) == 0) continue;
						edge eG = adj->theEdge();
						rrEdges.pushBack(eG);
					}
				}
			}
			break;
	
		case rrInserted:
			for(ListConstIterator<edge> it = origEdges.begin(); it.valid(); ++it)
				rrEdges.pushBack(*it);
			break;

		case rrNone:
		case rrIncremental:
			break;
		}
	
		// marks the end of the interval of rrEdges over which we iterate
		// initially set to invalid iterator which means all edges
		SListConstIterator<edge> itStop;
	
		bool improved;
		do {
			// abort postprocessing if time limit reached
			if (m_timeLimit >= 0 && m_timeLimit <= usedTime(T)) {
				retValue = retTimeoutFeasible;
				break;
			}
				
			++m_runsPostprocessing;
			improved = false;
	
			if(removeReinsert() == rrMostCrossed)
			{
				FEICrossingsBucket bucket(&PG);
				rrEdges.bucketSort(bucket);
	
				const int num = int(0.01 * percentMostCrossed() * G.numberOfEdges());
				itStop = rrEdges.get(num);
			}
	
			SListConstIterator<edge> it;
			for(it = rrEdges.begin(); it != itStop; ++it)
			{
				edge eOrig = *it;
							
				// remove only if crossings on edge;
				// in especially: forbidden edges are never handled by postprocessing
				//   since there are no crossings on such edges
				int pathLength;
				if(costOrig != 0)
					pathLength = costCrossed(eOrig,PG,*costOrig,edgeSubGraph);
				else
					pathLength = PG.chain(eOrig).size() - 1;
				if (pathLength == 0) continue; // cannot improve
	
				removeEdge(PG,E,eOrig,forbidCrossingGens,forbiddenEdgeOrig);
	
				// try to find a better insertion path
				SList<adjEntry> crossed;
				if(costOrig != 0) {
					int eSubGraph = 0;  // edgeSubGraph-data of eOrig
					if(edgeSubGraph!=0) eSubGraph = (*edgeSubGraph)[eOrig];

					findShortestPath(PG, E, *costOrig,
						PG.copy(eOrig->source()),PG.copy(eOrig->target()),
						forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrig) : Graph::association,
						crossed, edgeSubGraph, eSubGraph);
				} else {
					findShortestPath(E,
						PG.copy(eOrig->source()),PG.copy(eOrig->target()),
						forbidCrossingGens ? ((const PlanRepUML&)PG).typeOrig(eOrig) : Graph::association,
						crossed);
				}
	
				// re-insert edge (insertion path cannot be longer)
				insertEdge(PG,E,eOrig,crossed,forbidCrossingGens,forbiddenEdgeOrig);
	
				int newPathLength = (costOrig != 0) ? costCrossed(eOrig,PG,*costOrig,edgeSubGraph) : (PG.chain(eOrig).size() - 1);
				OGDF_ASSERT(newPathLength <= pathLength);
				
				if(newPathLength < pathLength)
					improved = true;
			}
		} while(improved); // iterate as long as we improve
	}
コード例 #11
0
void GraphImplementationRandom::computeRoute(Rank a,Rank b,vector<Rank>*route){
	findShortestPath(a,b,route);
}
コード例 #12
0
ファイル: FacilityLocation.cpp プロジェクト: phliguori/vpn
void FacilityLocation::builSolutionGraph()
{
	if (s == NULL)
		s = new Graph();

	activeRouters = 0;
	activeArcs = 0;

	s->nVertices = g->nVertices;
	s->nTerminals = g->nTerminals;
	s->nArcs = g->nArcs;
	s->reserve(g->nVertices + 1);

	for (int i = 0; i < g->nTerminals; ++i)
	{
		Vertex terminal = g->terminals[i];

		s->addTerminal(terminal);
		s->addVertex(terminal);
	}

	for (auto& vit : vHash[Variable::V_Y])
	{
		int col = vit.second;
		Variable var = vit.first;
		Vertex v = var.getVertex1();
		int code = v.getCode();


		if (!v.isTerminal() && fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			++activeRouters;
			v.setColor("red");
			s->vertices[code] = v;
		}
	}
	printf("");

	for (auto & vit : vHash[Variable::V_X])
	{
		Arc arc = vit.first.getArc();
		int col = vit.second;

		if (fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			Vertex router = arc.getHead();
			Vertex terminal = arc.getTail();

			auto & element = g->arcSet[router.getCode()].find(arc);
			if (element != g->arcSet[router.getCode()].end())
			{
				arc.setColor("red");
				arc.setPenwidht(3.5);

				s->addArc(arc);
			}
			else
			{
				std::vector<Arc> path;
				findShortestPath(router, terminal, g, path);

				for (int i = 0; i < path.size(); ++i)
				{
					Arc aux = path[i];
					aux.setColor("red");
					aux.setPenwidht(1.5);

					s->addArc(aux);
					s->vertices[aux.getHead().getCode()].setColor("red");
				}
				activeArcs += path.size();
				printf("");
			}
		}

	}
	printf("");

	for (auto& vit : vHash[Variable::V_Z])
	{
		Variable v = vit.first;
		int col = vit.second;
		Arc arc = v.getArc();

		if (fabs(xSol[col] - 1.0) < SOLVER_EPS)
		{
			++activeArcs;
			arc.setColor("red");
			arc.setPenwidht(3.5);
		}
		else
		{
			arc.setColor("black");
			arc.setStyle("dotted");
			arc.setPenwidht(1.0);
		}
		s->addArc(arc);
	}
	printf("");
#ifdef DEBUG
	s->toDot();
#endif

	return;
}
コード例 #13
0
ファイル: FacilityLocation.cpp プロジェクト: phliguori/vpn
int FacilityLocation::createConsRadiusDistance()
{
	// TODO
	// Implementação do corte a seguir: os vértices roteadores da árvore VPN não poderão ser
	// folhas na solução. Isso implica que deverá existir pelo menos dois arcos com extremidada
	// em cada vértice roteador:
	//
	// 2 y_i \leq \sum\limits_{e \in \delta(i)} z_e + \sum\limits_{p \in P} x_{ip}, \forall i \in I
	int numCons = 0;

	std::vector<std::vector<int> > dist((g->nVertices + 1), std::vector<int>((g->nVertices + 1), 0));

	clock_t start, end;

	start = clock();
	bfs(g, dist);
	end = clock();
#ifdef VERBOSE
	std::cout << "\nBFS_time: " << (end - start) / (double)CLOCKS_PER_SEC << "\n";
#endif

	for (auto & terminal : g->terminals)
	{
		// Identifyng all possible distances from node terminal
		std::set<int> distSet;
		for (auto & d : dist[terminal.getCode()])
		{
			if (d > 1)
				distSet.insert(d);
		}
		printf("");

		std::map<int, std::vector<Vertex>> auxp;
		for (auto & router : g->vertices)
		{
			// @annotation: comment next filter to resolve instances where
			// the vpn terminals may be considered internal nodes
			// 20160125
			if (terminal == router || router.isTerminal())
				continue;

			// The pair (terminal, router) corresponds to a variable x_ip
			// and now we know the distance (number of hops) between these
			// two nodes, given by d.
			int dtr = dist[terminal.getCode()][router.getCode()];

			std::vector<Arc> path;
			findShortestPath(router, terminal, g, path);

			if (path.size() > 0)
			{
				Vertex element = (*path.rbegin()).getHead();
				auxp[dtr].push_back(element);
				printf("");
			}
		}
		printf("");
		for (auto & eleDist : auxp)
		{
			int dist = eleDist.first;
			std::vector<Vertex> & elements = eleDist.second;
			std::vector<Vertex> & elementsConstrained = auxp[dist - 1];

			for (int j = 0; j < elementsConstrained.size(); ++j)
			{
				Vertex vj = elementsConstrained[j];
				Variable yj;
				yj.setType(Variable::V_Y);
				yj.setVertex1(vj);

				VariableHash::iterator yIt = vHash[Variable::V_Y].find(yj);
				if (yIt == vHash[Variable::V_Y].end())
					continue;

				Constraint c(elements.size() + 2, Row::LESS, 1.0);
				c.setType(Constraint::C_UNKNOWN);
				c.setClass(dist);
				c.setNode(vj);

				c.rowAddVar(yIt->second, 1.0);

				//std::cout << c.toString() << ": " <<  yj.toString();

				for (int i = 0; i < elements.size(); ++i)
				{
					Vertex router = elements[i];
					Arc a = Arc(router, terminal, 0.);
					Variable xrt;
					xrt.setType(Variable::V_X);
					xrt.setArc(a);

					VariableHash::iterator xIt = vHash[Variable::V_X].find(xrt);
					if (xIt == vHash[Variable::V_X].end())
						continue;

					c.rowAddVar(xIt->second, 1.0);

					//std::cout << " + " << xrt.toString();
				}
				if (c.getRowNnz() > 1)
				{
					bool isInserted = addRow(&c);

					if (isInserted)
					{
						c.setRowIdx(getNRows() - 1);
						cHash[c] = c.getRowIdx();
						numCons++;
					}
				}
				//std::cout << " <= " << 1 << std::endl;
			}
		}
		printf("");
	}
	printf("");
	return numCons;
}
コード例 #14
0
ファイル: main_2.c プロジェクト: pd0wm/epo2
/**
 * Second main function
 * @return
 */
int main_2() {
	// Initializations
	Position start, destination;
	Path_element *path = NULL;

	Path_element *robot_path;
	int x, y;



#ifdef CHALLENGE_AB
	int initial_facing_direction;
	int i;
	static int first_run = 1;

	if (first_run) {
		first_run = 0;

		// Get which places to user wants to visit
		getPlacesToVisit();
	}


	// Reset no_total_path_possible
	no_total_path_possible = 0;
#endif

	// Unvisit all places
	unvisitAll();

	// Seed the rand() function
	srand(time(NULL));
#ifdef CHALLENGE_AB
	// Randomize facing direction
	initial_facing_direction = NORTH;// = rand() % 4 + 1;
#endif

	// Initialize grid
	generateGrid();

#if MINES_ACTIVE == 1
	// Create mines
	// createMines();
	//	removeConnection(0,0,1,0);
	//	removeConnection(1,0,2,0);
	//	removeConnection(0,2,1,2);
	//	removeConnection(2,2,3,2);
	//	removeConnection(3,3,4,3);
	//	removeConnection(0,0,0,1);
	//	removeConnection(1,0,1,1);
	//	removeConnection(1,3,1,4);
	//	removeConnection(2,1,2,2);
	//	removeConnection(2,3,2,4);
	//	removeConnection(3,0,3,1);
	//	removeConnection(4,0,4,1);
	//	removeConnection(4,1,4,2);

	//	removeConnection(0,0,0,1);
	//	removeConnection(1,3,1,2);
	//	removeConnection(2,2,2,3);
	//	removeConnection(4,1,4,2);
#endif

	// Define the start position in the bottom left
	start.x = destination.x = 1;
	start.y = destination.y = 0;

#if MINES_ACTIVE == 1
	// Discover mines at start location
	// discoverMines(start.x, start.y);
#endif

#ifdef CHALLENGE_AB
	int key, q;
	goto go2;
	frombeginning2:
	cls_2();
	printf("Place the robot at the beginning, type '1' to continue...\n");
	key = 0;
	while (!key) { scanf("%d",&key); }
	go2:

	curDir = 0;

	setCommand(new_sck, MOVE, 1, 1, 0);
	wait_till_ready(new_sck);

	setCommand(new_sck, POS, 0, start.x+1, start.y+1);
	wait_till_ready(new_sck);

	// Get first destination
	destination.x = places_to_visit[getTargetPlace(start.x, start.y, initial_facing_direction, 0)][0];
	destination.y = places_to_visit[getTargetPlace(start.x, start.y, initial_facing_direction, 0)][1];

	// Create the robot_path linked list
	robot_path = malloc(sizeof (Path_element));
	robot_path->x = start.x;
	robot_path->y = start.y;
	robot_path->facing_direction = initial_facing_direction;
	robot_path->next = NULL;

	for (q = 0; q < NUM_NODES; q++) getNodeById(q)->mark = 0;

	// Mark places to visit
		for (i = 0; i < NUMBER_OF_PLACES_TO_VISIT; i++) {
			if (!places_to_visit[i][2])
				grid[places_to_visit[i][0]][places_to_visit[i][1]]->mark = 49 + i;
		}

	// Find initial path
		path = findShortestPath(start.x, start.y, initial_facing_direction, destination.x, destination.y);

	// If path == NULL, there was no path found
		if (!path || no_total_path_possible) {
		// Clear screen, print the grid, display a message, sleep for a while and then rerun the program
			cls_2();
			printGrid(robot_path);
			printf("\nCouldn't find a intial path...\n");
		// getchar();
		// main();
			return 0;
		}

	// Record start
		x = start.x;
		y = start.y;

	// Display first move
		cls_2();
		printGrid(robot_path);
	// getchar();
		int moveCorrect = 1;

		while (1) {
			if (kbhit()) goto frombeginning2;

			if (moveCorrect) path = path->next;
		// addToEndOfPath(&robot_path, path->x, path->y);
			if (x == path->x && y == path->y) {
				path = path->next;
			}

			int prevfd = path->facing_direction;

			if (makeMove(x,y,path->x,path->y)) {
				moveCorrect = 1;
				x = path->x;
				y = path->y;


			} else {
				printf("Returned mine between (%d,%d)<curr pos> and (%d,%d)\n",x,y,path->x,path->y);
				removeConnection(x,y,path->x,path->y);
				moveCorrect = 0;

			// prevfd = reverseDirection(prevfd);
			}


		// Move and save position and step weight, also add the position to the path
			if (moveCorrect) {
				path = path->next;
				addToEndOfPath(&robot_path, x, y);
			}

		// printf("VISIT\n");
			visit(x, y);
		// printf("VISITED ALL PLACES\n");
			if (visitedAllPlaces()) break;

		// printf("getTargetPlace\n");

 		// Get destination
			destination.x = places_to_visit[getTargetPlace(x, y, prevfd, 0)][0];
			destination.y = places_to_visit[getTargetPlace(x, y, prevfd, 0)][1];



// #if MINES_ACTIVE == 1
		// Check for mines
		// discoverMines(x, y);

		// Now filter combs for discovered mines

// #endif
		// Calculate new path, mines couldve changed something
// printf("New path %d,%d  %d  %d, %d\n",x,y,prevfd,destination.x,destination.y);

			path = findShortestPath(
			                        x, y,
			                        prevfd,
			                        destination.x,
			                        destination.y
			                        );

		// printf("kay\n");

		// If path == NULL, there was no path found
			if (!path || no_total_path_possible) {
				cls_2();
				printGrid(robot_path);
				printf("Could not find a path!\n");
				getchar();
				return 0;
			}

						// Display path and add step weight to path weight
			cls_2();
			printGrid(robot_path);
			getTargetPlace(x, y, path->facing_direction, DEBUG);
						// getchar();
		}

				// #if MINES_ACTIVE == 1
				// 	// Reveal mines
				// 	revealMines();
// #endif

	// Display final screen
		cls_2();
		printGrid(robot_path);
		printf("\nDone.\n");
		getchar();
#endif

#ifdef CHALLENGE_C
	// Find initial path
	int *combs;
	int index;
	int q;


	// clear grid markings


	// Some unreadable shit which makes things work like they should
	cls_2();
	printf("Press enter to start...\n"); getchar();
	int antiMine = 0;
	rerun:
	goto go3;
	antimine:
	antiMine = 1;
	go3:
	stepsTakenSize = 0;
	index = 0;
	int key;
	goto go2;
	frombeginning:
	cls_2();
	printf("Place the robot at the beginning, type '1' to continue, '9' to restart or '5' to restart in anti-mine mode...\n");
	key = 0;
	while (key==0) { scanf("%d",&key); }
	if(key==9) goto rerun;
	if(key==5) goto antimine;
	go2:

	curDir = 0;

	setCommand(new_sck, MOVE, 1, 1, 0);
	wait_till_ready(new_sck);

	for (q = 0; q < NUM_NODES; q++) getNodeById(q)->mark = 0;

		robot_path = malloc(sizeof (Path_element));
	robot_path->x = start.x;
	robot_path->y = start.y;
	robot_path->next = NULL;

	cls_2();
	printGrid(robot_path);

	setCommand(new_sck, POS, 0, start.x+1, start.y+1);
	wait_till_ready(new_sck);

	x = start.x;
	y = start.y;

	// Find initial path
	combs = exploreArea(grid[start.x][start.y]->id);



	// If path == NULL, there was no path found
	if (!combs) {
		// Clear screen, print the grid, display a message, sleep for a while and then rerun the program
		printf("\nCouldn't find a intial path...\n");
		getchar();
		// main();
		return 0;
	}

	while (1) {
		// Start by removing the path walked from the current combs
		int i;//, fins = 1;

		for (i = 0; combs[i] != -2; i+=2) {
			if (inStepsTaken(combs[i],combs[i+1])) {
				combs[i] = combs[i+1] = -1;
			}
		}
		// Check if there is a comb available
		if (combs[index] == -1) {
			index += 2;
			continue;
		}

		if (combs[index] == -2) break;

		// First walk to first node
		int nodeNow = combs[index];
		int nodeTo = combs[index+1];

		//printf

		path = findShortestPath(x, y,
		                        (path?path->facing_direction:NORTH),
			// 1,
		                        getNodeById(nodeNow)->positionGrid.x,
		                        getNodeById(nodeNow)->positionGrid.y);

		int failed = 0;
		int intcpt = 0;

		while (!(x == getNodeById(nodeNow)->positionGrid.x && y == getNodeById(nodeNow)->positionGrid.y)) {
			if (kbhit()) goto frombeginning;

			if (path && x == path->x && y == path->y) path = path->next;
			else if (!path) {
				printf("FAIL!\n");
				getchar();
				intcpt = 1;
				failed = 1;
				break;
			}

			// printf("Making first MOVE!\n");
			if (makeMove(x,y,path->x,path->y)) {

				stepTaken(grid[x][y]->id,grid[path->x][path->y]->id);
				// printf("Step correct! (from %d to %d)\n", grid[x][y]->id,grid[path->x][path->y]->id);getchar();
				x = path->x;
				y = path->y;
				path = path->next;
				addToEndOfPath(&robot_path, x, y);
			} else {
				if (antiMine) goto frombeginning;
				removeConnection(x,y,path->x,path->y);
				failed = 1;
				break;
			}

			cls_2();
			printGrid(robot_path);
		}

	if (failed) { // Soooo it failed, boohoo.
		if (!intcpt) islandSN(grid[x][y]->id);
			//cls_2();
		printf("Recalculating...\n");
		combs = exploreArea(grid[x][y]->id);
		index = 0;


		cls_2();
		printGrid(robot_path);
		continue;
	}

		// Okay now walk to second node

	path = findShortestPath(x, y,
	                        (path?path->facing_direction:NORTH),
	                        getNodeById(nodeTo)->positionGrid.x,
	                        getNodeById(nodeTo)->positionGrid.y);

	while (!(x == getNodeById(nodeTo)->positionGrid.x && y == getNodeById(nodeTo)->positionGrid.y)) {
		if (kbhit()) goto frombeginning;

		if (path && x == path->x && y == path->y) path = path->next;
		else if (!path) {
			printf("FAIL!\n");
			getchar();
			intcpt = 1;
			failed = 1;
			break;
		}

		if (makeMove(x,y,path->x,path->y)) {
			stepTaken(grid[x][y]->id,grid[path->x][path->y]->id);
				// printf("Step correct! (from %d to %d)\n", grid[x][y]->id,grid[path->x][path->y]->id);getchar();
			x = path->x;
			y = path->y;
			path = path->next;
			addToEndOfPath(&robot_path, x, y);
		} else {
			if (antiMine) goto frombeginning;
			removeConnection(x,y,path->x,path->y);
			failed = 1;
			break;
		}

		cls_2();
		printGrid(robot_path);
	}

		if (failed) { // Soooo it failed, boohoo.
			if (!intcpt) islandSN(grid[x][y]->id);
			//cls_2();
			printf("Recalculating...\n");
			combs = exploreArea(grid[x][y]->id);
			index = 0;
			// islandSN(grid[x][y]->id);

			cls_2();
			printGrid(robot_path);
			continue;
		}

		// Guess everything went okay
		index += 2;
	}

	printf("Aaaaaaaaaaaaaand we're done, type '1' to rerun and '5' to rerun in anti-mine mode!\n");
	key = 0;
	while (key==0) { scanf("%d",&key); }
	if (key==1)	goto rerun;
	else if(key==5) goto antimine;

#endif

	return EXIT_SUCCESS;
}
コード例 #15
0
ファイル: FixEdgeInserterCore.cpp プロジェクト: lncosie/ogdf
	//--------------------------------------------------------------------
	// actual algorithm call
	//--------------------------------------------------------------------
	Module::ReturnType FixEdgeInserterCore::call(
		const Array<edge> &origEdges,
		bool keepEmbedding,
		RemoveReinsertType rrPost,
		double percentMostCrossed)
	{
		double T;
		usedTime(T);

		Module::ReturnType retValue = Module::retFeasible;
		m_runsPostprocessing = 0;

		if(!keepEmbedding) m_pr.embed();
		OGDF_ASSERT(m_pr.representsCombEmbedding() == true);

		if (origEdges.size() == 0)
			return Module::retOptimal;  // nothing to do

		// initialization
		CombinatorialEmbedding E(m_pr);  // embedding of PG

		init(E);
		constructDual(E);

		// m_delFaces and m_newFaces are used by removeEdge()
		// if we can't allocate memory for them, we throw an exception
		if (rrPost != rrNone) {
			m_delFaces = new FaceSetSimple(E);
			if (m_delFaces == nullptr)
				OGDF_THROW(InsufficientMemoryException);

			m_newFaces = new FaceSetPure(E);
			if (m_newFaces == nullptr) {
				delete m_delFaces;
				OGDF_THROW(InsufficientMemoryException);
			}

		// no postprocessing -> no removeEdge()
		} else {
			m_delFaces = nullptr;
			m_newFaces = nullptr;
		}

		SListPure<edge> currentOrigEdges;
		if(rrPost == rrIncremental) {
			for(edge e : m_pr.edges)
				currentOrigEdges.pushBack(m_pr.original(e));
		}

		// insertion of edges
		bool doIncrementalPostprocessing =
			( rrPost == rrIncremental || rrPost == rrIncInserted );
		for(int i = origEdges.low(); i <= origEdges.high(); ++i)
		{
			edge eOrig = origEdges[i];
			storeTypeOfCurrentEdge(eOrig);
			//int eSubGraph = 0;  // edgeSubGraphs-data of eOrig
			//if(edgeSubGraphs!=0) eSubGraph = (*edgeSubGraphs)[eOrig];

			SList<adjEntry> crossed;
			if(m_pCost != nullptr) {
				findWeightedShortestPath(E, eOrig, crossed);
			} else {
				findShortestPath(E, eOrig, crossed);
			}

			insertEdge(E, eOrig, crossed);

			if(doIncrementalPostprocessing) {
				currentOrigEdges.pushBack(eOrig);

				bool improved;
				do {
					++m_runsPostprocessing;
					improved = false;

					for (edge eOrigRR : currentOrigEdges)
					{
						int pathLength = (m_pCost != nullptr) ? costCrossed(eOrigRR) : (m_pr.chain(eOrigRR).size() - 1);
						if (pathLength == 0) continue; // cannot improve

						removeEdge(E, eOrigRR);

						storeTypeOfCurrentEdge(eOrigRR);

						// try to find a better insertion path
						SList<adjEntry> crossed;
						if(m_pCost != nullptr) {
							findWeightedShortestPath(E, eOrigRR, crossed);
						} else {
							findShortestPath(E, eOrigRR, crossed);
						}

						// re-insert edge (insertion path cannot be longer)
						insertEdge(E, eOrigRR, crossed);

						int newPathLength = (m_pCost != nullptr) ? costCrossed(eOrigRR) : (m_pr.chain(eOrigRR).size() - 1);
						OGDF_ASSERT(newPathLength <= pathLength);

						if(newPathLength < pathLength)
							improved = true;
					}
				} while (improved);
			}
		}

		if(!doIncrementalPostprocessing) {
			// postprocessing (remove-reinsert heuristc)
			const int m = m_pr.original().numberOfEdges();
			SListPure<edge> rrEdges;

			switch(rrPost)
			{
			case rrAll:
			case rrMostCrossed:
				for(int i = m_pr.startEdge(); i < m_pr.stopEdge(); ++i)
					rrEdges.pushBack(m_pr.e(i));
				break;

			case rrInserted:
				for(int i = origEdges.low(); i <= origEdges.high(); ++i)
					rrEdges.pushBack(origEdges[i]);
				break;

			case rrNone:
			case rrIncremental:
			case rrIncInserted:
				break;
			}

			// marks the end of the interval of rrEdges over which we iterate
			// initially set to invalid iterator which means all edges
			SListConstIterator<edge> itStop;

			bool improved;
			do {
				// abort postprocessing if time limit reached
				if (m_timeLimit >= 0 && m_timeLimit <= usedTime(T)) {
					retValue = Module::retTimeoutFeasible;
					break;
				}

				++m_runsPostprocessing;
				improved = false;

				if(rrPost == rrMostCrossed)
				{
					FEICrossingsBucket bucket(&m_pr);
					rrEdges.bucketSort(bucket);

					const int num = int(0.01 * percentMostCrossed * m);
					itStop = rrEdges.get(num);
				}

				SListConstIterator<edge> it;
				for(it = rrEdges.begin(); it != itStop; ++it)
				{
					edge eOrig = *it;

					int pathLength = (m_pCost != nullptr) ? costCrossed(eOrig) : (m_pr.chain(eOrig).size() - 1);
					if (pathLength == 0) continue; // cannot improve

					removeEdge(E, eOrig);

					storeTypeOfCurrentEdge(eOrig);

					// try to find a better insertion path
					SList<adjEntry> crossed;
					if(m_pCost != nullptr) {
						findWeightedShortestPath(E, eOrig, crossed);
					} else {
						findShortestPath(E, eOrig, crossed);
					}

					// re-insert edge (insertion path cannot be longer)
					insertEdge(E, eOrig, crossed);

					// we cannot find a shortest path that is longer than before!
					int newPathLength = (m_pCost != nullptr) ? costCrossed(eOrig) : (m_pr.chain(eOrig).size() - 1);
					OGDF_ASSERT(newPathLength <= pathLength);

					if(newPathLength < pathLength)
						improved = true;
				}
			} while (improved);
		}

		// verify computed planarization
		OGDF_ASSERT(m_pr.representsCombEmbedding());

		// free resources
		cleanup();

		return retValue;
	}
コード例 #16
0
ファイル: hunter.c プロジェクト: haydenvr/furydracula
void decideMove (HunterView gameState) {
    printf("at start of code\n"); fflush(stdout);
	Graph g = newGraph();
    char *locations[] = {
        "AL", "AM", "AT", "BA", "BI", "BE", "BR", "BO", "BU", "BC", 
        "BD", "CA", "CG", "CD", "CF", "CO", "CN", "DU", "ED", "FL",
        "FR", "GA", "GW", "GE", "GO", "GR", "HA", "JM", "KL", "LE",
        "LI", "LS", "LV", "LO", "MA", "MN", "MR", "MI", "MU", "NA",
        "NP", "NU", "PA", "PL", "PR", "RO", "SA", "SN", "SR", "SJ",
        "SO", "ST", "SW", "SZ", "TO", "VA", "VR", "VE", "VI", "ZA",
        "ZU", "NS", "EC", "IS", "AO", "BB", "MS", "TS", "IO", "AS", 
        "BS", "C?", "S?", "HI", "D1", "D2", "D3", "D4", "D5", "TP"
	};
	int round = getRound(gameState);
	PlayerID id = getCurrentPlayer(gameState);
    LocationID move = getLocation(gameState, id);
    printf("the original loc is %d and health %d\n",move,getHealth(gameState,id));
	char * msg = "";
    printf("initialised all variables\n"); fflush(stdout);
	//set initial locations
	if (round - id == 0) {
	    if (id == PLAYER_LORD_GODALMING) {move = CASTLE_DRACULA; msg = "camping";}
	    else if (id == PLAYER_DR_SEWARD)  move = BELGRADE;
	    else if (id == PLAYER_VAN_HELSING) move = STRASBOURG;
	    else if (id == PLAYER_MINA_HARKER) move = MADRID;
	    registerBestPlay(locations[move], msg);
	    destroyGraph(g);
	    return;
    }
    printf("done initial moves\n"); fflush(stdout);

    //below code will throw errors if LG is killed
    //if (id == PLAYER_LORD_GODALMING) { registerBestPlay("CD","I'm camping MAN!!!"); return; }
	srand (time(NULL));
	int path[NUM_MAP_LOCATIONS];
    int amtLocs = 0;
    LocationID * adj = connectedLocations(&amtLocs, getLocation(gameState, id), id, round, ANY, g);
    LocationID target = UNKNOWN_LOCATION;
    int camper = 0, i, j;
    printf("setting up connected locs etc\n"); fflush(stdout);

    // check for campers
    // if the current player is camping, then the player
    // will stay camping and ai will return
    
    for (i = 0; i < NUM_HUNTERS; i++) {
        if (getLocation(gameState, i) == CASTLE_DRACULA) {
            camper = 1;
            if (id == i) {
	            registerBestPlay("CD", "Staying camping");
                destroyGraph(g);
                free(adj);
                return; 
            }
        }
    } 

    if (!camper) { //if no camper and hunter is shortest dist to castle dracula, move towards castle dracula
        int hunterDist[NUM_HUNTERS] = {UNKNOWN_LOCATION,UNKNOWN_LOCATION,UNKNOWN_LOCATION,UNKNOWN_LOCATION};
        int closestHunter = PLAYER_LORD_GODALMING;
        for (i = PLAYER_LORD_GODALMING; i < NUM_HUNTERS; i++) {
            hunterDist[i] = findShortestPath(getLocation(gameState, i), CASTLE_DRACULA, path, ANY, round);
            if (hunterDist[i] == -1) hunterDist[i] = 1000; //-1 is when there is no path, so don't want him to be shortest
            if ((hunterDist[closestHunter] > hunterDist[i]) || (hunterDist[closestHunter] == UNKNOWN_LOCATION)) closestHunter = i;
        }
        if (closestHunter == id) move = path[1];
    } else {
        LocationID draculaLoc[TRAIL_SIZE];
        getHistory (gameState, PLAYER_DRACULA, draculaLoc); //updates Dracula trail

        for (i = TRAIL_SIZE - 1; i >= 0 ; i--) //locations newer in trail will override older ones
            target = dracTarget(draculaLoc, i); //we have any useful info on his location...

        if (target != UNKNOWN_LOCATION) {
            //Note: Dracula cannot visit any location currently in his trail - hunters should not visit target itself!
            int pathLen = findShortestPath(getLocation(gameState, id), target, path, ANY, round); //success is any number not -1
        	if (getLocation(gameState, id) != target && pathLen != -1) { //path found, and not at rest on target (Drac's trail)
                if (path[1] != target) move = path[1]; 
                //don't move into Dracula's trail (see note above)
                else move = adj[rand() % amtLocs];
                for (i = 0; i < TRAIL_SIZE ; i++) if (path[1] == dracTarget(draculaLoc, i)) move = adj[rand() % amtLocs];
            } else move = adj[rand() % amtLocs];
		} else { //prevents doubling up of hunters when making a random move, since Dracula 404
            int occupied = 0, newLoc = UNKNOWN_LOCATION;
            move = adj[rand() % amtLocs];
            for (j = 0; j < NUM_HUNTERS; j++) if (move == getLocation(gameState, j)) occupied = 1;
            if (occupied) { 
                for (i = 0; i < amtLocs; i++) { 
                    occupied = 0;
                    for (j = 0; j < NUM_HUNTERS; j++) if (adj[i] == getLocation(gameState, j)) occupied = 1;
                    if (!occupied) {newLoc = i; break;}
                }
            }
            if (newLoc != UNKNOWN_LOCATION) move = adj[newLoc]; 
        }
    } 
    if (target != UNKNOWN_LOCATION) printf("*Moving from %s (%d) to target %s (%d) via %s (%d)*\n", locations[getLocation(gameState, id)], getLocation(gameState, id), locations[target], target, locations[move], move);
    else printf("*No target - moving from %s (%d) to %s (%d)*\n", locations[getLocation(gameState, id)], getLocation(gameState, id), locations[move], move);
    
	if (isLegalMove(gameState, id, move, round, g)) registerBestPlay(locations[move], "");
	else {
        printf("ERROR: Location is invalid! Registering default rest move...");
        registerBestPlay(locations[getLocation(gameState, id)], "");
    }
    destroyGraph(g);
    free(adj);
}