From bef36a93ede06a268b0ce5683392ffb23b111224 Mon Sep 17 00:00:00 2001
From: 13518104 Kevin Austin Stefano <13518104@std.stei.itb.ac.id>
Date: Fri, 5 Mar 2021 01:05:58 +0700
Subject: [PATCH] Quick Sort with Kruskal Representation

---
 src/MPI_pointtopoint.c |  27 +++++++++++
 src/MST_OpenMP.c       |  11 +++++
 src/MST_OpenMPI        | Bin 0 -> 13200 bytes
 src/MST_OpenMPI.c      | 108 ++++++++++++++++++++++++++++++++++++++---
 src/MST_Serial.c       |   4 --
 src/a                  | Bin 0 -> 8624 bytes
 6 files changed, 139 insertions(+), 11 deletions(-)
 create mode 100644 src/MPI_pointtopoint.c
 create mode 100755 src/MST_OpenMPI
 create mode 100755 src/a

diff --git a/src/MPI_pointtopoint.c b/src/MPI_pointtopoint.c
new file mode 100644
index 0000000..b3eb1b0
--- /dev/null
+++ b/src/MPI_pointtopoint.c
@@ -0,0 +1,27 @@
+#include <mpi.h>
+#include <stdio.h>
+
+int main()
+{
+    int id, x;
+
+    MPI_Init(NULL, NULL);
+    MPI_Comm_rank(MPI_COMM_WORLD, &id);
+
+    // P0 mengirim pesan x ke P1
+    // P1 menerima pesan dari P0, disimpan ke x
+    if (id == 0) {
+        x = 6;
+        MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
+        MPI_Recv(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, NULL);
+    }
+    if (id == 1)
+        MPI_Recv(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, NULL);
+        x =7;
+        MPI_Send(&x, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+
+    printf("P[%d] x: %d\n", id, x);
+
+    MPI_Finalize();
+    return 0;
+}
\ No newline at end of file
diff --git a/src/MST_OpenMP.c b/src/MST_OpenMP.c
index 757d567..f71ec19 100644
--- a/src/MST_OpenMP.c
+++ b/src/MST_OpenMP.c
@@ -147,15 +147,21 @@ int find(Subset subsets[], int i)
     // find root and make root as parent of i
     // (path compression)
     if (subsets[i].parent != i)
+        #pragma omp single
         subsets[i].parent = find(subsets, subsets[i].parent);
     return subsets[i].parent;
 }
 
 void Union(Subset subsets[], int x, int y)
 {
+    #pragma omp task
     int xroot = find(subsets, x);
+
+    #pragma omp task
     int yroot = find(subsets, y);
 
+    #pragma omp taskwait
+
     // Attach smaller rank tree under root of high
     // rank tree (Union by Rank)
     if (subsets[xroot].rank < subsets[yroot].rank)
@@ -205,11 +211,16 @@ void KruskalMST(Graph *graph, Edge result[], int *e)
         // Pick the smallest edge of the graph
         Edge next_edge = graph->edge[i++];
 
+        #pragma omp task
         int x = find(subsets, next_edge.src);
+        #pragma omp task
         int y = find(subsets, next_edge.dest);
+        #pragma omp taskwait
+
         if (x != y)
         {
             result[(*e)++] = next_edge;
+
             Union(subsets, x, y);
         }
     }
diff --git a/src/MST_OpenMPI b/src/MST_OpenMPI
new file mode 100755
index 0000000000000000000000000000000000000000..556099513aad8e81d4c4db15ab75e054b12b7459
GIT binary patch
literal 13200
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
V7nvLp$*QNykS^LJ{Wn+t{{ZTIWC{QP

literal 0
HcmV?d00001

diff --git a/src/MST_OpenMPI.c b/src/MST_OpenMPI.c
index ed877db..5ac42e2 100644
--- a/src/MST_OpenMPI.c
+++ b/src/MST_OpenMPI.c
@@ -24,6 +24,7 @@ typedef struct
     Edge *edge;
 } Graph;
 
+
 // Create new Graph based on V vertices and E edges
 Graph *CreateGraph(int V, int E)
 {
@@ -33,7 +34,95 @@ Graph *CreateGraph(int V, int E)
     graph->edge = (Edge *)(malloc(E * sizeof(Edge)));
     return graph;
 }
+void PartisiSrc(Edge T[], int i, int j, int *k)
+{
+    Edge pivot = T[i - 1];
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (T[p - 1].src < pivot.src)
+        {
+            p++;
+        }
+        while (T[q - 1].src > pivot.src)
+        {
+            q--;
+        }
+        if (p < q)
+        {
+            Edge temp = T[p - 1];
+            T[p - 1] = T[q - 1];
+            T[q - 1] = Edge;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+
+// Mengurutkan array dengan menggunakan Quick Sort
+void QuickSortSrc(Edge T[], int i, int j)
+{
+    int k;
+    if (i < j)
+    {
+        PartisiSrc(T, i, j, &k);
+        // PrintArray(T, i, k);
+        // PrintArray(T, k + 1, j);
+        QuickSortSrc(T, i, k);
+        QuickSortSrc(T, k + 1, j);
+    }
+}
 
+void PartisiWeight(Edge T[], int i, int j, int *k)
+{
+    Edge pivot = T[i - 1];
+    int p = i;
+    int q = j;
+    while (p <= q)
+    {
+        while (T[p - 1].weight < pivot.weight)
+        {
+            p++;
+        }
+        while (T[q - 1].weight > pivot.weight)
+        {
+            q--;
+        }
+        if (p < q)
+        {
+            Edge temp = T[p - 1];
+            T[p - 1] = T[q - 1];
+            T[q - 1] = temp;
+            p++;
+            q--;
+        }
+        else if (p == q)
+        {
+            p++;
+        }
+    }
+    *k = q;
+}
+
+// Mengurutkan array dengan menggunakan Quick Sort
+void QuickSortWeight(Edge T[], int i, int j)
+{
+    int k;
+    if (i < j)
+    {
+        PartisiWeight(T, i, j, &k);
+        // PrintArray(T, i, k);
+        // PrintArray(T, k + 1, j);
+        QuickSortWeight(T, i, k);
+        QuickSortWeight(T, k + 1, j);
+    }
+}
 // Print all graph component to the CLI
 void PrintGraph(Graph *graph)
 {
@@ -202,7 +291,7 @@ void KruskalMST(Graph *graph, Edge result[], int *e)
     {
         // Pick the smallest edge of the graph
         Edge next_edge = graph->edge[i++];
-
+        MPI_Send(&x, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
         int x = find(subsets, next_edge.src);
         int y = find(subsets, next_edge.dest);
         if (x != y)
@@ -218,8 +307,9 @@ void KruskalMST(Graph *graph, Edge result[], int *e)
 }
 
 void printResult(Edge *result, int e)
-{
-    // printf("%d\n", e);
+{ // Get the number of processes
+   
+
     int minimumCost = 0;
 // #pragma omp parallel for
     for (int i = 0; i < e; i++)
@@ -228,15 +318,19 @@ void printResult(Edge *result, int e)
         minimumCost += result[i].weight;
     }
     printf("%d\n", minimumCost);
-    for (int i = 0; i < e; i++)
+
+    
+    for (int i = start; i < numPartition; i++)
     {
         printf("%d-%d\n", result[i].src, result[i].dest);
     }
 }
 
 // Driver program to test above functions
-int main(int argc, char** argv)
+int main()
 {
+
+    Graph *graph= ReadArguments();
     MPI_Init(NULL, NULL);
     // Get the number of processes
     int world_size;
@@ -247,13 +341,13 @@ int main(int argc, char** argv)
     MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
 
 
-    Graph *graph = ReadArguments();
     Edge result[graph->V];
     int e = 0;
     int t = clock();
     KruskalMST(graph, result, &e);
     t = clock() - t;
-    printResult(result, e);
+    // printResult(result, e);
     printf("Waktu Eksekusi: %f ms \n", ((double)t) / CLOCKS_PER_SEC * 1000);
     MPI_Finalize();
+    return 0;
 }
\ No newline at end of file
diff --git a/src/MST_Serial.c b/src/MST_Serial.c
index 78971dd..6f4a643 100644
--- a/src/MST_Serial.c
+++ b/src/MST_Serial.c
@@ -185,10 +185,6 @@ void KruskalMST(Graph *graph, Edge result[], int *e)
     bubbleSort(graph->edge, graph->E, 1);
     // Step 2: Allocate memory for creating V subsets
     Subset *subsets = CreateSubset(V);
-<<<<<<< HEAD
-
-=======
->>>>>>> fd8239d3b13d39b3a279991ba4a69031b1378216
     while (((*e) < V - 1) && (i < graph->E))
     {
         // Pick the smallest edge of the graph
diff --git a/src/a b/src/a
new file mode 100755
index 0000000000000000000000000000000000000000..80bbe4ed5ce9bfdf04b0344f38f98032aabeaa95
GIT binary patch
literal 8624
zcmds6Yiv{J8U7rT#FXHea0{1?GuCWj9VXn;K+78E#z~h@3W1eTICEl$xHxuZAD4i7
ziI%p)W$ChZKdPydDplI(x=mD?Cg_hg6&<YFen6*gOk+~kwQGWUNmYtySMZ+qJKt*`
zAKUAs?bp7@=l$O2y?poEn}^!FI?7xw!O1PYE{GfPSV*%H3@ud|kY>>&X5)LKSS~8S
z&ytuWZ?*`eR=TQOGgWSd8)C9+Dzo&Qbh!ni1S@e3iIyv@7&%#Gp-hF)BtUjl*WtO6
z1=VDR=~Jp6CvLFhY)3HJ9aVNml^s)|?3i-<sBQG?QF143gNzbW(xtThZ8Jo9bB<&S
z=xr7(n6lknu%mkZr^%-jcc}78^~+IJf2KSRYod|f#tmztq1DkyEH%7(xT$e<;|6~+
z?q4U{P5w!D>$Y98BpPq-Dys7W{0JlYwqI0???3y;+WBi9+i~faYZ~8q@>>HWqb}!h
zJ36t_B|2JW6IP914Sp~F{fYZq+uwNi!guaoK0fE}E2qXj^j`YI2j0lV`hJLure}bX
ztuvhmPz?71*PP1W-@&h#{$L6GM&KHL&a?@D<^;iCz;9&{{61jC$~8*h6D9B`OW;-L
zaG$6Z^|cx_a_JLfePXfj`LrBJIi>H!AA)Ee{Ae{AX<3U1WG8+#VvaahNnkGRLAC}X
z+oR?^OP)hU`r&eU5@G%g4n^dIYY>KUU@#stl4dYr8ip`Bd%BHKI1xS&Nt)qAPj_oH
z9t-ybd!u1XR$LN^MNDDzgNW|!oknYXaL`BuV+SSINkW2mg!}Fjag=S)uaA@t#S_tx
z6m~>n!D!@2STZ}qu~1Gk5;FxV-A7e!M2%6|zJo^Jz(J!w7>SCZ1Qhy#_YDWB4wf6k
zAQRQF!C)jNjBqGu2BFuROj<Y~l(V&~v!&Ho=iiXct@CfRdXc(}yUn7sx?J+lqVz2j
zzXr<t!h%QyOU*6j$?+8;wKOuDyetDxiT6$3??xb{G@|xL#+w!HQRBxr^B1Z$X-9h(
z)r!-k4d*?MWK%ZWzTeH*aQoD{YQwo~@}sHx&{;B{0F`*Y63%@=qGyyJ@~ygnU~$}r
za~~6a!iL+=tCKcdbq%SD2^*e0f`I?lhTE6MIUBByJn2Uteb=KOE5BB$3H^}?vn+E?
zAAQwxTFU5?+4v)fGIdYmTfL$gIpPOMG(DL?s(XTXYU1=c$v;LsHEnuA^4}$%hHCnR
z<c|<fLp1%2<P*eGlc&cee=qSB#E)d{`^Uk{wD!Hu^!fdI`b~ZGt(omTU1Q}hqAY!E
zZmT3){sFDb!bbSGT)m==BwO}?*`<$_-vz2~x~iw&HkY8uONm93=kCi)_WP?>JS_e1
zJ58<3@vvV)ienpVq?=XOVXwb(-L0o*^jD^C*Ij4y^ViK<I6PlrIjkawrTmR-`LkEU
z@>rvfZuuz;P&3r0N<X&cXW*vhqRCS_K4;2bfS!x0GeQ;n=rmlSJ*2*Gx*r;p!|3@!
z`mtGc^-$5%?N`@MyhPeB(`RbvdM2Zfwa@73GiXMy2mT)bbgX^mk%?6JZ2RR3XhGp}
z*Vx=PNCPLy>=ccqKDKZj>hqG!r_WB6TdpqCbh%eRe?ftMS%LoOt3H%9dexQMK&51D
zFQ6w?SyUj(I#X^d>$PjBHf&MBN-35Ve73;o2X><njE?QPjPhh-Pr*>OW@;}4Q$N8+
zvih;^t08@TmFzIHeCh!RUOSx|?(x7k1G_uZe+ujhU~bhtS|+E?YN9&>>1&<oD_yIo
z*FE|x*W6Pte}<Yq@}8-!{R@wGSNhYg^p&>s2Z79ji~8tkm%iz*sY|q`_U;SZ6WABn
zA23dj=L-A?OHKMytB&^7?R)D&`?TTBT3tvkZPzmQtxaeU4cGlBl4j~>pg#w#LIZk0
z7h!;21&v~6yajp@^lKPBx;IgB9oZpV!#>xts!GqetI|g}-IY(k&&{NuQgMADZi1Zj
zXa1SVjF7I^*Ws<bqk7IE&xp8v>8)Q~f742W$-WIg9e(ZmC)wVE-yNv$H)vJ`yuL@v
zTIW`{J6x!ew7DPf2-*<_6)j%h_sd$mwU4{oz1rBU7H|Fc%5`tUqZPWhX|%H2+nn$=
z1-uObZ+(kbgC6u-ydJp+Q$HMsAKHZeUlN~}d_GbaQgTu{lPU2Y&-W&}2UFtv(h`f!
zp3BP=&tt~VH$I<f{3x;f<Lj9?@%#?rGwb9mLbKO5aX}3NpHW{?73Q<4)>0P>6=gyP
z2Bo9w+~To3Zo%1kO*;go#TF6u3Shj677Y^Dd&Xh~pQT*>7ZlEVnC7y5sIG)Coh0v3
z{;<4QE-hyiKdCz66UB2ol>7e~$-XBY9xGG>7Ag8=MH?0EP;|GV{fau=d@jrPv8}DG
zo3;8~y{VX)(r)o@^f#<tpOW0#2iG?F8#b)6(9d-U1vh3hzw7P#ZtRKt9?r+z!sLlz
z6S(oB<aud>;lDgPAM^1F!SgmBuM|9<`M5{$Jjlmq3!ZQJ_zl^4nU5E~Ye??K>Yd>U
zY%_4<g*#MayxhW@jlbB`;ivF@Wcl}rZ}S4Q8Q}JwjUU)x_^A;mit5kL?jQO33$pk6
ze0(9|BAOkNdAC@UUFUY8n^rZy<7@&qy%US#ysPDuX}g&vKFs70D@Xfd8T##nqd&b0
zpK;({R5<UymKPyzLB>V(snsN;wl~os@xp$f_db=&`?)m2=djc-?9Zow7ps4%c0Dis
z)QDg40RWy;F+ZoIuyEXe58PE`T;7!W^9#oJBZc!jPqO$_prS79?#^*P3tTHQzSY2s
z#Vcw{;B?2SL4R&n^OLuO-zl8qk~gag-3DCa%Gqe6)Gu5wbXO@BPq<s^+Z?Fup%VBA
zaIH{XJPmvvZY{hX)$u8wFQNY%;1pMJu8Y@!uPoyKeez#c7>D^(;k=KtX(c+4`g2kp
z*zzt0;bMuiR*q^Va6fR03pwLFn@i~LE`h&~qKd_r`k-GdUUW#7TiD(QrGKw@Odb64
z4hrA%Bwl16?n{_SGu7Yk?-RMmkYNrQeH0r?BA^nA8waBC-eA-Snejx@2&RSw!aGCJ
zuo({dZ)x1rR9s0$jErC+5j>1YjF~tr`V+yyun|fP4jzVyjWa03l&4A&rJ*=NKW1DK
zRL?Lvb_BZHjrMJA6w5LYA~o7|1?p`(gt4{j&Xz!zac4)z&h{RoC(zQ>PKtTXL-~LV
zjR~V|&$d8!XKOAzWrdxZn>l<$K_eA(>Px1qV3;GimW_Q;M5`b`mG6q0CnIP7J|uT1
zB3YqG%t$4}s5eFLibv=SihXg^D=$)(U#wvu=9lfjP%>@|1Y;qJ{#o%fY8v%cE})km
z@XL#?QF*pVU9O}J`60h-zu01eDq1Hacfy}MJZJ`cLCu6k2RMhW3@3(!KNdH`{y<CT
zYBP91aR*{4e{U*+NP8qC{KO3elLNvZIvj&Pi<${ba$h)+jKpJki~(6991W6z$_+(L
z;g{|ABkMm92Wy6h@s+_(e<ChpjQ;R|n!E!cIAP8*wPvwp!FiMr9E|j#P86c_BSI<s
z)EQV6xgF-e%h9_ATOH0^EAjo3DZgu!Sn6_~=$G)Ls~Fq!J(Q^inLY9T&DdIG?Dl+L
zWqK1UD(bXv1AYZ>2`-=SwM?6p9lyUE*A}r2aylB>{({Odoutk|qGt_d*`D7;yMfUg
zhVA*D%#`1AP?1TwV^-`(j^0Xa&-ZDj^-7cL&w5M`LQZcl=K0>uv_aWB>#tyO1R3g6
zw&(jfQ+^L}`Ofw~tn6EqLw;W}J+5%FUxc62{&8T`C+gXl{XYi3%lX|36`7plp9X5T
z=XU|q5z8$5^{E`wAA+~r^ZS7**OwhI&-BL*d%jOGeVsejQ7-#?)?v@_2d4ZEXMJb;
zpHuc+4BwNO&SOJGo%Sy{>`iq~WP01@*i$5x`j5-!cMww#32lk{jiJ|&p*ID`0r-B*
z|37u=Gtcx5*jC%@IUX~j0y?Y*6`7c4`Zu67_qcq%hx7lZxnVp%*^cKAy+5dlS^H`Y
z9K~fM5yKYAe%YSsB}nY{*?X%hfXiVAY{&czGK6vYntJ#7l%dCAps}H%AA?f)4Gx^`
zS2=LfrDUf(_Lju@HmmZFtB#{{hTa%l9o|1_eskR|OY1vDn+4LS!#S60N$HMT-2R|?
M>Rx9>MV<El0$o%&VE_OC

literal 0
HcmV?d00001

-- 
GitLab