{"id":510,"date":"2025-05-05T17:46:43","date_gmt":"2025-05-05T17:46:43","guid":{"rendered":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/?p=510"},"modified":"2025-05-05T19:12:48","modified_gmt":"2025-05-05T19:12:48","slug":"3-uniform-set-systems-on-n-for-small-n","status":"publish","type":"post","link":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/2025\/05\/05\/3-uniform-set-systems-on-n-for-small-n\/","title":{"rendered":"3-uniform set systems on [n] with VC-dimension 2, for small n"},"content":{"rendered":"\n<p>The following code implements an exhaustive search using backtracking to compute the maximum size of a 3-uniform set system on [n] with VC-dimension at most 2.<\/p>\n\n\n\n<p>In practice, this program only works for small values of n. For our purpose, we only need the result for n=6 and n=7. For example, on a typical personal computer, when n = 7, this C program takes only about 1 minute to verify that the size of the largest 3-uniform set system on [7] with the given VC-dimension is at most 16.<\/p>\n\n\n\n<p>The detailed algorithm is provided in the Appendix.<\/p>\n\n\n\n<p>The following code was written by Prof. Jian Wang (wangjian01@tyut.edu.cn).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/*A search using back-tracking*\/\n#include &lt;iostream&gt;\n#include&lt;fstream&gt;\n#include &lt;algorithm&gt;\n#include&lt;ctime&gt;\n#include &lt;string&gt;\n#include &lt;bitset&gt;\n#include &lt;math.h&gt;\nusing namespace std;\n#define N 50\n#define M 10000\n#define L 7\n#define K 3\n\n\nint n, k, tmp,sum=1,pos;\n\nint setNum&#091;M];       \/\/the set of all 0-1 sequences with k 1's\nint traceList&#091;M]&#091;N]; \/\/traceList&#091;i]&#091;j], j=1,2,...,2^k, list all possible traces of sequences  setNum&#091;i]\nint traceList2&#091;N]&#091;M]&#091;N]; \/\/traceList2&#091;q]&#091;i]&#091;j] gives whether the trace traceList&#091;i]&#091;j] is shattered in run q of the backtracking\nint current&#091;M];    \/\/the list in backtracking\nint max = 1;\nfstream file;\n\nint number_of_1(int m) \/\/ return the number of 1's in  binary  m\n{\n    int count = 0;\n    for (int i = 0; i &lt; n; i++) {\n        if (((m &gt;&gt; i) &amp; 1) == 1) {\n            count++;\n        }\n    }\n    return count;\n}\nstring index_of_1(int m) \/\/return the index of 1 in  binary m\n{\n    string set = \"\";\n    for (int i = 0; i &lt; n; i++) {\n        if (((m &gt;&gt; i) &amp; 1) == 1) {\n            set = set + to_string(i + 1);\n        }\n    }\n    if (set == \"\") set = \"empty\";\n    return set;\n}\n\nint generateSets()\/\/ generate all 0-1 sequences with k 1's as an integer\n{\n    sum = 1;\n    for (int i = 0; i &lt; pow(2, n); i++)\n    {\n        tmp = number_of_1(i);\n        if (tmp == k)\n        {\n            setNum&#091;sum] = i;\n          \/\/  bitset&lt;7&gt; bit(i);\n          \/\/  cout &lt;&lt; bit &lt;&lt; endl;\n            sum++;\n        }\n    }\n    sum--;\n    return 0;\n}\n\nint generateTracelist()\/\/ generate all possible traces of sequences  setNum&#091;i]\n{\n    for (int i = 1; i &lt;= sum; i++)\n    {\n        bitset&lt;L&gt; bit1(setNum&#091;i]);\n        tmp = setNum&#091;i]; \n        for (int j = 0; j &lt; pow(2, k); j++)\n        {\n            bitset&lt;K&gt; bit2(j);\n            int count = 0;\n            for (int p = 0; p &lt; n; p++) {\n                if (((tmp &gt;&gt; p) &amp; 1) == 1) {\n\n                    bit1&#091;p] = bit2&#091;count];\n                    count++;\n                }\n            }\n            traceList&#091;i]&#091;j+1] = bit1.to_ullong();\n        }\n    }\n    return 1;\n}\n\nint showList()\n{\n    file.open(\"full.txt\", ios::out);\n    if (!file) {\n        cerr &lt;&lt; \"Unable to open file!\" &lt;&lt; endl;\n        return 1; \/\/ fail\n    }\n    for (int i = 1; i &lt;=sum; i++)\n    {\n        file &lt;&lt;i&lt;&lt;\"-&gt;\" &lt;&lt; index_of_1(setNum&#091;i]) &lt;&lt; \":\";\n        for (int j = 1; j &lt;=pow(2, k); j++)\n        {\n            file &lt;&lt; index_of_1(traceList&#091;i]&#091;j]) &lt;&lt; \"|\";\n        }\n        file &lt;&lt; endl;\n    }\n    file.close();\n    return 0;\n}\n\nint checkList()\n{\n    file.open(\"checkList.txt\", ios::out);\n    if (!file) {\n        cerr &lt;&lt; \"Unable to open file!\" &lt;&lt; endl;\n        return 1; \/\/ fail\n    }\n    pos = 13;\n    current&#091;1] = 4; current&#091;2] = 6; current&#091;3] = 8; current&#091;4] = 9;\n    current&#091;5] = 10; current&#091;6] = 11; current&#091;7] = 14; current&#091;8] = 15;\n    current&#091;9] = 16; current&#091;10] = 17; current&#091;11] = 18; current&#091;12] = 19;\n    current&#091;13] = 20;\n    int temlist&#091;N];\n \n    for (int i = 1; i &lt;= pos; i++)\n    {\n        for (int j = 1; j &lt;= pow(2, k); j++)\n        {\n            temlist&#091;j] = 0;\n        }\n        int x = current&#091;i];\/\/check the trace  of x\n        for (int j = 1; j &lt;= pos; j++)\n        {\n            int y = current&#091;j];\n            int trace = setNum&#091;x] &amp; setNum&#091;y];\n            for (int p = 1; p &lt;= pow(2, k); p++)\n            {\n                if (temlist&#091;p] == 0 &amp;&amp; trace == traceList&#091;x]&#091;p])\n                {\n                    temlist&#091;p] = 1;\n                }\n            }\n        }\n        file &lt;&lt; index_of_1(setNum&#091;x]) &lt;&lt; \":missing-&gt;\";\n        for (int j = 1; j &lt;= pow(2, k); j++)\n         {\n                if (temlist&#091;j] == 0)\n                {\n                    file &lt;&lt; index_of_1(traceList&#091;x]&#091;j]) &lt;&lt; \"|\";\n                }\n        }\n        file &lt;&lt; \"********trace-&gt;\";\n        for (int j = 1; j &lt;= pow(2, k); j++)\n        {\n                if (temlist&#091;j] == 1)\n                {\n                    file &lt;&lt; index_of_1(traceList&#091;x]&#091;j]) &lt;&lt; \"|\";\n                }\n        }\n        \n        file &lt;&lt; \"*********************************************************************\" &lt;&lt; endl;\n    }\n    file.close();\n    return 0;\n}\n\nint maxSetVcdim2() \/\/the back-tracking\n{\n    file.open(\"example.txt\", ios::out);\n    if (!file) {\n        cerr &lt;&lt; \"Unable to open file!\" &lt;&lt; endl;\n        return 1; \/\/ fail\n    }\n    for (int i = 1; i &lt;= sum; i++)\n    {\n        for (int j = 0; j &lt;= pow(2, k); j++)\n        {\n            for (int p = 0; p &lt;= pow(2, k); p++)\n            {\n                traceList2&#091;p]&#091;i]&#091;j] = 0;\n            }\n        }\n    }\n\n    current&#091;1] = 1;\n    traceList2&#091;1]&#091;1]&#091;0] = 1;\n    traceList2&#091;1]&#091;1]&#091;(int)pow(2, k)] = 1;\n    pos=2;\n    int max = 1;\n    current&#091;pos] = current&#091;pos - 1];\n    while (pos&gt;1)\n    {\n        \/*checking output data*\/ \n       \/* for (int i = 1; i &lt; pos; i++)\n        {\n            int y = current&#091;i]; \n            cout &lt;&lt; index_of_1(setNum&#091;y]) &lt;&lt; \":missing-&gt;\";\n            for (int j = 1; j &lt;= pow(2, k); j++)\n            {\n                if (traceList2&#091;pos - 1]&#091;y]&#091;j] == 0)\n                {\n                    cout&lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                }\n            }\n            cout &lt;&lt; index_of_1(setNum&#091;y]) &lt;&lt; \"********trace-&gt;\";\n            for (int j = 1; j &lt;= pow(2, k); j++)\n            {\n                if (traceList2&#091;pos - 1]&#091;y]&#091;j] == 1)\n                {\n                    cout &lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                }\n            }\n            cout &lt;&lt; endl;\n        }\n       \/\/ getchar();\n        \/*checking output data*\/\n        current&#091;pos]++;\n        if (current&#091;pos] &gt; sum)\n        {\n            pos--;\n            if (pos &gt;=max) \/\/If a larger family is found then output it.\n            {\n                max = pos;\n                file &lt;&lt; max &lt;&lt; \"-&gt;\";\n                for (int i = 1; i &lt;=pos; i++)\n                {\n                    file &lt;&lt; index_of_1(setNum&#091;current&#091;i]]) &lt;&lt; \"   \";\n                }\n                file &lt;&lt; endl;\n                file &lt;&lt; \"*********************************************************************\" &lt;&lt; endl;\n                for (int i = 1; i &lt;=pos; i++)\n                {\n                    int y = current&#091;i];\n                    file &lt;&lt; index_of_1(setNum&#091;y]) &lt;&lt; \":missing-&gt;\";\n                    for (int j = 1; j &lt;= pow(2, k); j++)\n                    {\n                        if (traceList2&#091;pos]&#091;y]&#091;j] == 0)\n                        {\n                            file &lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                        }\n                    }\n                    file &lt;&lt;\"********trace-&gt;\";\n                    for (int j = 1; j &lt;= pow(2, k); j++)\n                    {\n                        if (traceList2&#091;pos]&#091;y]&#091;j] == 1)\n                        {\n                            file &lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                        }\n                    }\n                    file &lt;&lt; endl;\n                }\n                file &lt;&lt; \"*********************************************************************\" &lt;&lt; endl;\n\n            }\n            continue;\n        }\n        int increaseVCdim = 0;  \n        \/\/if we add setNum&#091;z] to the family, the variable used to check whether the Vc dimension is increased.\n        int z = current&#091;pos];\/\/index of the new set\n        for (int j = 1; j &lt;= pow(2, k); j++)\n        {\n            traceList2&#091;pos]&#091;z]&#091;j] = 0;\n        }\n        traceList2&#091;pos]&#091;z]&#091;(int)pow(2, k)] = 1;\n        for (int i = 1; i &lt;pos; i++)\n        {\n            int y = current&#091;i];\n            int numx = setNum&#091;y]&amp;setNum&#091;z];\/\/the intersection of setNum&#091;y] and setNum&#091;z]\n            for (int j = 1; j &lt;= pow(2, k) - 1; j++)\n            {\n                if (numx == traceList&#091;z]&#091;j])\/\/record the traces of z with sets already in the family\n                {\n                    traceList2&#091;pos]&#091;z]&#091;j] =1;\n                }\n            }\n          \/\/ cout &lt;&lt; index_of_1(numx) &lt;&lt; \"------\" &lt;&lt; index_of_1(setNum&#091;z]) &lt;&lt; \"cap\" &lt;&lt; index_of_1(setNum&#091;y]) &lt;&lt; traceList2&#091;pos]&#091;z]&#091;4] &lt;&lt; endl;\n            if (traceList2&#091;pos-1]&#091;y]&#091;0] !=(int) pow(2, k) - 1) continue; \/\/clearly y is not shattered in this case\n           \n            for (int j = 1; j &lt;= pow(2, k)-1; j++) \/\/if traces of setNum&#091;y] is 2^k-1 before adding z, consider the new trace created by setNum&#091;y]&amp;setNum&#091;z]\n            {\n                if (numx == traceList&#091;y]&#091;j]&amp;&amp; traceList2&#091;pos-1]&#091;y]&#091;j] == 0)\n                {\n                    increaseVCdim = 1;\n                    break;\n                }\n            }\n            if (increaseVCdim == 1) break;\n        }\n        traceList2&#091;pos]&#091;z]&#091;0] = 0;  \/\/update the trace of setNum&#091;z]\n        for (int j = 1; j &lt;= pow(2, k); j++)\n        {\n            traceList2&#091;pos]&#091;z]&#091;0] += traceList2&#091;pos]&#091;z]&#091;j];\n        }\n        if (traceList2&#091;pos]&#091;z]&#091;0] == (int)pow(2, k))  increaseVCdim = 1;\/\/ if z is shattered\n\n        if (increaseVCdim == 0) \/\/one can add z into the current family\n        {\n            for (int i = 1; i &lt; pos; i++)\n            {\n                int y = current&#091;i]; \/\/copy the previous trace \n                for (int j = 0; j &lt;= pow(2, k); j++)\n                {\n                    traceList2&#091;pos]&#091;y]&#091;j] = traceList2&#091;pos-1]&#091;y]&#091;j];\n                }\n            }\n\n            for (int i = 1; i &lt; pos; i++)\/\/update the traces \n            {\n                int y = current&#091;i];\n                int numx = setNum&#091;y] &amp; setNum&#091;z];\n                for (int j = 1; j &lt;= pow(2, k) - 1; j++)\n                {\n                    if (numx == traceList&#091;y]&#091;j]&amp;&amp; traceList2&#091;pos]&#091;y]&#091;j]==0)\n                    {\n                        traceList2&#091;pos]&#091;y]&#091;j] = 1;\n                        traceList2&#091;pos]&#091;y]&#091;0]++;\n                    }\n                }\n            }\n            if (false&amp;&amp;pos == 3) {\n            for (int i = 1; i &lt;= pos; i++)\n            {\n                int y = current&#091;i];\n                cout &lt;&lt; index_of_1(setNum&#091;y]) &lt;&lt; \":missing-&gt;\";\n                for (int j = 1; j &lt;= pow(2, k); j++)\n                {\n                    if (traceList2&#091;pos]&#091;y]&#091;j] == 0)\n                    {\n                        cout &lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                    }\n                }\n                cout &lt;&lt; \"********trace-&gt;\";\n                for (int j = 1; j &lt;= pow(2, k); j++)\n                {\n                    if (traceList2&#091;pos]&#091;y]&#091;j] == 1)\n                    {\n                        cout &lt;&lt; index_of_1(traceList&#091;y]&#091;j]) &lt;&lt; \"|\";\n                    }\n                }\n                cout &lt;&lt; endl;\n            }\n           \/\/ getchar();\n            }\n            \n            pos++;\n            current&#091;pos] = current&#091;pos - 1];\n        }\n   }\n    file.close();\n    return 1;\n}\n\nint main()\n{\n    n = L;\n    k = K;\n    generateSets();\n    generateTracelist();\n    showList();\n    \/\/checkList();\n   \/\/ getchar();\n    maxSetVcdim2();\n    return 0; \n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The following code implements an exhaustive search using backtracking to compute the maximum size of a 3-uniform set system on [n] with VC-dimension at most 2. In practice, this program only works for small values of n. For our purpose, we only need the result for n=6 and n=7. For example, on a typical personal [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-510","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/posts\/510","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/comments?post=510"}],"version-history":[{"count":4,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/posts\/510\/revisions"}],"predecessor-version":[{"id":514,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/posts\/510\/revisions\/514"}],"wp:attachment":[{"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/media?parent=510"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/categories?post=510"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ibs.re.kr\/ecopro\/zixiangxu\/wp-json\/wp\/v2\/tags?post=510"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}