|
25 | 25 | "sns.set_theme(context=\"paper\", style=\"white\")" |
26 | 26 | ] |
27 | 27 | }, |
| 28 | + { |
| 29 | + "cell_type": "code", |
| 30 | + "execution_count": null, |
| 31 | + "id": "73158062-f645-4e9b-9104-8a8850fb5509", |
| 32 | + "metadata": {}, |
| 33 | + "outputs": [], |
| 34 | + "source": [ |
| 35 | + "!python3 scripts/combine_data.py" |
| 36 | + ] |
| 37 | + }, |
| 38 | + { |
| 39 | + "cell_type": "code", |
| 40 | + "execution_count": null, |
| 41 | + "id": "3daf29a1-0d99-4be0-9e3e-86e8ce05460d", |
| 42 | + "metadata": {}, |
| 43 | + "outputs": [], |
| 44 | + "source": [ |
| 45 | + "!mkdir -p figures" |
| 46 | + ] |
| 47 | + }, |
28 | 48 | { |
29 | 49 | "cell_type": "code", |
30 | 50 | "execution_count": null, |
31 | 51 | "id": "2ce88784-56ab-49d1-b79c-875abbde17cc", |
32 | 52 | "metadata": {}, |
33 | 53 | "outputs": [], |
34 | 54 | "source": [ |
35 | | - "df = pd.read_csv(\"../data/experiments.csv\")\n", |
| 55 | + "df = pd.read_csv(\"./data/experiments.csv\")\n", |
36 | 56 | "df[\"n+m\"] = df[\"n\"] + df[\"m\"]\n", |
37 | 57 | "df = df[df[\"n+m\"] != 0]\n", |
38 | 58 | "df[\"log(n+m)\"] = np.log(df[\"n+m\"])\n", |
|
70 | 90 | "data.groupby(\"dataset\")[\"time/(n+m) [ns]\"].agg([\"count\", \"mean\"])" |
71 | 91 | ] |
72 | 92 | }, |
| 93 | + { |
| 94 | + "cell_type": "code", |
| 95 | + "execution_count": null, |
| 96 | + "id": "fa7e01da-ffaf-4b1c-a7de-ac182949679c", |
| 97 | + "metadata": {}, |
| 98 | + "outputs": [], |
| 99 | + "source": [ |
| 100 | + "data = df.copy()\n", |
| 101 | + "data.groupby([\"dataset\", \"algo\"], observed=True)[\"time/(n+m) [ns]\"].mean()" |
| 102 | + ] |
| 103 | + }, |
73 | 104 | { |
74 | 105 | "cell_type": "code", |
75 | 106 | "execution_count": null, |
|
389 | 420 | "plt.show()" |
390 | 421 | ] |
391 | 422 | }, |
392 | | - { |
393 | | - "cell_type": "code", |
394 | | - "execution_count": null, |
395 | | - "id": "fd47d899-9156-48d4-9417-640301778a04", |
396 | | - "metadata": {}, |
397 | | - "outputs": [], |
398 | | - "source": [] |
399 | | - }, |
400 | 423 | { |
401 | 424 | "cell_type": "markdown", |
402 | 425 | "id": "6969b204-1770-4462-9ad9-91d7a292fbcc", |
|
503 | 526 | "id": "d71985d0-2a3f-4f46-8c62-11db9899e15d", |
504 | 527 | "metadata": {}, |
505 | 528 | "source": [ |
506 | | - "# Edge cases" |
| 529 | + "# Simple graphs" |
507 | 530 | ] |
508 | 531 | }, |
509 | 532 | { |
|
513 | 536 | "metadata": {}, |
514 | 537 | "outputs": [], |
515 | 538 | "source": [ |
516 | | - "fig, axes = plt.subplots(figsize=(6, 2.5), ncols=3, sharey=True)\n", |
| 539 | + "fig, axes = plt.subplots(figsize=(6, 3), ncols=3, sharey=True)\n", |
517 | 540 | "for ax, dataset, title in zip(axes, (\"empty\", \"path\", \"cycle\"), (\"Empty graphs $E_n$\", \"Path graphs $P_n$\", \"Cycle graphs $C_n$\")):\n", |
518 | 541 | " data = df[df[\"dataset\"] == dataset]\n", |
519 | 542 | " ax.set(title=title)\n", |
520 | 543 | " ax.set(ylim=(0, 3.5), axisbelow=True)\n", |
521 | 544 | " ax.tick_params(axis='x', which='major', bottom=True, labelsize=8)\n", |
522 | 545 | " ax.grid(True)\n", |
523 | | - " sns.scatterplot(x=\"n\", y=\"time/n [μs]\", hue=\"algo\", edgecolor=None, s=2, data=data, ax=ax, rasterized=True)\n", |
524 | | - "for ax in axes[:-1]:\n", |
| 546 | + " sns.scatterplot(x=\"n+m\", y=\"time/(n+m) [μs]\", hue=\"algo\", edgecolor=None, s=2, data=data, ax=ax, rasterized=True)\n", |
525 | 547 | " ax.legend([],[], frameon=False)\n", |
526 | | - "axes[-1].legend(bbox_to_anchor=(1.0, 1.0), frameon=False, markerscale=4, title=\"Algorithm\")\n", |
| 548 | + "axes[1].legend(bbox_to_anchor=(1.0, 1.0), markerscale=4, title=\"Algorithm\")\n", |
527 | 549 | "sns.despine(left=True)\n", |
528 | 550 | "fig.tight_layout()\n", |
529 | 551 | "plt.savefig(\"figures/empty-path-cycle.pdf\", dpi=300)\n", |
530 | 552 | "plt.show()" |
531 | 553 | ] |
| 554 | + }, |
| 555 | + { |
| 556 | + "cell_type": "markdown", |
| 557 | + "id": "605bdb3a-1b34-45a7-931d-66df1276c486", |
| 558 | + "metadata": {}, |
| 559 | + "source": [ |
| 560 | + "# Anaylsis of $G(n, m)$ model" |
| 561 | + ] |
| 562 | + }, |
| 563 | + { |
| 564 | + "cell_type": "code", |
| 565 | + "execution_count": null, |
| 566 | + "id": "af30f324-dbe9-4914-9764-d45e93403a55", |
| 567 | + "metadata": {}, |
| 568 | + "outputs": [], |
| 569 | + "source": [ |
| 570 | + "import networkx as nx\n", |
| 571 | + "from tqdm.contrib.concurrent import process_map\n", |
| 572 | + "from itertools import product\n", |
| 573 | + "from subprocess import run\n", |
| 574 | + "from tempfile import NamedTemporaryFile, TemporaryDirectory\n", |
| 575 | + "\n", |
| 576 | + "import sys \n", |
| 577 | + "sys.path.insert(1, '../scripts')\n", |
| 578 | + "import analyze\n", |
| 579 | + "\n", |
| 580 | + "def write_metis_to_file(f, graph: nx.Graph):\n", |
| 581 | + " graph = nx.convert_node_labels_to_integers(graph)\n", |
| 582 | + " f.write(f\"{graph.number_of_nodes()} {graph.number_of_edges()}\\n\".encode())\n", |
| 583 | + " for u in graph.nodes:\n", |
| 584 | + " f.write((\" \".join(str(v+1) for v in graph[u]) + \"\\n\").encode())\n", |
| 585 | + " f.flush()\n", |
| 586 | + " f.seek(0)\n", |
| 587 | + "\n", |
| 588 | + "def modular_decomposition(graph: nx.Graph):\n", |
| 589 | + " with NamedTemporaryFile() as input_file, TemporaryDirectory() as dir:\n", |
| 590 | + " write_metis_to_file(input_file, graph)\n", |
| 591 | + " output = Path(dir) / \"out\"\n", |
| 592 | + " cmd = [\"../target/release/md\", \"--input-type\", \"metis\", \"--input\", input_file.name, \"--algo\", \"fracture\", \"--output\", output]\n", |
| 593 | + " out = run(cmd, capture_output=True)\n", |
| 594 | + " out.check_returncode()\n", |
| 595 | + " return analyze.analyze_tree(output, only_header=False, timeout=10)\n", |
| 596 | + "\n", |
| 597 | + "def generate_data(params):\n", |
| 598 | + " n, m, seed = params\n", |
| 599 | + " m = int(m)\n", |
| 600 | + " graph = nx.gnm_random_graph(n, m, seed=seed)\n", |
| 601 | + " res = modular_decomposition(graph)\n", |
| 602 | + " return [dict(n=n, m=m, seed=seed, kind=kind, num=num) for kind, num in zip((\"prime\", \"series\", \"parallel\"), map(int, res.split(\",\")[5:8]))]" |
| 603 | + ] |
| 604 | + }, |
| 605 | + { |
| 606 | + "cell_type": "code", |
| 607 | + "execution_count": null, |
| 608 | + "id": "11b6cbbe-9824-47c6-a39d-9e3601782aa3", |
| 609 | + "metadata": {}, |
| 610 | + "outputs": [], |
| 611 | + "source": [ |
| 612 | + "if False:\n", |
| 613 | + " params = [(n, m, seed) for n, repeats in [(2**10, 40), (2**16, 10)] for m, seed in product(np.linspace(0, 3 * 2**10, 81), range(repeats))]\n", |
| 614 | + " rows = process_map(generate_data, params, chunksize=16)\n", |
| 615 | + "else:\n", |
| 616 | + " rows = []" |
| 617 | + ] |
| 618 | + }, |
| 619 | + { |
| 620 | + "cell_type": "code", |
| 621 | + "execution_count": null, |
| 622 | + "id": "c302fa6e-3eb7-4cdf-9e93-699a7e7c4922", |
| 623 | + "metadata": {}, |
| 624 | + "outputs": [], |
| 625 | + "source": [ |
| 626 | + "data = pd.DataFrame([row for group in rows for row in group])\n", |
| 627 | + "data = data[data[\"n\"].isin([2**10, 2**16])]\n", |
| 628 | + "data[\"m/n\"] = data[\"m\"] / data[\"n\"]\n", |
| 629 | + "data[\"num/n\"] = data[\"num\"] / data[\"n\"]\n", |
| 630 | + "\n", |
| 631 | + "fig, ax = plt.subplots(figsize=(6, 2.5))\n", |
| 632 | + "sns.lineplot(x=\"m/n\", y=\"num/n\", hue=\"kind\", style=\"n\", rasterized=True, data=data, ax=ax)\n", |
| 633 | + "ax.legend(bbox_to_anchor=(1, 1), loc=\"upper left\", frameon=False)\n", |
| 634 | + "sns.despine()\n", |
| 635 | + "plt.savefig(\"figures/gnm-module-distribution.pdf\", dpi=300)\n", |
| 636 | + "plt.show()" |
| 637 | + ] |
532 | 638 | } |
533 | 639 | ], |
534 | 640 | "metadata": { |
|
0 commit comments