/// Generates a small-world graph using the Watts-Strogatz model. /// We assume a circle where each node creates links to NodeOutDeg other nodes. /// This way at the end each node is connected to 2*NodeOutDeg other nodes. /// See: Collective dynamics of 'small-world' networks. Watts and Strogatz. /// URL: http://research.yahoo.com/files/w_s_NATURE_0.pdf PUNGraph GenSmallWorld(const int& Nodes, const int& NodeOutDeg, const double& RewireProb, TRnd& Rnd) { THashSet<TIntPr> EdgeSet(Nodes*NodeOutDeg); IAssertR(Nodes > NodeOutDeg, TStr::Fmt("Insufficient nodes for out degree, %d!", NodeOutDeg)); for (int node = 0; node < Nodes; node++) { const int src = node; for (int edge = 1; edge <= NodeOutDeg; edge++) { int dst = (node+edge) % Nodes; // edge to next neighbor if (Rnd.GetUniDev() < RewireProb) { // random edge dst = Rnd.GetUniDevInt(Nodes); while (dst == src || EdgeSet.IsKey(TIntPr(src, dst))) { dst = Rnd.GetUniDevInt(Nodes); } } EdgeSet.AddKey(TIntPr(src, dst)); } } PUNGraph GraphPt = TUNGraph::New(); TUNGraph& Graph = *GraphPt; Graph.Reserve(Nodes, EdgeSet.Len()); int node; for (node = 0; node < Nodes; node++) { IAssert(Graph.AddNode(node) == node); } for (int edge = 0; edge < EdgeSet.Len(); edge++) { Graph.AddEdge(EdgeSet[edge].Val1, EdgeSet[edge].Val2); } Graph.Defrag(); return GraphPt; }
// 1次元配列を受け取って2次元配列的に分解する // データをCreateObjectに渡してオブジェクトを生成する void StageBase::MapSet(int map_array[]) { left = MAP_HEIGHT * 1; right = MAP_HEIGHT * (map_array[1]-1); int* map = new int[map_array[0] * map_array[1]]; for (int i = 0; i < map_array[0] * map_array[1]; i++) { map[i] = map_array[i + 4]; } for (int y = 0; y < map_array[0]; y++) { for (int x = 0; x < map_array[1]; x++) { int index = x + y * map_array[1]; CreateObject(map[index], x, y, map_array[2], map_array[3]); } } EdgeSet((float)(0.f), (float)((map_array[1] - 1) * MAP_WIDTH)); // カメラ初期化 p_camera = PlayCamera(right_edge, left_edge, Vector3(80.f, 50.f)); delete[] map; }
EdgeSet findRetreatingEdges(const IRUnit& unit) { auto v = jit::vector<Edge*>{}; visit_retreating_edges(unit, [&] (Edge* edge) { v.push_back(edge); return true; }); return EdgeSet(begin(v), end(v)); }
/* High Level Interface based on arrays of vertices and colours. */ void GPolygon2(Vec4 *x, int n, Vec4 col) { //draw a 2D polygon with constant colour. int i; int colour = vcolour(col); EAClear(); for (i=0; i < n; i++) { int j= (i+1) % n; EdgeSet((int) x[j][0], (int) x[j][1], (int) x[i][0], (int) x[i][1]); } EdgeScan(colour); }
/// Rewire the network. Keeps node degrees as is but randomly rewires the edges. /// Use this function to generate a random graph with the same degree sequence /// as the OrigGraph. /// See: On the uniform generation of random graphs with prescribed degree /// sequences by R. Milo, N. Kashtan, S. Itzkovitz, M. E. J. Newman, U. Alon /// URL: http://arxiv.org/abs/cond-mat/0312028 PUNGraph GenRewire(const PUNGraph& OrigGraph, const int& NSwitch, TRnd& Rnd) { const int Nodes = OrigGraph->GetNodes(); const int Edges = OrigGraph->GetEdges(); PUNGraph GraphPt = TUNGraph::New(); TUNGraph& Graph = *GraphPt; Graph.Reserve(Nodes, -1); TExeTm ExeTm; // generate a graph that satisfies the constraints printf("Randomizing edges (%d, %d)...\n", Nodes, Edges); TIntPrSet EdgeSet(Edges); for (TUNGraph::TNodeI NI = OrigGraph->BegNI(); NI < OrigGraph->EndNI(); NI++) { const int NId = NI.GetId(); for (int e = 0; e < NI.GetOutDeg(); e++) { if (NId <= NI.GetOutNId(e)) { continue; } EdgeSet.AddKey(TIntPr(NId, NI.GetOutNId(e))); } Graph.AddNode(NI.GetId()); } // edge switching uint skip=0; for (uint swps = 0; swps < 2*uint(Edges)*uint(NSwitch); swps++) { const int keyId1 = EdgeSet.GetRndKeyId(Rnd); const int keyId2 = EdgeSet.GetRndKeyId(Rnd); if (keyId1 == keyId2) { skip++; continue; } const TIntPr& E1 = EdgeSet[keyId1]; const TIntPr& E2 = EdgeSet[keyId2]; TIntPr NewE1(E1.Val1, E2.Val1), NewE2(E1.Val2, E2.Val2); if (NewE1.Val1 > NewE1.Val2) { Swap(NewE1.Val1, NewE1.Val2); } if (NewE2.Val1 > NewE2.Val2) { Swap(NewE2.Val1, NewE2.Val2); } if (NewE1!=NewE2 && NewE1.Val1!=NewE1.Val2 && NewE2.Val1!=NewE2.Val2 && ! EdgeSet.IsKey(NewE1) && ! EdgeSet.IsKey(NewE2)) { EdgeSet.DelKeyId(keyId1); EdgeSet.DelKeyId(keyId2); EdgeSet.AddKey(TIntPr(NewE1)); EdgeSet.AddKey(TIntPr(NewE2)); } else { skip++; } if (swps % Edges == 0) { printf("\r %uk/%uk: %uk skip [%s]", swps/1000u, 2*uint(Edges)*uint(NSwitch)/1000u, skip/1000u, ExeTm.GetStr()); if (ExeTm.GetSecs() > 2*3600) { printf(" *** Time limit!\n"); break; } // time limit 2 hours } } printf("\r total %uk switchings attempted, %uk skiped [%s]\n", 2*uint(Edges)*uint(NSwitch)/1000u, skip/1000u, ExeTm.GetStr()); for (int e = 0; e < EdgeSet.Len(); e++) { Graph.AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); } return GraphPt; }