void main() { Graph g; CSTree t; printf("请选择无向图\n"); CreateGraph(g); Display(g); DFSForest(g, t); printf("先序遍历生成森林:\n"); PreOrderTraverse(t, Visit); printf("\n"); }
void main() { int i,j,k,n; ALGraph g; VertexType v1,v2; printf("请顺序选择有向图,有向网,无向图,无向网\n"); for(i=0;i<4;i++) // 验证4种情况 { CreateGraph(g); Display(g); printf("插入新顶点,请输入顶点的值: "); scanf("%s",v1); InsertVex(g,v1); printf("插入与新顶点有关的弧或边,请输入弧或边数: "); scanf("%d",&n); for(k=0;k<n;k++) { printf("请输入另一顶点的值: "); scanf("%s",v2); if(g.kind<=1) // 有向 { printf("对于有向图或网,请输入另一顶点的方向(0:弧头 1:弧尾): "); scanf("%d",&j); if(j) InsertArc(g,v2,v1); else InsertArc(g,v1,v2); } else // 无向 InsertArc(g,v1,v2); } Display(g); if(i==3) { printf("删除一条边或弧,请输入待删除边或弧的弧尾 弧头:"); scanf("%s%s",v1,v2); DeleteArc(g,v1,v2); printf("修改顶点的值,请输入原值 新值: "); scanf("%s%s",v1,v2); PutVex(g,v1,v2); } printf("删除顶点及相关的弧或边,请输入顶点的值: "); scanf("%s",v1); DeleteVex(g,v1); Display(g); DestroyGraph(g); } }
int main( void ) { /* 그래프 생성 */ Graph* G = CreateGraph(); /* 정점 생성 */ Vertex* V1 = CreateVertex( '1' ); Vertex* V2 = CreateVertex( '2' ); Vertex* V3 = CreateVertex( '3' ); Vertex* V4 = CreateVertex( '4' ); Vertex* V5 = CreateVertex( '5' ); /* 그래프에 정점을 추가 */ AddVertex( G, V1 ); AddVertex( G, V2 ); AddVertex( G, V3 ); AddVertex( G, V4 ); AddVertex( G, V5 ); /* 정점과 정점을 간선으로 잇기 */ AddEdge( V1, CreateEdge(V1, V2, 0) ); AddEdge( V1, CreateEdge(V1, V3, 0) ); AddEdge( V1, CreateEdge(V1, V4, 0) ); AddEdge( V1, CreateEdge(V1, V5, 0) ); AddEdge( V2, CreateEdge(V2, V1, 0) ); AddEdge( V2, CreateEdge(V2, V3, 0) ); AddEdge( V2, CreateEdge(V2, V5, 0) ); AddEdge( V3, CreateEdge(V3, V1, 0) ); AddEdge( V3, CreateEdge(V3, V2, 0) ); AddEdge( V4, CreateEdge(V4, V1, 0) ); AddEdge( V4, CreateEdge(V4, V5, 0) ); AddEdge( V5, CreateEdge(V5, V1, 0) ); AddEdge( V5, CreateEdge(V5, V2, 0) ); AddEdge( V5, CreateEdge(V5, V4, 0) ); PrintGraph( G ); /* 그래프 소멸 */ DestroyGraph( G ); return 0; }
int main() { //그래프 생성 Graph* G = CreateGraph(); // 정점 생성 Vertex* V1 = CreateVertex('1'); Vertex* V2 = CreateVertex('2'); Vertex* V3 = CreateVertex('3'); Vertex* V4 = CreateVertex('4'); Vertex* V5 = CreateVertex('5'); // 그래프에 정점을 추가 AddVertex(G, V1); AddVertex(G, V2); AddVertex(G, V3); AddVertex(G, V4); AddVertex(G, V5); // 정점과 정점을 간선으로 잇기 AddEdge(V1, CreateEdge(V1, V2, 0)); AddEdge(V1, CreateEdge(V1, V3, 0)); AddEdge(V1, CreateEdge(V1, V4, 0)); AddEdge(V1, CreateEdge(V1, V5, 0)); AddEdge(V2, CreateEdge(V2, V1, 0)); AddEdge(V2, CreateEdge(V2, V2, 0)); AddEdge(V2, CreateEdge(V2, V5, 0)); AddEdge(V3, CreateEdge(V3, V1, 0)); AddEdge(V3, CreateEdge(V3, V2, 0)); AddEdge(V4, CreateEdge(V4, V1, 0)); AddEdge(V4, CreateEdge(V4, V5, 0)); AddEdge(V5, CreateEdge(V5, V1, 0)); AddEdge(V5, CreateEdge(V5, V2, 0)); AddEdge(V5, CreateEdge(V5, V4, 0)); PrintGraph(G); // 그래프 소멸 DestroyGraph(G); return 0; }
int main(int argc, char *argv[]) { graph g; g = CreateGraph(9); g = AddEdgeDirected(g,1,2); g = AddEdgeDirected(g,1,4); g = AddEdgeDirected(g,1,3); //g = AddEdgeDirected(g,4,2); //g = AddEdgeDirected(g,3,4); g = AddEdgeDirected(g,3,5); g = AddEdgeDirected(g,4,6); g = AddEdgeDirected(g,5,9); g = AddEdgeDirected(g,5,8); g = AddEdgeDirected(g,9,7); //printf("%d ", Value(g[1].top->next)); IsCyclicGraph(g); }
LGraph BuildGraph() { int i; int nv,ne; LGraph newGraph; Edge newEdge; printf("input Nv,Ne:"); scanf("%d %d",&nv,&ne); newGraph = CreateGraph(nv); newGraph->ne = ne; for(i = 0; i< ne; i++){ newEdge = (Edge)malloc(sizeof(struct ENode)); printf("input <v1,v2>"); scanf("%d %d %d",&newEdge->v1,&newEdge->v2,&newEdge->weight);/*有权重就读权重呗*/ InsertEdge(newGraph,newEdge); } return newGraph; }
static bool GenDrawFormatFile(Digraph& dg, VNG_Param& param, const string& fmt, char** result, unsigned int* length) { GVC_t* gvc = gvContext(); //创建图 Agraph_t* g = CreateGraph(dg, param); gvLayout(gvc,g,"dot"); //写入到缓存数组中 gvRenderData(gvc,g,fmt.c_str(), result, length); //gvFreeRenderData(result); gvFreeLayout(gvc,g); agclose(g); // gvfreecontext函数返回错误个数 // 错误数为0表示没有问题 return (gvFreeContext(gvc) == 0); }
BOOL CGraphShowDlg::OnInitDialog() { CDialog::OnInitDialog(); if (m_uiADCFileLength > 0) { m_pSampleData = new double[m_uiADCFileLength]; } // 创建绘图控件并设置相关参数 CreateGraph(IDC_STATIC_GRAPHSHOW, &m_OScopeCtrl); // customize the control SetRange(DrawGraphYAxisLower, DrawGraphYAxisUpper, DecimalPlaces, &m_OScopeCtrl) ; SetYUnits(DrawGraphYAxisLabel, &m_OScopeCtrl) ; SetXUnits(DrawGraphXAxisLabel, &m_OScopeCtrl) ; SetBackgroundColor(DrawGraphSetBackgroundColor, &m_OScopeCtrl) ; SetGridColor(DrawGraphSetGridColor, &m_OScopeCtrl) ; SetPlotColor(DrawGraphSetPlotColor, &m_OScopeCtrl) ; m_Sec_GraphADCShow.Lock(); m_uiADCGraphDrowFromNb = (m_pADCDataRecThread->m_uiADCDataFrameCount[m_uiADCGraphNb - 1]) * ReceiveDataSize; m_Sec_GraphADCShow.Unlock(); if (m_uiADCGraphDrowFromNb > m_OScopeCtrl.m_uiXAxisPointNum) { m_OScopeCtrl.m_uiXAxisLabelMax = m_uiADCGraphDrowFromNb; } else { m_OScopeCtrl.m_uiXAxisLabelMax = m_OScopeCtrl.m_uiXAxisPointNum; } m_OScopeCtrl.m_uiXAxisLabelMin = m_OScopeCtrl.m_uiXAxisLabelMax - m_OScopeCtrl.m_uiXAxisPointNum; m_OScopeCtrl.Reset(false); m_OScopeCtrl.m_dPreviousPosition = 0.0; m_OScopeCtrl.m_uiPointNum = m_uiADCGraphDrowFromNb; // 绘制了的点的个数 // OnSetHScrollBarRange(); m_OScopeCtrl.m_bStopSample = m_bStopSample; m_Sec_GraphADCShow.Lock(); m_pADCDataRecThread->m_pOScopeCtrl[m_uiADCGraphNb - 1] = &m_OScopeCtrl; m_pADCDataRecThread->m_uiADCGraphIP[m_uiADCGraphNb - 1] = IPSetAddrStart + IPSetAddrInterval * m_uiADCGraphNb; m_Sec_GraphADCShow.Unlock(); return TRUE; // return TRUE unless you set the focus to a control }
BOOL CGraphShowDlg::OnInitDialog() { CDialog::OnInitDialog(); // 创建绘图控件并设置相关参数 CreateGraph(IDC_STATIC_GRAPHSHOW, &m_OScopeCtrl); // customize the control SetRange(-2.5, 2.5, DecimalPlaces, &m_OScopeCtrl) ; SetYUnits("Y", &m_OScopeCtrl) ; SetXUnits("X", &m_OScopeCtrl) ; SetBackgroundColor(RGB(0, 0, 64), &m_OScopeCtrl) ; SetGridColor(RGB(192, 192, 255), &m_OScopeCtrl) ; SetPlotColor(RGB(255, 255, 255), &m_OScopeCtrl) ; unsigned int uiLength = 0; m_Sec.Lock(); uiLength = m_ADCDataRecThread->m_uiADCDataFrameCount[m_uiADCGraphNb - 1] * ReceiveDataSize; m_Sec.Unlock(); if (uiLength > m_OScopeCtrl.m_uiXAxisPointNum) { m_OScopeCtrl.m_uiXAxisLabelMax = uiLength; } else { m_OScopeCtrl.m_uiXAxisLabelMax = m_OScopeCtrl.m_uiXAxisPointNum; } m_OScopeCtrl.m_uiXAxisLabelMin = m_OScopeCtrl.m_uiXAxisLabelMax - m_OScopeCtrl.m_uiXAxisPointNum; m_OScopeCtrl.Reset(false); m_OScopeCtrl.m_dPreviousPosition = 0.0; m_OScopeCtrl.m_uiPointNum = uiLength; // 绘制了的点的个数 m_dSampleData.reserve(1024); OnSetHScrollBarRange(); m_Sec.Lock(); m_ADCDataRecThread->m_uiADCGraphIP = 71 + 10 * m_uiADCGraphNb; m_Sec.Unlock(); m_OScopeCtrl.m_bStopSample = m_bStopSample; return TRUE; // return TRUE unless you set the focus to a control }
int main() { MGraph graph; int articulated[MAXVEX + 1]; int i, j; if (CreateGraph(&graph) != OK)return 1; for (i = 0; i < graph.vexnum; i++) { for (j = 0; j < graph.vexnum; j++) { if (graph.arcs[i][j] == MAXINT)printf("∞"); else printf("%2d", graph.arcs[i][j]); } printf("\n"); } printf("%d\n", isBiconnectedGraph(graph)); if (FindArticul(graph, articulated) != OK)return 1; for (i = 1; i <= articulated[0]; ++i) printf("%d ", articulated[i]); printf("\n"); return 0; }
BacklashGraph::BacklashGraph(wxDialog *parent, BacklashTool *pBL) : wxDialog(parent, wxID_ANY, wxGetTranslation(_("Backlash Results")), wxDefaultPosition, wxSize(500, 400)) { m_BLT = pBL; // Just but a big button area for the graph with a button below it wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); // Use a bitmap button so we don't waste cycles in paint events wxBitmap theGraph = CreateGraph(450, 300); wxBitmapButton *graphButton = new wxBitmapButton(this, wxID_ANY, theGraph, wxDefaultPosition, wxSize(450, 300), wxBU_AUTODRAW | wxBU_EXACTFIT); vSizer->Add(graphButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxFIXED_MINSIZE, 5); graphButton->SetBitmapDisabled(theGraph); graphButton->Enable(false); // ok button because we're modal vSizer->Add( CreateButtonSizer(wxOK), wxSizerFlags(0).Expand().Border(wxALL, 10)); SetSizerAndFit(vSizer); }
void main() { int i,j,k,n; MGraph g; VertexType v1,v2; printf("请顺序选择有向图,有向网,无向图,无向网\n"); for(i=0;i<4;i++) // 验证4种情况 { CreateGraph(g); // 构造图g Display(g); // 输出图g printf("插入新顶点,请输入顶点的值: "); scanf("%s",v1); InsertVex(g,v1); printf("插入与新顶点有关的弧或边,请输入弧或边数: "); scanf("%d",&n); for(k=0;k<n;k++) { printf("请输入另一顶点的值: "); scanf("%s",v2); if(g.kind<=1) // 有向 { printf("对于有向图或网,请输入另一顶点的方向(0:弧头 1:弧尾): "); scanf("%d",&j); if(j) // v2是弧尾 InsertArc(g,v2,v1); else // v2是弧头 InsertArc(g,v1,v2); } else // 无向 InsertArc(g,v1,v2); } Display(g); // 输出图g printf("删除顶点及相关的弧或边,请输入顶点的值: "); scanf("%s",v1); DeleteVex(g,v1); Display(g); // 输出图g } DestroyGraph(g); // 销毁图g }
int main(){ int n; printf("\nEnter the number of nodes in graph : "); scanf("%d",&n); GNode* graph=CreateGraph(n); int i,source,dest; int E; printf("\nEnter the number of edges : "); scanf("%d",&E); for(i=0;i<E;i++){ printf("\nEnter source destionation..."); scanf("%d %d",&source,&dest); AddVertex(graph,source,dest); } printf("\nPress enter to traverse adjacency List\n"); getch(); TraverseAdjList(graph); getch(); printf("\nEnter src & dest to see if there exists a path between them : "); scanf("%d %d",&source,&dest); int result=BFS(graph,source,dest); printf("\nPress enter to see result : "); getch(); if(result){ printf("\nYes - Path exists"); }else{ printf("\nNo - Path doesn't exist"); } getch(); return 0; }
// Populate one of the panels in the wxNotebook void CalReviewDialog::CreatePanel(wxPanel* thisPanel, bool AO) { wxBoxSizer* panelHSizer = new wxBoxSizer(wxHORIZONTAL); thisPanel->SetSizer(panelHSizer); // Put the graph and its legend on the left side wxBoxSizer* panelGraphVSizer = new wxBoxSizer(wxVERTICAL); panelHSizer->Add(panelGraphVSizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); // Use a bitmap button so we don't have to fool with Paint events wxBitmap theGraph = CreateGraph(AO); wxBitmapButton* graphButton = new wxBitmapButton(thisPanel, wxID_ANY, theGraph, wxDefaultPosition, wxSize(250, 250), wxBU_AUTODRAW | wxBU_EXACTFIT); panelGraphVSizer->Add(graphButton, 0, wxALIGN_CENTER_HORIZONTAL | wxALL | wxFIXED_MINSIZE, 5); graphButton->SetBitmapDisabled(theGraph); graphButton->Enable(false); wxBoxSizer* graphLegendGroup = new wxBoxSizer(wxHORIZONTAL); panelGraphVSizer->Add(graphLegendGroup, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); wxStaticText* labelRA = new wxStaticText(thisPanel, wxID_STATIC, _("Right Ascension"), wxDefaultPosition, wxDefaultSize, 0); labelRA->SetForegroundColour(pFrame->pGraphLog->GetRaOrDxColor()); if (AO) labelRA->SetLabelText(_("X")); else labelRA->SetLabelText(_("Right Ascension")); graphLegendGroup->Add(labelRA, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); wxStaticText* labelDec = new wxStaticText(thisPanel, wxID_STATIC, _("Declination"), wxDefaultPosition, wxDefaultSize, 0); labelDec->SetForegroundColour(pFrame->pGraphLog->GetDecOrDyColor()); if (AO) labelDec->SetLabelText(_("Y")); else labelDec->SetLabelText(_("Declination")); graphLegendGroup->Add(labelDec, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); // Done with left-hand side // Now put the data grid(s) on the right side thisPanel->SetForegroundColour("WHITE"); CreateDataGrids(thisPanel, panelHSizer, AO); // Virtual function }
void create_theory(){ double mass[]={300,400,500,600,700,800,900,1000}; int N=sizeof(mass)/sizeof(double); double stopxs[]={1.99608,0.35683,0.0855847,0.0248009,0.0081141,0.00289588,0.00109501,0.000435488}; double squarkxs[]={19.8283,3.54338,0.847051,0.244862,0.0799667,0.0284146, 0.0106744, 0.00424173,0.0106744}; double squarkxsE[]={15.8736,15.6882,16.3916,17.9829,19.7578,22.2285,25.4549}; double scale=0.4; CreateGraph("stop_xs_st_Acc0p5"); for(int iP=0; iP<N; iP++){ grName["stop_xs"]->SetPoint(iP,mass[iP],stopxs[iP]*1000); grName["stop_xs_st_Acc0p5"]->SetPoint(iP,mass[iP]*2,stopxs[iP]*1000*0.005); } for(int iP=0; iP<N; iP++){ grName["squark_xs"]->SetPoint(iP,mass[iP],scale*squarkxs[iP]*1000); grName["squark_xs"]->SetPointError(iP,0,0,scale*squarkxs[iP]*(squarkxsE[iP]/100)*1000,squarkxs[iP]*(squarkxsE[iP]/100)*1000); } }
main() { int x,y,vertex,*result; char input[1000],*num; tGraph *graph; printf("input vertex count of your gragdddp:") ; scanf("%d",&vertex); graph=CreateGraph(vertex); printf("input your graph use matrix \n"); for (x=0;x<vertex;x++) { scanf("%s",input); num=strtok(input,SP); y=0; while(num!=NULL) { if(isdigit(num[0])) SetVertex(graph,x,y,atoi(num)); num=strtok(NULL,SP); y++; } } for (x=0;x<vertex;x++) for(y=0;y<vertex;y++) printf("%d ",GetVertex(graph,x,y)),y==vertex-1?printf("\n"):0; result=CalcShortestPath(graph,0,vertex-1); x=0; if (result!=NULL) { while (result[x]!=vertex-1) printf("%d-->",result[x++]); printf("%d\n",result[x]); } else printf("no way!\n"); system("pause"); }
void PluginTreeBuilder::Calculate () { Graph_.clear (); Object2Vertex_.clear (); Result_.clear (); CreateGraph (); QMap<Edge_t, QPair<Vertex_t, Vertex_t> > edge2vert = MakeEdges (); QMap<Vertex_t, QList<Vertex_t> > reachable; QPair<Vertex_t, Vertex_t> pair; Q_FOREACH (pair, edge2vert) reachable [pair.first] << pair.second; QList<Edge_t> backEdges; CycleDetector<Edge_t> cd (backEdges); boost::depth_first_search (Graph_, boost::visitor (cd)); QList<Vertex_t> backVertices; Q_FOREACH (const Edge_t& backEdge, backEdges) backVertices << edge2vert [backEdge].first; FulfillableChecker<Graph_t, Vertex_t> checker (Graph_, backVertices, reachable); boost::depth_first_search (Graph_, boost::visitor (checker)); typedef boost::filtered_graph<Graph_t, boost::keep_all, VertexPredicate<Graph_t> > fg_t; fg_t fg = fg_t (Graph_, boost::keep_all (), VertexPredicate<Graph_t> (Graph_)); QList<Vertex_t> vertices; boost::topological_sort (fg, std::back_inserter (vertices)); Q_FOREACH (const Vertex_t& vertex, vertices) Result_ << fg [vertex].Object_; }
int main(){ int n; printf("\nEnter the number of nodes in graph : "); scanf("%d",&n); GNode* graph=CreateGraph(n); int i,source,dest,weight; int E; printf("\nenter the num of edges : "); scanf("%d",&E); for(i=0;i<E;i++){ printf("\nEnter source destionation and weight..."); scanf("%d %d %d",&source,&dest,&weight); AddVertex(graph,source,dest,weight); } printf("\nPress enter to traverse adjacency List\n"); getch(); TraverseAdjList(graph); getch(); return 0; }
int main(){ /* int a,b,c,d,e,f,g,h; scanf("%d,%d,%d,%d",&a,&b,&c,&d); getchar(); Queue Q = CreateQueue(); Enqueue(Q,a); Enqueue(Q,b); Enqueue(Q,c); Enqueue(Q,d); e = Dequeue(Q); printf("%d\n",e); f = Dequeue(Q); printf("%d\n",f); g = Dequeue(Q); printf("%d\n",g); h = Dequeue(Q); printf("%d\n",h); printf("%d,%d,%d,%d\n",e,f,g,h); getchar(); */ int vertexNumber = 0; int vertex; int weights; int i; int f; Table table; printf("Create graph:\n"); printf("Input vertex number:"); scanf("%d",&vertexNumber); getchar(); printf("Graph initing...\n"); Graph graph = CreateGraph(vertexNumber); if(graph == NULL){ printf("Graph init failed\n"); return 0; } for(i = 1;i <= vertexNumber;i++){ printf("Vertex:%d\nHas adjavent?[1/0]:",i); scanf("%d",&f); getchar(); while(f){ printf("adjacent:"); scanf("%d",&vertex); getchar(); printf("weights:"); scanf("%d",&weights); getchar(); printf("continue?[1/0]:"); scanf("%d",&f); getchar(); AddEdge(graph,i,vertex,weights); } } ShowGraph(graph,vertexNumber); printf("input source:"); scanf("%d",&i); getchar(); table = Dijkstra(graph,i,vertexNumber); ShowTable(table,vertexNumber); PrintPath(table,i,2); printf("hello linux c\n"); return 0; }
int main() { int i; ALGraph G; //创建图 CreateGraph(&G); //深度优先遍历图 DFSTraverse(G,PrintElem); printf("\n"); //求关节点 FindArticul(G); printf("i G.vertices[i].data visited[i] low[i] Order_Low\n"); for(i = 0; i < G.vexnum ; i++) printf("%d %d %d %d %d\n",i,G.vertices[i].data,visited[i],low[i],Order_Low[i]); return 0; /* please enter the kind of graph(DG:0,DN:1,UDG:2,UDN:3):2 please the vexnum and arcnum:13,17 please enter the value of each vertex:1,2,3,4,5,6,7,8,9,10,11,12,13 please enter the heads and tails: 1,2 1,3 1,6 1,12 2,3 2,4 2,7 2,8 2,13 4,5 7,8 7,9 7,11 8,11 10,12 10,13 12,13 >>(可以看到2输出了两次,这是因为删除2会将图分割成三颗树) 1 2 3 4 5 7 8 11 9 13 10 12 6 6,7 1,2 3,4 1,2 0,1 i G.vertices[i].data visited[i] low[i] Order_Low 0 1 1 1 0 1 2 5 1 9 2 3 12 1 8 3 4 10 5 7 4 5 11 10 6 5 6 13 1 12 6 7 8 5 3 7 8 6 5 5 8 9 9 8 2 9 10 4 2 1 10 11 7 5 4 11 12 2 1 11 12 13 3 1 10 */ }
int main() { printf("Welcome to Supply route problem..\n"); int testcase; int T; scanf("%d", &T); for(testcase=1; testcase <=T; testcase++) { int num; int r; int c; int ans; char ch; int k; /* time_t start, stop; clock_t ticks; long count; time(&start);*/ clock_t start, stop; start = clock(); scanf("%d", &num); /* Initialize Adjacency List */ for(r=0; r< num*num; r++) { for(c=0; c<4; c++) { adjlist[r][c] = -1; } } for(r=0; r< num; r++) { for(c=0; c< num; c++) { scanf(" %c", &ch); inputmat[r][c] = ch - '0'; } } #if 0 for(r=0; r< num; r++) { for(c=0; c< num; c++) { printf("[%d]", inputmat[r][c]); } printf("\n"); } #endif CreateGraph(num); /* Diktra preparation */ for(k=0; k < num*num; k++) { dist[k] = INF; visited[k] = NO; } dist[0] = 0; ShortestPath(num); ans = dist[num*num -1]; printf("#%d %d\n", testcase, ans); stop = clock(); //time(&stop); printf("testcase [%d] started %6.3f seconds Finished %6.3f \n", testcase, start, stop /*difftime(stop, start)*/); } }
void main() { int i,j,k,n; ALGraph g; VertexType v1,v2; printf("请选择有向图\n"); CreateGraph(&g); Display(g); printf("删除一条边或弧,请输入待删除边或弧的弧尾 弧头:"); scanf("%s%s",v1,v2); DeleteArc(&g,v1,v2); printf("修改顶点的值,请输入原值 新值: "); scanf("%s%s",v1,v2); PutVex(&g,v1,v2); printf("插入新顶点,请输入顶点的值: "); scanf("%s",v1); InsertVex(&g,v1); printf("插入与新顶点有关的弧或边,请输入弧或边数: "); scanf("%d",&n); for(k=0;k<n;k++) { printf("请输入另一顶点的值: "); scanf("%s",v2); printf("对于有向图,请输入另一顶点的方向(0:弧头 1:弧尾): "); scanf("%d",&j); if(j) InsertArc(&g,v2,v1); else InsertArc(&g,v1,v2); } Display(g); printf("删除顶点及相关的弧或边,请输入顶点的值: "); scanf("%s",v1); DeleteVex(&g,v1); Display(g); printf("深度优先搜索的结果:\n"); DFSTraverse(g,print); printf("广度优先搜索的结果:\n"); BFSTraverse(g,print); DestroyGraph(&g); printf("请顺序选择有向网,无向图,无向网\n"); for(i=0;i<3;i++) /* 验证另外3种情况 */ { CreateGraph(&g); Display(g); printf("插入新顶点,请输入顶点的值: "); scanf("%s",v1); InsertVex(&g,v1); printf("插入与新顶点有关的弧或边,请输入弧或边数: "); scanf("%d",&n); for(k=0;k<n;k++) { printf("请输入另一顶点的值: "); scanf("%s",v2); if(g.kind<=1) /* 有向 */ { printf("对于有向图或网,请输入另一顶点的方向(0:弧头 1:弧尾): "); scanf("%d",&j); if(j) InsertArc(&g,v2,v1); else InsertArc(&g,v1,v2); } else /* 无向 */ InsertArc(&g,v1,v2); } Display(g); printf("删除顶点及相关的弧或边,请输入顶点的值: "); scanf("%s",v1); DeleteVex(&g,v1); Display(g); DestroyGraph(&g); } }
void CreateCoarseGraph_Global(ctrl_t *ctrl, graph_t *graph, idx_t cnvtxs) { idx_t h, i, j, k, l, ii, jj, ll, nnbrs, nvtxs, nedges, ncon; idx_t firstvtx, lastvtx, cfirstvtx, clastvtx, otherlastvtx; idx_t npes=ctrl->npes, mype=ctrl->mype; idx_t cnedges, nsend, nrecv, nkeepsize, nrecvsize, nsendsize, v, u; idx_t *xadj, *adjncy, *adjwgt, *vwgt, *vsize, *vtxdist, *home, *where; idx_t *match, *cmap; idx_t *cxadj, *cadjncy, *cadjwgt, *cvwgt, *cvsize = NULL, *chome = NULL, *cwhere = NULL, *cvtxdist; idx_t *rsizes, *ssizes, *rlens, *slens, *rgraph, *sgraph, *perm; idx_t *peind, *recvptr, *recvind; real_t *nvwgt, *cnvwgt; graph_t *cgraph; ikv_t *scand, *rcand; idx_t htable[LHTSIZE], htableidx[LHTSIZE]; WCOREPUSH; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; vwgt = graph->vwgt; vsize = graph->vsize; nvwgt = graph->nvwgt; home = graph->home; where = graph->where; adjncy = graph->adjncy; adjwgt = graph->adjwgt; match = graph->match; vtxdist = graph->vtxdist; firstvtx = vtxdist[mype]; lastvtx = vtxdist[mype+1]; cmap = graph->cmap = ismalloc(nvtxs+graph->nrecv, -1, "Global_CreateCoarseGraph: cmap"); nnbrs = graph->nnbrs; peind = graph->peind; recvind = graph->recvind; recvptr = graph->recvptr; /* Initialize the coarser graph */ cgraph = CreateGraph(); cgraph->nvtxs = cnvtxs; cgraph->ncon = ncon; cgraph->level = graph->level+1; cgraph->finer = graph; graph->coarser = cgraph; /************************************************************* * Obtain the vtxdist of the coarser graph **************************************************************/ cvtxdist = cgraph->vtxdist = imalloc(npes+1, "Global_CreateCoarseGraph: cvtxdist"); cvtxdist[npes] = cnvtxs; /* Use last position in the cvtxdist as a temp buffer */ gkMPI_Allgather((void *)(cvtxdist+npes), 1, IDX_T, (void *)cvtxdist, 1, IDX_T, ctrl->comm); MAKECSR(i, npes, cvtxdist); cgraph->gnvtxs = cvtxdist[npes]; #ifdef DEBUG_CONTRACT PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); #endif /************************************************************* * Construct the cmap vector **************************************************************/ cfirstvtx = cvtxdist[mype]; clastvtx = cvtxdist[mype+1]; /* Create the cmap of what you know so far locally. */ for (cnvtxs=0, i=0; i<nvtxs; i++) { if (match[i] >= KEEP_BIT) { k = match[i] - KEEP_BIT; if (k>=firstvtx && k<firstvtx+i) continue; /* Both (i,k) are local and i has been matched via the (k,i) side */ cmap[i] = cfirstvtx + cnvtxs++; if (k != firstvtx+i && (k>=firstvtx && k<lastvtx)) { /* I'm matched locally */ cmap[k-firstvtx] = cmap[i]; match[k-firstvtx] += KEEP_BIT; /* Add the KEEP_BIT to simplify coding */ } } } PASSERT(ctrl, cnvtxs == clastvtx-cfirstvtx); CommInterfaceData(ctrl, graph, cmap, cmap+nvtxs); /* Update the cmap of the locally stored vertices that will go away. * The remote processor assigned cmap for them */ for (i=0; i<nvtxs; i++) { if (match[i] < KEEP_BIT) { /* Only vertices that go away satisfy this*/ cmap[i] = cmap[nvtxs+BSearch(graph->nrecv, recvind, match[i])]; } } CommInterfaceData(ctrl, graph, cmap, cmap+nvtxs); #ifndef NDEBUG for (i=0; i<nvtxs+graph->nrecv; i++) { if (cmap[i] == -1) errexit("cmap[%"PRIDX"] == -1\n", i); } #endif #ifdef DEBUG_CONTRACT PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); #endif /************************************************************* * Determine how many adjcency lists you need to send/receive. **************************************************************/ /* first pass: determine sizes */ for (nsend=0, nrecv=0, i=0; i<nvtxs; i++) { if (match[i] < KEEP_BIT) /* This is going away */ nsend++; else { k = match[i]-KEEP_BIT; if (k<firstvtx || k>=lastvtx) /* This is comming from afar */ nrecv++; } } scand = ikvwspacemalloc(ctrl, nsend); rcand = graph->rcand = ikvmalloc(nrecv, "CreateCoarseGraph: rcand"); /* second pass: place them in the appropriate arrays */ nkeepsize = nsend = nrecv = 0; for (i=0; i<nvtxs; i++) { if (match[i] < KEEP_BIT) { /* This is going away */ scand[nsend].key = match[i]; scand[nsend].val = i; nsend++; } else { nkeepsize += (xadj[i+1]-xadj[i]); k = match[i]-KEEP_BIT; if (k<firstvtx || k>=lastvtx) { /* This is comming from afar */ rcand[nrecv].key = k; rcand[nrecv].val = cmap[i] - cfirstvtx; /* Set it for use during the partition projection */ PASSERT(ctrl, rcand[nrecv].val>=0 && rcand[nrecv].val<cnvtxs); nrecv++; } } } #ifdef DEBUG_CONTRACT PrintPairs(ctrl, nsend, scand, "scand"); PrintPairs(ctrl, nrecv, rcand, "rcand"); #endif /*************************************************************** * Determine how many lists and their sizes you will send and * received for each of the neighboring PEs ****************************************************************/ rlens = graph->rlens = imalloc(nnbrs+1, "CreateCoarseGraph: graph->rlens"); slens = graph->slens = imalloc(nnbrs+1, "CreateCoarseGraph: graph->slens"); rsizes = iset(nnbrs, 0, iwspacemalloc(ctrl, nnbrs)); ssizes = iset(nnbrs, 0, iwspacemalloc(ctrl, nnbrs)); /* Take care the sending data first */ ikvsortii(nsend, scand); slens[0] = 0; for (k=i=0; i<nnbrs; i++) { otherlastvtx = vtxdist[peind[i]+1]; for (; k<nsend && scand[k].key < otherlastvtx; k++) ssizes[i] += (xadj[scand[k].val+1]-xadj[scand[k].val]); slens[i+1] = k; } /* Take care the receiving data next. You cannot yet determine the rsizes[] */ ikvsortii(nrecv, rcand); rlens[0] = 0; for (k=i=0; i<nnbrs; i++) { otherlastvtx = vtxdist[peind[i]+1]; for (; k<nrecv && rcand[k].key < otherlastvtx; k++); rlens[i+1] = k; } #ifdef DEBUG_CONTRACT PrintVector(ctrl, nnbrs+1, 0, slens, "slens"); PrintVector(ctrl, nnbrs+1, 0, rlens, "rlens"); #endif /*************************************************************** * Exchange size information ****************************************************************/ /* Issue the receives first. */ for (i=0; i<nnbrs; i++) { if (rlens[i+1]-rlens[i] > 0) /* Issue a receive only if you are getting something */ gkMPI_Irecv((void *)(rsizes+i), 1, IDX_T, peind[i], 1, ctrl->comm, ctrl->rreq+i); } /* Take care the sending data next */ for (i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) /* Issue a send only if you are sending something */ gkMPI_Isend((void *)(ssizes+i), 1, IDX_T, peind[i], 1, ctrl->comm, ctrl->sreq+i); } /* OK, now get into the loop waiting for the operations to finish */ for (i=0; i<nnbrs; i++) { if (rlens[i+1]-rlens[i] > 0) gkMPI_Wait(ctrl->rreq+i, &ctrl->status); } for (i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) gkMPI_Wait(ctrl->sreq+i, &ctrl->status); } #ifdef DEBUG_CONTRACT PrintVector(ctrl, nnbrs, 0, rsizes, "rsizes"); PrintVector(ctrl, nnbrs, 0, ssizes, "ssizes"); #endif /************************************************************* * Allocate memory for received/sent graphs and start sending * and receiving data. * rgraph and sgraph is a different data structure than CSR * to facilitate single message exchange. **************************************************************/ nrecvsize = isum(nnbrs, rsizes, 1); nsendsize = isum(nnbrs, ssizes, 1); rgraph = iwspacemalloc(ctrl, (4+ncon)*nrecv+2*nrecvsize); WCOREPUSH; /* for freeing sgraph right away */ sgraph = iwspacemalloc(ctrl, (4+ncon)*nsend+2*nsendsize); /* Deal with the received portion first */ for (l=i=0; i<nnbrs; i++) { /* Issue a receive only if you are getting something */ if (rlens[i+1]-rlens[i] > 0) { gkMPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_T, peind[i], 1, ctrl->comm, ctrl->rreq+i); l += (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i]; } } /* Deal with the sent portion now */ for (ll=l=i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) { /* Issue a send only if you are sending something */ for (k=slens[i]; k<slens[i+1]; k++) { ii = scand[k].val; sgraph[ll++] = firstvtx+ii; sgraph[ll++] = xadj[ii+1]-xadj[ii]; for (h=0; h<ncon; h++) sgraph[ll++] = vwgt[ii*ncon+h]; sgraph[ll++] = (ctrl->partType == STATIC_PARTITION || ctrl->partType == ORDER_PARTITION ? -1 : vsize[ii]); sgraph[ll++] = (ctrl->partType == STATIC_PARTITION || ctrl->partType == ORDER_PARTITION ? -1 : home[ii]); for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { sgraph[ll++] = cmap[adjncy[jj]]; sgraph[ll++] = adjwgt[jj]; } } PASSERT(ctrl, ll-l == (4+ncon)*(slens[i+1]-slens[i])+2*ssizes[i]); /*myprintf(ctrl, "Sending to pe:%"PRIDX", %"PRIDX" lists of size %"PRIDX"\n", peind[i], slens[i+1]-slens[i], ssizes[i]); */ gkMPI_Isend((void *)(sgraph+l), ll-l, IDX_T, peind[i], 1, ctrl->comm, ctrl->sreq+i); l = ll; } } /* OK, now get into the loop waiting for the operations to finish */ for (i=0; i<nnbrs; i++) { if (rlens[i+1]-rlens[i] > 0) gkMPI_Wait(ctrl->rreq+i, &ctrl->status); } for (i=0; i<nnbrs; i++) { if (slens[i+1]-slens[i] > 0) gkMPI_Wait(ctrl->sreq+i, &ctrl->status); } #ifdef DEBUG_CONTRACT rprintf(ctrl, "Graphs were sent!\n"); PrintTransferedGraphs(ctrl, nnbrs, peind, slens, rlens, sgraph, rgraph); #endif WCOREPOP; /* free sgraph */ /************************************************************* * Setup the mapping from indices returned by BSearch to * those that are actually stored **************************************************************/ perm = iset(graph->nrecv, -1, iwspacemalloc(ctrl, graph->nrecv)); for (j=i=0; i<nrecv; i++) { perm[BSearch(graph->nrecv, recvind, rgraph[j])] = j+1; j += (4+ncon)+2*rgraph[j+1]; } /************************************************************* * Finally, create the coarser graph **************************************************************/ /* Allocate memory for the coarser graph, and fire up coarsening */ cxadj = cgraph->xadj = imalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); cvwgt = cgraph->vwgt = imalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); cnvwgt = cgraph->nvwgt = rmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize = cgraph->vsize = imalloc(cnvtxs, "CreateCoarserGraph: cvsize"); chome = cgraph->home = imalloc(cnvtxs, "CreateCoarserGraph: chome"); } if (where != NULL) cwhere = cgraph->where = imalloc(cnvtxs, "CreateCoarserGraph: cwhere"); /* these are just upper bound estimates for now */ cadjncy = iwspacemalloc(ctrl, nkeepsize+nrecvsize); cadjwgt = iwspacemalloc(ctrl, nkeepsize+nrecvsize); iset(LHTSIZE, -1, htable); cxadj[0] = cnvtxs = cnedges = 0; for (i=0; i<nvtxs; i++) { if (match[i] >= KEEP_BIT) { v = firstvtx+i; u = match[i]-KEEP_BIT; if (u>=firstvtx && u<lastvtx && v > u) continue; /* I have already collapsed it as (u,v) */ /* Collapse the v vertex first, which you know is local */ for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] = vwgt[i*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize[cnvtxs] = vsize[i]; chome[cnvtxs] = home[i]; } if (where != NULL) cwhere[cnvtxs] = where[i]; nedges = 0; /* Collapse the v (i) vertex first */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = cmap[adjncy[j]]; if (k < 0) printf("k=%d\n", (int)k); if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&MASK; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } } } } /* Collapse the u vertex next */ if (v != u) { if (u>=firstvtx && u<lastvtx) { /* Local vertex */ u -= firstvtx; for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] += vwgt[u*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) cvsize[cnvtxs] += vsize[u]; for (j=xadj[u]; j<xadj[u+1]; j++) { k = cmap[adjncy[j]]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&MASK; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges] = adjwgt[j]; nedges++; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges] = adjwgt[j]; nedges++; } } } } } else { /* Remote vertex */ u = perm[BSearch(graph->nrecv, recvind, u)]; for (h=0; h<ncon; h++) /* Remember that the +1 stores the vertex weight */ cvwgt[cnvtxs*ncon+h] += rgraph[(u+1)+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { cvsize[cnvtxs] += rgraph[u+1+ncon]; chome[cnvtxs] = rgraph[u+2+ncon]; } for (j=0; j<rgraph[u]; j++) { k = rgraph[u+3+ncon+2*j]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&MASK; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges] = rgraph[u+3+ncon+2*j+1]; nedges++; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += rgraph[u+3+ncon+2*j+1]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += rgraph[u+3+ncon+2*j+1]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges] = rgraph[u+3+ncon+2*j+1]; nedges++; } } } } } } cnedges += nedges; for (j=cxadj[cnvtxs]; j<cnedges; j++) htable[cadjncy[j]&MASK] = -1; /* reset the htable */ cxadj[++cnvtxs] = cnedges; } } cgraph->nedges = cnedges; /* ADD: In order to keep from having to change this too much */ /* ADD: I kept vwgt array and recomputed nvwgt for each coarser graph */ for (j=0; j<cnvtxs; j++) { for (h=0; h<ncon; h++) cgraph->nvwgt[j*ncon+h] = ctrl->invtvwgts[h]*cvwgt[j*ncon+h]; } cgraph->adjncy = imalloc(cnedges, "CreateCoarserGraph: cadjncy"); cgraph->adjwgt = imalloc(cnedges, "CreateCoarserGraph: cadjwgt"); icopy(cnedges, cadjncy, cgraph->adjncy); icopy(cnedges, cadjwgt, cgraph->adjwgt); WCOREPOP; /* Note that graph->where works fine even if it is NULL */ gk_free((void **)&graph->where, LTERM); }
/************************************************************************* * This function assembles the graph into a single processor **************************************************************************/ GraphType *Mc_AssembleAdaptiveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) { int i, j, k, l, gnvtxs, nvtxs, ncon, gnedges, nedges, gsize; idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *vtxdist, *imap; idxtype *axadj, *aadjncy, *aadjwgt, *avwgt, *avsize = NULL, *alabel; idxtype *mygraph, *ggraph; int *rcounts, *rdispls, mysize; float *anvwgt; GraphType *agraph; gnvtxs = graph->gnvtxs; nvtxs = graph->nvtxs; ncon = graph->ncon; nedges = graph->xadj[nvtxs]; xadj = graph->xadj; vwgt = graph->vwgt; vsize = graph->vsize; adjncy = graph->adjncy; adjwgt = graph->adjwgt; vtxdist = graph->vtxdist; imap = graph->imap; /*************************************************************/ /* Determine the # of idxtype to receive from each processor */ /*************************************************************/ rcounts = imalloc(ctrl->npes, "AssembleGraph: rcounts"); switch (ctrl->partType) { case STATIC_PARTITION: mysize = (1+ncon)*nvtxs + 2*nedges; break; case ADAPTIVE_PARTITION: case REFINE_PARTITION: mysize = (2+ncon)*nvtxs + 2*nedges; break; default: printf("WARNING: bad value for ctrl->partType %d\n", ctrl->partType); break; } MPI_Allgather((void *)(&mysize), 1, MPI_INT, (void *)rcounts, 1, MPI_INT, ctrl->comm); rdispls = imalloc(ctrl->npes+1, "AssembleGraph: rdispls"); rdispls[0] = 0; for (i=1; i<ctrl->npes+1; i++) rdispls[i] = rdispls[i-1] + rcounts[i-1]; /* Construct the one-array storage format of the assembled graph */ mygraph = (mysize <= wspace->maxcore ? wspace->core : idxmalloc(mysize, "AssembleGraph: mygraph")); for (k=i=0; i<nvtxs; i++) { mygraph[k++] = xadj[i+1]-xadj[i]; for (j=0; j<ncon; j++) mygraph[k++] = vwgt[i*ncon+j]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) mygraph[k++] = vsize[i]; for (j=xadj[i]; j<xadj[i+1]; j++) { mygraph[k++] = imap[adjncy[j]]; mygraph[k++] = adjwgt[j]; } } ASSERT(ctrl, mysize == k); /**************************************/ /* Assemble and send the entire graph */ /**************************************/ gsize = rdispls[ctrl->npes]; ggraph = (gsize <= wspace->maxcore-mysize ? wspace->core+mysize : idxmalloc(gsize, "AssembleGraph: ggraph")); MPI_Allgatherv((void *)mygraph, mysize, IDX_DATATYPE, (void *)ggraph, rcounts, rdispls, IDX_DATATYPE, ctrl->comm); GKfree((void **)&rcounts, (void **)&rdispls, LTERM); if (mysize > wspace->maxcore) free(mygraph); agraph = CreateGraph(); agraph->nvtxs = gnvtxs; switch (ctrl->partType) { case STATIC_PARTITION: agraph->nedges = gnedges = (gsize-(1+ncon)*gnvtxs)/2; break; case ADAPTIVE_PARTITION: case REFINE_PARTITION: agraph->nedges = gnedges = (gsize-(2+ncon)*gnvtxs)/2; break; default: printf("WARNING: bad value for ctrl->partType %d\n", ctrl->partType); agraph->nedges = gnedges = -1; break; } agraph->ncon = ncon; /*******************************************/ /* Allocate memory for the assembled graph */ /*******************************************/ axadj = agraph->xadj = idxmalloc(gnvtxs+1, "AssembleGraph: axadj"); avwgt = agraph->vwgt = idxmalloc(gnvtxs*ncon, "AssembleGraph: avwgt"); anvwgt = agraph->nvwgt = fmalloc(gnvtxs*ncon, "AssembleGraph: anvwgt"); aadjncy = agraph->adjncy = idxmalloc(gnedges, "AssembleGraph: adjncy"); aadjwgt = agraph->adjwgt = idxmalloc(gnedges, "AssembleGraph: adjwgt"); alabel = agraph->label = idxmalloc(gnvtxs, "AssembleGraph: alabel"); if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) avsize = agraph->vsize = idxmalloc(gnvtxs, "AssembleGraph: avsize"); for (k=j=i=0; i<gnvtxs; i++) { axadj[i] = ggraph[k++]; for (l=0; l<ncon; l++) avwgt[i*ncon+l] = ggraph[k++]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) avsize[i] = ggraph[k++]; for (l=0; l<axadj[i]; l++) { aadjncy[j] = ggraph[k++]; aadjwgt[j] = ggraph[k++]; j++; } } /*********************************/ /* Now fix up the received graph */ /*********************************/ MAKECSR(i, gnvtxs, axadj); for (i=0; i<gnvtxs; i++) for (j=0; j<ncon; j++) anvwgt[i*ncon+j] = (float)(agraph->vwgt[i*ncon+j]) / (float)(ctrl->tvwgts[j]); for (i=0; i<gnvtxs; i++) alabel[i] = i; if (gsize > wspace->maxcore-mysize) free(ggraph); return agraph; }
/****************************************************************************** * This function creates a coarse graph corresponding to the partitioning vector *******************************************************************************/ GraphType *CreatePartitionGraphForContact(idxtype nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, idxtype cnvtxs, idxtype *part) { idxtype i, ii, j, jj, k, cnedges; idxtype *cxadj, *cadjncy, *cvwgt, *cadjwgt; idxtype *ptr, *ind, *marker; GraphType *cgraph; ptr = idxsmalloc(cnvtxs+1, 0, "CreatePartitionGraph: ptr"); ind = idxmalloc(nvtxs, "CreatePartitionGraph: ind"); marker = idxsmalloc(cnvtxs, -1, "CreatePartitionGraph: marker"); cgraph = CreateGraph(); cgraph->ncon = 2; cgraph->nvtxs = cnvtxs; cxadj = cgraph->xadj = idxsmalloc(cnvtxs+1, 0, "CreatePartitionGraph: cxadj"); cadjncy = cgraph->adjncy = idxmalloc(xadj[nvtxs], "CreatePartitionGraph: cadjncy"); cvwgt = cgraph->vwgt = idxmalloc(2*cnvtxs, "CreatePartitionGraph: cvwgt"); cadjwgt = cgraph->adjwgt = idxmalloc(xadj[nvtxs], "CreatePartitionGraph: cadjwgt"); for (i=0; i<nvtxs; i++) ptr[part[i]]++; MAKECSR(i, cnvtxs, ptr); for (i=0; i<nvtxs; i++) ind[ptr[part[i]]++] = i; SHIFTCSR(i, cnvtxs, ptr); /* Create the adjacency list of the coarse/partition graph */ for (cxadj[0]=cnedges=0, i=0; i<cnvtxs; i++) { cvwgt[2*i+0] = cvwgt[2*i+1] = 0; for (j=ptr[i]; j<ptr[i+1]; j++) { ii = ind[j]; cvwgt[2*i+0] += vwgt[2*ii+0]; cvwgt[2*i+1] += vwgt[2*ii+1]; for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { if ((k = part[adjncy[jj]]) == i) continue; if (marker[k] == -1) { cadjncy[cnedges] = k; cadjwgt[cnedges] = adjwgt[jj]; marker[k] = cnedges++; } else cadjwgt[marker[k]] += adjwgt[jj]; } } cxadj[i+1] = cnedges; /* reset the marker array */ for (j=cxadj[i]; j<cnedges; j++) marker[cadjncy[j]] = -1; } gk_free((void **)&ptr, &ind, &marker, LTERM); return cgraph; }
graph_t *CompressGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt, idx_t *cptr, idx_t *cind) { idx_t i, ii, iii, j, jj, k, l, cnvtxs, cnedges; idx_t *cxadj, *cadjncy, *cvwgt, *mark, *map; ikv_t *keys; graph_t *graph=NULL; mark = ismalloc(nvtxs, -1, "CompressGraph: mark"); map = ismalloc(nvtxs, -1, "CompressGraph: map"); keys = ikvmalloc(nvtxs, "CompressGraph: keys"); /* Compute a key for each adjacency list */ for (i=0; i<nvtxs; i++) { k = 0; for (j=xadj[i]; j<xadj[i+1]; j++) k += adjncy[j]; keys[i].key = k+i; /* Add the diagonal entry as well */ keys[i].val = i; } ikvsorti(nvtxs, keys); l = cptr[0] = 0; for (cnvtxs=i=0; i<nvtxs; i++) { ii = keys[i].val; if (map[ii] == -1) { mark[ii] = i; /* Add the diagonal entry */ for (j=xadj[ii]; j<xadj[ii+1]; j++) mark[adjncy[j]] = i; map[ii] = cnvtxs; cind[l++] = ii; for (j=i+1; j<nvtxs; j++) { iii = keys[j].val; if (keys[i].key != keys[j].key || xadj[ii+1]-xadj[ii] != xadj[iii+1]-xadj[iii]) break; /* Break if keys or degrees are different */ if (map[iii] == -1) { /* Do a comparison if iii has not been mapped */ for (jj=xadj[iii]; jj<xadj[iii+1]; jj++) { if (mark[adjncy[jj]] != i) break; } if (jj == xadj[iii+1]) { /* Identical adjacency structure */ map[iii] = cnvtxs; cind[l++] = iii; } } } cptr[++cnvtxs] = l; } } IFSET(ctrl->dbglvl, METIS_DBG_INFO, printf(" Compression: reduction in # of vertices: %"PRIDX".\n", nvtxs-cnvtxs)); if (cnvtxs < COMPRESSION_FRACTION*nvtxs) { /* Sufficient compression is possible, so go ahead and create the compressed graph */ graph = CreateGraph(); cnedges = 0; for (i=0; i<cnvtxs; i++) { ii = cind[cptr[i]]; cnedges += xadj[ii+1]-xadj[ii]; } /* Allocate memory for the compressed graph */ cxadj = graph->xadj = imalloc(cnvtxs+1, "CompressGraph: xadj"); cvwgt = graph->vwgt = ismalloc(cnvtxs, 0, "CompressGraph: vwgt"); cadjncy = graph->adjncy = imalloc(cnedges, "CompressGraph: adjncy"); graph->adjwgt = ismalloc(cnedges, 1, "CompressGraph: adjwgt"); /* Now go and compress the graph */ iset(nvtxs, -1, mark); l = cxadj[0] = 0; for (i=0; i<cnvtxs; i++) { mark[i] = i; /* Remove any dioganal entries in the compressed graph */ for (j=cptr[i]; j<cptr[i+1]; j++) { ii = cind[j]; /* accumulate the vertex weights of the consistuent vertices */ cvwgt[i] += (vwgt == NULL ? 1 : vwgt[ii]); /* generate the combined adjancency list */ for (jj=xadj[ii]; jj<xadj[ii+1]; jj++) { k = map[adjncy[jj]]; if (mark[k] != i) { mark[k] = i; cadjncy[l++] = k; } } } cxadj[i+1] = l; } graph->nvtxs = cnvtxs; graph->nedges = l; graph->ncon = 1; SetupGraph_tvwgt(graph); SetupGraph_label(graph); } gk_free((void **)&keys, &map, &mark, LTERM); return graph; }
graph_t *PruneGraph(ctrl_t *ctrl, idx_t nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt, idx_t *iperm, real_t factor) { idx_t i, j, k, l, nlarge, pnvtxs, pnedges; idx_t *pxadj, *padjncy, *pvwgt; idx_t *perm; graph_t *graph=NULL; perm = imalloc(nvtxs, "PruneGraph: perm"); factor = factor*xadj[nvtxs]/nvtxs; pnvtxs = pnedges = nlarge = 0; for (i=0; i<nvtxs; i++) { if (xadj[i+1]-xadj[i] < factor) { perm[i] = pnvtxs; iperm[pnvtxs++] = i; pnedges += xadj[i+1]-xadj[i]; } else { perm[i] = nvtxs - ++nlarge; iperm[nvtxs-nlarge] = i; } } IFSET(ctrl->dbglvl, METIS_DBG_INFO, printf(" Pruned %"PRIDX" of %"PRIDX" vertices.\n", nlarge, nvtxs)); if (nlarge > 0 && nlarge < nvtxs) { /* Prunning is possible, so go ahead and create the prunned graph */ graph = CreateGraph(); /* Allocate memory for the prunned graph*/ pxadj = graph->xadj = imalloc(pnvtxs+1, "PruneGraph: xadj"); pvwgt = graph->vwgt = imalloc(pnvtxs, "PruneGraph: vwgt"); padjncy = graph->adjncy = imalloc(pnedges, "PruneGraph: adjncy"); graph->adjwgt = ismalloc(pnedges, 1, "PruneGraph: adjwgt"); pxadj[0] = pnedges = l = 0; for (i=0; i<nvtxs; i++) { if (xadj[i+1]-xadj[i] < factor) { pvwgt[l] = (vwgt == NULL ? 1 : vwgt[i]); for (j=xadj[i]; j<xadj[i+1]; j++) { k = perm[adjncy[j]]; if (k < pnvtxs) padjncy[pnedges++] = k; } pxadj[++l] = pnedges; } } graph->nvtxs = pnvtxs; graph->nedges = pnedges; graph->ncon = 1; SetupGraph_tvwgt(graph); SetupGraph_label(graph); } else if (nlarge > 0 && nlarge == nvtxs) { IFSET(ctrl->dbglvl, METIS_DBG_INFO, printf(" Pruning is ignored as it removes all vertices.\n")); nlarge = 0; } gk_free((void **)&perm, LTERM); return graph; }
/********************************************************************* * * _cbDialog */ static void _cbDialog(WM_MESSAGE * pMsg) { WM_HWIN hItem; int NCode; int Id; // USER START (Optionally insert additional variables) // USER END switch (pMsg->MsgId) { case WM_INIT_DIALOG: { // hItem = WM_GetDialogItem(pMsg->hWin, ID_FRAMEWIN_0); //// FRAMEWIN_SetResizeable(hItem,1); // FRAMEWIN_SetFont(hItem,GUI_FONT_COMIC24B_ASCII); //// FRAMEWIN_SetMoveable(hItem,1); //// GUI_ExecCreatedDialog(hItem); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); BUTTON_SetSkin(hItem,BUTTON_SKIN_FLEX); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1); BUTTON_SetSkin(hItem,BUTTON_SKIN_FLEX); // // Initialization of 'Edit' // hItem = WM_GetDialogItem(pMsg->hWin, ID_EDIT_0); EDIT_SetText(hItem, "blabalbalablablaba"); // // Initialization of 'Listwheel' // hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTWHEEL_0); LISTWHEEL_SetLBorder(hItem,10); LISTWHEEL_SetFont(hItem,GUI_FONT_COMIC24B_ASCII); LISTWHEEL_AddString(hItem, "jeden"); LISTWHEEL_AddString(hItem, "dwa"); LISTWHEEL_AddString(hItem, "trzy"); LISTWHEEL_AddString(hItem, "cztery"); LISTWHEEL_AddString(hItem, "piec"); LISTWHEEL_AddString(hItem, "szesc"); LISTWHEEL_AddString(hItem, "siedem"); // // Initialization of 'Checkbox' // hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_0); CHECKBOX_SetText(hItem, "Check"); // // Initialization of 'Checkbox' // hItem = WM_GetDialogItem(pMsg->hWin, ID_CHECKBOX_1); CHECKBOX_SetText(hItem, "Check"); // USER START (Optionally insert additional code for further widget initialization) // USER END hItem=WM_GetDialogItem(pMsg->hWin,ID_PROGBAR_0); PROGBAR_SetMinMax(hItem,0,15); PROGBAR_SetSkin(hItem,PROGBAR_SKIN_FLEX); break; } case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch(Id) { case ID_EDIT_0: // Notifications sent by 'Edit' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END WM_DeleteWindow(hBox); hBox = MESSAGEBOX_Create("Keyboard not supported yet!","ERROR", GUI_MESSAGEBOX_CF_MOVEABLE); break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_VALUE_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; case ID_BUTTON_0: // Notifications sent by 'Button' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: { CreateMojeokno2(); hItem=WM_GetDialogItem(pMsg->hWin,ID_PROGBAR_0); PROGBAR_SetValue(hItem,il++); break; } } break; case ID_BUTTON_1: // Notifications sent by 'Button' switch(NCode) { case WM_NOTIFICATION_CLICKED: { break; } case WM_NOTIFICATION_RELEASED: { CreateGraph(); // WM_DeleteWindow(hBox); // hBox = MESSAGEBOX_Create("Release the BUTTON !","ERROR", GUI_MESSAGEBOX_CF_MOVEABLE); // WM_DeleteWindow(hBox); break; } } break; case ID_LISTWHEEL_0: // Notifications sent by 'Listwheel' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_SEL_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; case ID_CHECKBOX_0: // Notifications sent by 'Checkbox' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_VALUE_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; case ID_CHECKBOX_1: // Notifications sent by 'Checkbox' switch(NCode) { case WM_NOTIFICATION_CLICKED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_RELEASED: // USER START (Optionally insert code for reacting on notification message) // USER END break; case WM_NOTIFICATION_VALUE_CHANGED: // USER START (Optionally insert code for reacting on notification message) // USER END break; // USER START (Optionally insert additional code for further notification handling) // USER END } break; // USER START (Optionally insert additional code for further Ids) // USER END } break; // USER START (Optionally insert additional message handling) // USER END default: WM_DefaultProc(pMsg); break; } }
/************************************************************************* * This function extracts a subgraph from a graph given an indicator array. **************************************************************************/ graph_t *ExtractGraph(ctrl_t *ctrl, graph_t *graph, idx_t *indicator, idx_t *map, idx_t *rmap) { idx_t h, i, j; idx_t nvtxs, envtxs, enedges, ncon; idx_t vtx, count; idx_t *xadj, *vsize, *adjncy, *adjwgt, *where; idx_t *exadj, *evsize, *eadjncy, *eadjwgt, *ewhere; real_t *nvwgt, *envwgt; graph_t *egraph; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; vsize = graph->vsize; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; count = 0; for (i=0; i<nvtxs; i++) { if (indicator[i] == 1) { map[count] = i; rmap[i] = count; count++; } } if (count == 0) return NULL; /*******************/ /* allocate memory */ /*******************/ egraph = CreateGraph(); envtxs = egraph->nvtxs = count; egraph->ncon = graph->ncon; exadj = egraph->xadj = imalloc(envtxs*3+1, "exadj"); ewhere = egraph->where = exadj + envtxs + 1; evsize = egraph->vsize = exadj + 2*envtxs + 1; envwgt = egraph->nvwgt = rmalloc(envtxs*ncon, "envwgt"); /************************************************/ /* compute xadj, where, nvwgt, and vsize arrays */ /************************************************/ iset(envtxs+1, 0, exadj); for (i=0; i<envtxs; i++) { vtx = map[i]; ewhere[i] = where[vtx]; for (h=0; h<ncon; h++) envwgt[i*ncon+h] = nvwgt[vtx*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) evsize[i] = vsize[vtx]; for (j=xadj[vtx]; j<xadj[vtx+1]; j++) if (indicator[adjncy[j]] == 1) exadj[i]++; } MAKECSR(i, envtxs, exadj); /************************************/ /* compute adjncy and adjwgt arrays */ /************************************/ enedges = egraph->nedges = exadj[envtxs]; eadjncy = egraph->adjncy = imalloc(enedges*2, "eadjncy"); eadjwgt = egraph->adjwgt = eadjncy + enedges; for (i=0; i<envtxs; i++) { vtx = map[i]; for (j=xadj[vtx]; j<xadj[vtx+1]; j++) { if (indicator[adjncy[j]] == 1) { eadjncy[exadj[i]] = rmap[adjncy[j]]; eadjwgt[exadj[i]++] = adjwgt[j]; } } } for (i=envtxs; i>0; i--) exadj[i] = exadj[i-1]; exadj[0] = 0; return egraph; }
void CreateCoarseGraph_Local(ctrl_t *ctrl, graph_t *graph, idx_t cnvtxs) { idx_t h, i, j, k, l; idx_t nvtxs, ncon, nedges, firstvtx, cfirstvtx; idx_t npes=ctrl->npes, mype=ctrl->mype; idx_t cnedges, v, u; idx_t *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *vtxdist, *where, *home; idx_t *match, *cmap; idx_t *cxadj, *cvwgt, *cvsize = NULL, *cadjncy, *cadjwgt, *cvtxdist, *chome = NULL, *cwhere = NULL; real_t *cnvwgt; graph_t *cgraph; idx_t htable[LHTSIZE], htableidx[LHTSIZE]; WCOREPUSH; nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; vwgt = graph->vwgt; home = graph->home; vsize = graph->vsize; adjncy = graph->adjncy; adjwgt = graph->adjwgt; where = graph->where; match = graph->match; vtxdist = graph->vtxdist; firstvtx = vtxdist[mype]; cmap = graph->cmap = ismalloc(nvtxs+graph->nrecv, -1, "CreateCoarseGraph: cmap"); /* Initialize the coarser graph */ cgraph = CreateGraph(); cgraph->nvtxs = cnvtxs; cgraph->level = graph->level+1; cgraph->ncon = ncon; cgraph->finer = graph; graph->coarser = cgraph; /************************************************************* * Obtain the vtxdist of the coarser graph **************************************************************/ cvtxdist = cgraph->vtxdist = imalloc(npes+1, "CreateCoarseGraph: cvtxdist"); cvtxdist[npes] = cnvtxs; /* Use last position in the cvtxdist as a temp buffer */ gkMPI_Allgather((void *)(cvtxdist+npes), 1, IDX_T, (void *)cvtxdist, 1, IDX_T, ctrl->comm); MAKECSR(i, npes, cvtxdist); cgraph->gnvtxs = cvtxdist[npes]; #ifdef DEBUG_CONTRACT PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); #endif /************************************************************* * Construct the cmap vector **************************************************************/ cfirstvtx = cvtxdist[mype]; /* Create the cmap of what you know so far locally */ cnvtxs = 0; for (i=0; i<nvtxs; i++) { if (match[i] >= KEEP_BIT) { k = match[i] - KEEP_BIT; if (k<firstvtx+i) continue; /* i has been matched via the (k,i) side */ cmap[i] = cfirstvtx + cnvtxs++; if (k != firstvtx+i) { cmap[k-firstvtx] = cmap[i]; match[k-firstvtx] += KEEP_BIT; /* Add the KEEP_BIT to simplify coding */ } } } CommInterfaceData(ctrl, graph, cmap, cmap+nvtxs); #ifdef DEBUG_CONTRACT PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); #endif /************************************************************* * Finally, create the coarser graph **************************************************************/ /* Allocate memory for the coarser graph, and fire up coarsening */ cxadj = cgraph->xadj = imalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); cvwgt = cgraph->vwgt = imalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); cnvwgt = cgraph->nvwgt = rmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) chome = cgraph->home = imalloc(cnvtxs, "CreateCoarserGraph: chome"); if (vsize != NULL) cvsize = cgraph->vsize = imalloc(cnvtxs, "CreateCoarserGraph: cvsize"); if (where != NULL) cwhere = cgraph->where = imalloc(cnvtxs, "CreateCoarserGraph: cwhere"); cadjncy = iwspacemalloc(ctrl, graph->nedges); cadjwgt = iwspacemalloc(ctrl, graph->nedges); iset(LHTSIZE, -1, htable); cxadj[0] = cnvtxs = cnedges = 0; for (i=0; i<nvtxs; i++) { v = firstvtx+i; u = match[i]-KEEP_BIT; if (v > u) continue; /* I have already collapsed it as (u,v) */ /* Collapse the v vertex first, which you know that is local */ for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] = vwgt[i*ncon+h]; if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) chome[cnvtxs] = home[i]; if (vsize != NULL) cvsize[cnvtxs] = vsize[i]; if (where != NULL) cwhere[cnvtxs] = where[i]; nedges = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = cmap[adjncy[j]]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&MASK; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } } } } /* Collapse the u vertex next */ if (v != u) { u -= firstvtx; for (h=0; h<ncon; h++) cvwgt[cnvtxs*ncon+h] += vwgt[u*ncon+h]; if (vsize != NULL) cvsize[cnvtxs] += vsize[u]; if (where != NULL && cwhere[cnvtxs] != where[u]) myprintf(ctrl, "Something went wrong with the where local matching! %"PRIDX" %"PRIDX"\n", cwhere[cnvtxs], where[u]); for (j=xadj[u]; j<xadj[u+1]; j++) { k = cmap[adjncy[j]]; if (k != cfirstvtx+cnvtxs) { /* If this is not an internal edge */ l = k&MASK; if (htable[l] == -1) { /* Seeing this for first time */ htable[l] = k; htableidx[l] = cnedges+nedges; cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } else if (htable[l] == k) { cadjwgt[htableidx[l]] += adjwgt[j]; } else { /* Now you have to go and do a search. Expensive case */ for (l=0; l<nedges; l++) { if (cadjncy[cnedges+l] == k) break; } if (l < nedges) { cadjwgt[cnedges+l] += adjwgt[j]; } else { cadjncy[cnedges+nedges] = k; cadjwgt[cnedges+nedges++] = adjwgt[j]; } } } } } cnedges += nedges; for (j=cxadj[cnvtxs]; j<cnedges; j++) htable[cadjncy[j]&MASK] = -1; /* reset the htable */ cxadj[++cnvtxs] = cnedges; } cgraph->nedges = cnedges; for (j=0; j<cnvtxs; j++) { for (h=0; h<ncon; h++) cgraph->nvwgt[j*ncon+h] = ctrl->invtvwgts[h]*cvwgt[j*ncon+h]; } cgraph->adjncy = imalloc(cnedges, "CreateCoarserGraph: cadjncy"); cgraph->adjwgt = imalloc(cnedges, "CreateCoarserGraph: cadjwgt"); icopy(cnedges, cadjncy, cgraph->adjncy); icopy(cnedges, cadjwgt, cgraph->adjwgt); WCOREPOP; /* Note that graph->where works fine even if it is NULL */ gk_free((void **)&graph->where, LTERM); }