/******************************************************************** * Simple weighted similarity function ********************************************************************/ double Scan::weightedMeanSim(uint node1, uint node2) { // Variables std::set<Edge> *n1, *n2; std::set<Edge> inter; double divisor; n1 = g.getAdjacency(node1); n2 = g.getAdjacency(node2); // Calculate the intersection between the edges' neighbors set_intersection(n1->begin(),n1->end(), n2->begin(), n2->end(), std::insert_iterator< std::set<Edge> > (inter, inter.begin())); divisor = n1->size() * n2->size(); divisor = sqrt(divisor); divisor = (inter.size()/(double)divisor); // Ou seja, média simples entre a similaridade tradicional e o peso // da aresta entre os vértices return (divisor + getEdgeWeight(node1, node2))/2.0; }
// Dijkstra 알고리즘 int *shortestPathDijkstra(LinkedGraph* pGraph, int startVertexID) { int *pReturn = NULL; int *pSelected = NULL; int nodeCount = 0, maxNodeCount = 0; int i = 0, j = 0, weight = 0; int vertexID = 0, y_w = 0, y_v = 0; ListNode *pListNode = NULL; LinkedList *pEdgeList = NULL; if (pGraph == NULL) { printf("Graph is NULL\n"); return pReturn; } maxNodeCount = getMaxVertexCountLG(pGraph); nodeCount = getVertexCountLG(pGraph); pReturn = (int *)malloc(sizeof(int) * maxNodeCount); pSelected = (int *)malloc(sizeof(int) * maxNodeCount); if (pReturn == NULL || pSelected == NULL) { if (pReturn != NULL) free(pReturn); printf("오류, 메모리 할당 in shortestPathDijkstra()\n"); return NULL; } // Step 0. 초기화 for(i = 0; i < maxNodeCount; i++) { if (i == startVertexID) { pReturn[i] = 0; } else { if (pGraph->pVertex[i] == USED) { pSelected[i] = TRUE; pReturn[i] = getEdgeWeight(pGraph, startVertexID, i); } else { pSelected[i] = FALSE; pReturn[i] = MAX_INT; } } } for(i = 0; i < maxNodeCount; i++) { printf("(%d,%d)->%d\n", startVertexID, i, pReturn[i]); } for(i = 0; i < nodeCount - 1; i++) { printf("[%d]-Iteration\n", i+1); // Step-1. // 집합 S중 최단 거리를 가지는 정점(vertexID)을 선택 vertexID = getMinDistance(pReturn, pSelected, maxNodeCount); pSelected[vertexID] = FALSE; // 선택된 정점(vertexID)에 인접한 정점들에 대해 거리 변경 조건 점검. pEdgeList = pGraph->ppAdjEdge[vertexID]; pListNode = pEdgeList->headerNode.pLink; while(pListNode != NULL) { int toVertexID = pListNode->data.vertexID; int weight = pListNode->data.weight; // y_v + c_v,w 와 y_w 비교 y_v = pReturn[vertexID]; y_w = pReturn[toVertexID]; if (y_v + weight < y_w) { pReturn[toVertexID] = y_v + weight; } pListNode = pListNode->pLink; } for(j = 0; j < maxNodeCount; j++) { printf("\t(%d,%d)->%d\n", startVertexID, j, pReturn[j]); } } free(pSelected); return pReturn; }
/******************************************************************** * Similarity function using only edge weight ********************************************************************/ double Scan::weightedOnlySim(uint node1, uint node2) { return getEdgeWeight(node1, node2); }
NetPath DijkstraRouter::search() { if ( !validateInput() ) { printf("[RD]Wrong input\n"); return NetPath(); } if ( link->getFirst() == link->getSecond() ) return NetPath(); std::set<ElementWeight, WeightCompare> elementsToParse; std::map<Element * , Link *> incomingEdge; std::map<Element * , std::vector<Link *> > elementLinks; Links & links = network->getLinks(); for ( Links::iterator i = links.begin(); i != links.end(); i++ ) { Link * l = *i; if ( l->getFirst() != link->getFirst() ) elementsToParse.insert(ElementWeight(l->getFirst(), LONG_MAX)); if ( l->getSecond() != link->getFirst() ) elementsToParse.insert(ElementWeight(l->getSecond(), LONG_MAX)); elementLinks[l->getFirst()].push_back(l); elementLinks[l->getSecond()].push_back(l); } elementsToParse.insert(ElementWeight(link->getFirst(), 0)); elementsToParse.insert(ElementWeight(link->getSecond(), LONG_MAX)); Element * currentElement = link->getFirst(); Link edge("dijkstraedge", 0); ElementWeight temp(0, -LONG_MAX); std::set<ElementWeight, WeightCompare>::iterator tempIter; long curWeight = 0; while ( currentElement != 0 && currentElement != link->getSecond() ) { temp.element = currentElement; tempIter = elementsToParse.find(temp); assert(tempIter != elementsToParse.end()); curWeight = tempIter->weight; elementsToParse.erase(tempIter); if ( elementLinks.find(currentElement) == elementLinks.end() ) return NetPath(); std::vector<Link *>& curLinks = elementLinks[currentElement]; unsigned int size = curLinks.size(); for(unsigned int index = 0; index < size; index++) { Link * cur = curLinks[index]; Element * other = cur->getFirst() == currentElement ? cur->getSecond() : cur->getFirst(); temp.element = other; temp.weight = LONG_MAX; tempIter = elementsToParse.find(temp); if ( tempIter != elementsToParse.end() ) { edge.setCapacity(cur->getCapacity()); edge.bindElements(currentElement, other); long weight = getEdgeWeight(&edge) + curWeight; if ( weight < tempIter->weight ) { temp.element = other; temp.weight = weight; elementsToParse.erase(tempIter); elementsToParse.insert(temp); incomingEdge[other] = cur; } } temp.weight = -LONG_MAX; } if (elementsToParse.begin()->weight != LONG_MAX) currentElement = elementsToParse.begin()->element; else return NetPath(); } if ( currentElement != link->getSecond() ) return NetPath(); Element * other = currentElement; NetPath result; while ( incomingEdge[currentElement]->getFirst() != link->getFirst() && incomingEdge[currentElement]->getSecond() != link->getFirst() ) { result.push_back(incomingEdge[currentElement]); other = incomingEdge[currentElement]->getFirst() == currentElement ? incomingEdge[currentElement]->getSecond() : incomingEdge[currentElement]->getFirst(); result.push_back((NetworkingElement *)other); currentElement = other; } result.push_back(incomingEdge[other]); std::reverse(result.begin(), result.end()); return result; }
void CutShape::setDissimilarityMatrix(int n, double *dissimilarity, DTWMode mode) { matchingMode = mode; shapeNum = n; isMatched = false; // delete existing memory matching.clear(); if (verts) delete [] verts; if (edges) delete [] edges; if (faces) delete [] faces; // reserve memory for the graph int numEh, numEv; PlanarEdge *edgesH, *edgesV, *edgesD; vertsPerRow = 4 * shapeNum; facesPerRow = 2 * shapeNum + 1; vertRows = shapeNum; faceRows = shapeNum + 1; numF = facesPerRow * faceRows - (shapeNum+1); // cylinder connectivity numV = vertsPerRow * vertRows + 2; // source and sink numE = numF + numV - 2; numEh = 2 * (shapeNum * shapeNum) + shapeNum; // horizontal edges numEv = 2 * (shapeNum * shapeNum) + shapeNum; // vertical edges faces = new PlanarFace[numF]; verts = new PlanarVertex[numV]; edges = new PlanarEdge[numE]; edgesH = edges; edgesV = edges + numEh; edgesD = edges + numEh + numEv; sink = verts + (numV - 1); source = verts + (numV - 2); // define edges int edgeID; PlanarVertex *u, *v; double weight, weightR; // define horizontal edges edgeID = 0; for (int y=0; y<faceRows; y++) { for (int x=0; (y==faceRows-1) ? (x<shapeNum) : (x<facesPerRow-1); x++) { u = vertXY(x*2+1, y); v = vertXY(x*2, y-1); weight = getEdgeWeight(x, y, dissimilarity, HORIZONTAL); weightR = CAP_INF; if (u == source || v == sink) { if (weight < EPSILON) weight = EPSILON; weightR = 0; } edgesH[edgeID++].setEdge(u, v, faceXY(x+1,y), faceXY(x,y), weight, weightR); } } // define vertical edges edgeID = 0; for (int y=0; y<faceRows-1; y++) { for (int x=0; x<facesPerRow; x++) { u = vertXY(x*2-1, y); v = vertXY(x*2 , y); weight = getEdgeWeight(x, y, dissimilarity, VERTICAL); weightR = CAP_INF; if (u == source || v == sink) { if (weight < EPSILON) weight = EPSILON; weightR = 0; } edgesV[edgeID++].setEdge(u, v, faceXY(x,y+1), faceXY(x,y), weight, weightR); } } // define diagonal edges edgeID = 0; for (int y=0; y<faceRows-1; y++) { for (int x=0; x<facesPerRow-1; x++) { u = vertXY(x*2, y); v = vertXY(x*2+1, y); weight = getEdgeWeight(x, y, dissimilarity, DIAGONAL); weightR = CAP_INF; if (u == source || v == sink) { if (weight < EPSILON) weight = EPSILON; weightR = 0; } edgesD[edgeID++].setEdge(u, v, faceXY(x+1,y+1), faceXY(x,y), weight, weightR); } } //define ccw for every vertex (except source and sink) PlanarEdge **ccw; int dIdx, hIdx, vIdx; hEdgesPerRow = facesPerRow - 1; vEdgesPerRow = facesPerRow; dEdgesPerRow = facesPerRow - 1; ccw = new PlanarEdge*[3]; dIdx = hIdx = vIdx = 0; for (int y=0; y<vertRows; y++) { int x1, x2; for (x1=0, x2=1; x1<vertsPerRow; x1+=2, x2+=2) { ccw[0] = edgesD + dIdx; ccw[1] = edgesH + ((hIdx + hEdgesPerRow) % numEh); //cyclic ccw[2] = edgesV + vIdx; (vertXY(x1,y))->setEdgesCCW(ccw, 3); ccw[1] = edgesH + hIdx; ccw[2] = edgesV + (vIdx + 1); (vertXY(x2,y))->setEdgesCCW(ccw, 3); dIdx++; hIdx++; vIdx++; } vIdx++; //between two rows, the verts do not have one single common edge } delete [] ccw; //define source edges ccw = new PlanarEdge*[2*shapeNum]; for (edgeID=0, vIdx=0; edgeID<shapeNum; edgeID++, vIdx+=vEdgesPerRow) ccw[edgeID] = edgesV + vIdx; for (edgeID=shapeNum, hIdx=shapeNum*hEdgesPerRow; edgeID<shapeNum*2; edgeID++,hIdx++) ccw[edgeID] = edgesH + hIdx; source->setEdgesCCW(ccw, shapeNum*2); //define sink edges for (edgeID=0, vIdx=shapeNum*vEdgesPerRow-1; edgeID<shapeNum; edgeID++, vIdx -= vEdgesPerRow) ccw[edgeID] = edgesV + vIdx; for (edgeID=shapeNum, hIdx=hEdgesPerRow-1; edgeID<shapeNum*2; edgeID++, hIdx--) ccw[edgeID] = edgesH + hIdx; sink->setEdgesCCW(ccw, shapeNum*2); delete [] ccw; }