Open john-boyer-phd opened 7 months ago
Initial investigation has yielded interesting results. I started by using the Nauty makeg
in older planarity code to generate the exact sequence of OK (K{3,3}-free) and NONEMBEDDABLE (containing K{3,3}) results.
Then, I tested the same sequence of OK and NONEMBEDDABLE results coming from the current version of planarity
running over a .g6
file generated by the current Nauty&Traces version 2.8000 (32 bits) geng program
:
> geng 11 20:20 > n11.m20.g6
I got the following results:
> planarity -t -3 n11.m20.g6 n11.m20.g6.t.3.out.txt
Start testing all graphs in "n11.m20.g6".
Num OK disagreements = 2200162, Num NONEMBEDDABLE disagreements = 2200062
Done testing all graphs (65.363 seconds).
With output file:
FILENAME="n11.m20.g6" DURATION="65.363"
-3 15108047 3500029 11608018 SUCCESS
Comparing with tables generated back in the 2.0 release of planarity
, there's 100 more OK
s and 100 less NONEMBEDDABLE
s. However, there are also 4.4 million disagreements, which suggests that the old makeg
program did not generate graphs in the same order as the new geng
program.
After adding the G6WriteIterator
code into the old planarity
project, I was able to write the graphs generated by the makeg
functionality of the old planarity
codebase to a .g6
output file. When the new planarity
project is run on this .g6
file, we now report the same results as were produced by the old version of planarity
:
Old planarity
code:
> planarity -gen -3 11 20 20
...
Begin Stats for Algorithm K3,3 Search
Status=SUCCESS
maxn=11, mine=20, maxe=20, arcCapacity=40
# Edges # Graphs no K3,3 with K3,3
------- ---------- ---------- ----------
20 15108047 3499929 11608118
TOTALS 15108047 3499929 11608118
End Stats for Algorithm K3,3 Search
Total time = 69.010 seconds
Current planarity
code running command:
planarity -t -3 n11.m20.oldgeng.g6 n11.m20.oldgeng.g6.t.3.out.txt
Produces output file:
FILENAME="n11.m20.oldgeng.g6" DURATION="65.481"
-3 15108047 3499929 11608118 SUCCESS
These results suggest that the old makeg
may have had a bug in generating graphs that has been fixed by the newer geng
program. Less likely, perhaps there is a bug in the newer geng
program. To test these hypotheses, Since the makeg
and geng
programs generated the same total number of 11-vertex 20-edge graphs, I will be pursuing the following next steps:
.g6
file?
OK
s and 100 less NONEMBEDDABLE
s in the output of running planarity on the new file: there are 50 graphs that do contain a K_{3, 3}
that are duplicated, then that would indicate we overcount the NONEMBEDDABLE
s by 50 and undercount the OK
s by 50, which would mean the old planarity results are incorrect.g6
file?
OK
s and 100 less NONEMBEDDABLE
s in the output of running planarity on the new file: if there are 50 graphs that do not contain a K_{3, 3}
that are duplicated, then that would indicate we overcount the OK
s by 50 and undercount the NONEMBEDDABLE
s by 50, which explain why the new planarity results are incorrect vs. the old.g6
files. Specifically, search for graphs that appear in the new .g6
file that didn't appear in the old one, and search for graphs that appear in the old .g6
file but don't appear in the new one.
K_{3,3}
and the new file instead contains 50 new graphs that are all K_{3,3}-free
. If the new graphs can be wrangled and then the old planarity code also reports them as K_{3,3}-free
, then we we can safely conclude that no bug has been introduced into the K_{3,3}
search algorithm but rather that the new numbers in the K_{3,3}
table reflect appropriate output from the newer geng
in the current Nauty suite.In a fork of the planarity-backup
repository, I added some additional code within runTest()
of outproc.c
(called by makeg_main()
of makeg.c
) to write a separate debug file such that for each graph that we write to the .g6
file using the G6WriteIterator
framework, we indicate whether the graph was OK
(i.e. "No K_{3, 3}
found") with a 1 or that the graph was found to be NONEMBEDDABLE
(i.e. "found a K_{3, 3}
") with a 0.
Then, I was able to add some code to the edge-addition-planarity-suite
repository's testAllGraphs()
(within planarityTestGraphFunctionality.c
) so that for each graph in the input file (in this case, the "old" .g6
file created by planarity-backup
with the new G6WriteIterator
), we check to see whether the new version of planarity (i.e. edge-addition-planarity-suite
) agrees with the old version of planarity (i.e. planarity-backup
) on whether the graph contains a K_{3, 3}
(i.e. NONEMBEDDABLE
) or not (i.e. OK
):
% ../../Release/planarity -t -3 n11.m20-20.oldgeng.g6 n11.m20.oldgeng.g6.t.3.out.txt
Start testing all graphs in "n11.m20-20.oldgeng.g6".
Num OK disagreements = 0, Num NONEMBEDDABLE disagreements = 0
Done testing all graphs (43.392 seconds).
% cat n11.m20.oldgeng.g6.t.3.out.txt
FILENAME="n11.m20-20.oldgeng.g6" DURATION="43.392"
-3 15108047 3499929 11608118 SUCCESS
% cat planarity-backup.n11.m20.gen.3.out.txt
Begin Stats for Algorithm K3,3 Search
Status=SUCCESS
maxn=11, mine=20, maxe=20, arcCapacity=40
# Edges # Graphs no K3,3 with K3,3
------- ---------- ---------- ----------
20 15108047 3499929 11608118
TOTALS 15108047 3499929 11608118
End Stats for Algorithm K3,3 Search
Total time = 45.922 seconds
So not only was I able to confirm that the edge-addition-planarity-suite
was obtaining the same number of OK
's and NONEMBEDDABLE
's as the planarity-backup
was on the same graphs, but that both were agreeing on the same graphs (i.e. not a fluke that the numbers happened to add up to the same totals)
Finally, I then looked at the number of disagreements between the edge-addition-planarity-suite
being run on the new .g6
file generated by nauty
's geng
vs. planarity-backup
being run on the graphs generated by the embedded version of makeg
:
% ../../Release/planarity -t -3 n11.m20.g6 n11.m20.g6.t.3.out.txt
Start testing all graphs in "n11.m20.g6".
Num OK disagreements = 2200162, Num NONEMBEDDABLE disagreements = 2200062
Done testing all graphs (43.357 seconds).
% cat n11.m20.g6.t.3.out.txt
FILENAME="n11.m20.g6" DURATION="43.357"
-3 15108047 3500029 11608018 SUCCESS
As we can see, the number of disagreements is massive, far greater than the difference in the number of OK
's between the edge-addition-planarity-suite
running on the new .g6
graphs generated by nauty
's geng
vs. edge-addition-planarity-suite
run on the the old .g6
graphs generated by makeg
embedded within planarity-backup
written to file using the G6WriteIterator
(i.e. 3500029 - 3499929 = 100). This meant we had to do more digging into what exactly changed between the .g6
files, since edge-addition-planarity-suite
agreed with planarity-backup
on the old .g6
file.
I implemented a Python script to interrogate two .g6
files (https://github.com/graph-algorithms/edge-addition-planarity-suite/pull/72) to determine the following:
.g6
file, are there any duplicates?.g6
file, are there any duplicates?.g6
file that do not appear in the second .g6
file?.g6
file that do not appear in the first .g6
file?For N = 11
and M = 20
running on n11.m20.g6
, which was generated by nauty
's geng
using the following command:
geng 11 20:20 > n11.m20.g6
and on n11.m20-20.oldgeng.g6
, which was generated by planarity-backup
's embedded version of makeg
and written to file using the G6WriteIterator
framework:
% ./planarity-backup/Release/planarity -gen -3 11 20 20 > planarity-backup.n11.m20.gen.3.out.txt
Running the script indicated that:
.g6
file,.g6
files that appeared on different line numbers:
% python ../../TestSupport/g6_diff_finder.py -f n11.m20.g6 -s n11.m20-20.oldgeng.g6
INFO:root:Populating comparand dict from infile path 'n11.m20.g6'.
INFO:root:Populating comparand dict from infile path 'n11.m20-20.oldgeng.g6'.
INFO:root:No duplicates present in '/Users/wbkboyer/git/edge-addition-planarity-suite-fork/n11/20-20/n11.m20.g6'.
INFO:root:No duplicates present in '/Users/wbkboyer/git/edge-addition-planarity-suite-fork/n11/20-20/n11.m20-20.oldgeng.g6'.
INFO:root:Outputting graphs present in n11.m20 that aren't in n11.m20-20.oldgeng to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n11/20-20/graphs_in_n11.m20_not_in_n11.m20-20.oldgeng.txt.
INFO:root:Outputting graphs present in n11.m20-20.oldgeng that aren't in n11.m20 to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n11/20-20/graphs_in_n11.m20-20.oldgeng_not_in_n11.m20.txt.
INFO:root:Outputting graphs present in both n11.m20 and n11.m20-20.oldgeng that appear on different lines to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n11/20-20/graphs_in_n11.m20_and_n11.m20-20.oldgeng.txt.
This disproved the initial hypothesis of OK
's being inflated by duplicates, but due to the sheer number of graphs which might contribute to the Num OK
disagreements (2200162) and number of NONEMBEDDABLE
disagreements (2200062) (i.e. 1064452 graphs in n11.m20.g6
file not in n11.m20-20.oldgeng.g6
, and the same number in n11.m20-20.oldgeng.g6
file not in n11.m20.g6
; roughly 13739040 graphs appearing in both files but on different line numbers), this motivated the search for the smallest N
with the smallest number of edges M
such that the number of OK
's and NONEMBEDDABLE
's is different between the .g6
file generated by nauty
's geng
vs. the graphs generated by planarity-backup
's makeg
functionality and written to .g6
.
In order to ensure that we would find graphs that have subgraphs homeomorphic to K_{3, 3}
or subgraphs homeomorphic to K_5
, we need to start at N = 6
. So I used nauty
's geng
and planarity-backup
's embedded makeg
to generate the "new" and "old" .g6
files for all graphs on each N
count to see when edge-addition-planarity-suite
's testAllGraphs
for K_{3, 3}
search (i.e. planarity -t -3
) would produce a difference in the number of OK
's and NONEMBEDDABLE
's:
% cat n6.mALL.g6.t.3.out.txt
FILENAME="n6.mALL.g6" DURATION="0.001"
-3 156 147 9 SUCCESS
% cat n6.mALL.oldgeng.g6.t.3.out.txt
FILENAME="n6.mALL.oldgeng.g6" DURATION="0.001"
-3 156 147 9 SUCCESS
...
% cat n7.mALL.g6.t.3.out.txt
FILENAME="n7.mALL.g6" DURATION="0.005"
-3 1044 861 183 SUCCESS
% cat n7.mALL.oldgeng.g6.t.3.out.txt
FILENAME="n7.mALL.oldgeng.g6" DURATION="0.005"
-3 1044 861 183 SUCCESS
...
% cat n8.mALL.g6.t.3.out.txt
FILENAME="n8.mALL.g6" DURATION="0.042"
-3 12346 7327 5019 SUCCESS
% cat n8.mALL.oldgeng.g6.t.3.out.txt
FILENAME="n8.mALL.oldgeng.g6" DURATION="0.044"
-3 12346 7326 5020 SUCCESS
As seen above, it was only at N = 8
that I was able to find that there was one more OK
for the .g6
file produced by nauty
's geng
(i.e. n8.mALL.g6
) than the .g6
file produced by planarity-backup
's embedded makeg
(i.e. n8.mALL.oldgeng.g6
).
I then iteratively tested each edge-count (starting at M = 9
) and found that M = 15
was the first instance where the OK
's and NONEMBEDDABLE
's disagreed between the old and new .g6
file:
% cat n8.m15.t.3.out.txt
FILENAME="n8.m15.g6" DURATION="0.010"
-3 1557 722 835 SUCCESS
% cat n8.m15.oldgeng.t.3.out.txt
FILENAME="n8.m15-15.oldgeng.g6" DURATION="0.009"
-3 1557 721 836 SUCCESS
Using the Python .g6
diff finder script on the .g6
file produced by nauty
's geng
(i.e. n8.m15.g6
) vs. the .g6
produced by planarity-backup
's embedded makeg
(i.e. n8.m15-15.oldgeng.g6
):
% python ../../../TestSupport/g6_diff_finder.py -f n8.m15.g6 -s n8.m15-15.oldgeng.g6
INFO:root:Populating comparand dict from infile path 'n8.m15.g6'.
INFO:root:Populating comparand dict from infile path 'n8.m15-15.oldgeng.g6'.
INFO:root:No duplicates present in '/Users/wbkboyer/git/edge-addition-planarity-suite-fork/n8/15-15/1initialInvestigation/n8.m15.g6'.
INFO:root:No duplicates present in '/Users/wbkboyer/git/edge-addition-planarity-suite-fork/n8/15-15/1initialInvestigation/n8.m15-15.oldgeng.g6'.
INFO:root:Outputting graphs present in n8.m15 that aren't in n8.m15-15.oldgeng to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n8/15-15/1initialInvestigation/graphs_in_n8.m15_not_in_n8.m15-15.oldgeng.txt.
INFO:root:Outputting graphs present in n8.m15-15.oldgeng that aren't in n8.m15 to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n8/15-15/1initialInvestigation/graphs_in_n8.m15-15.oldgeng_not_in_n8.m15.txt.
INFO:root:Outputting graphs present in both n8.m15 and n8.m15-15.oldgeng that appear on different lines to /Users/wbkboyer/git/edge-addition-planarity-suite-fork/n8/15-15/1initialInvestigation/graphs_in_n8.m15_and_n8.m15-15.oldgeng.txt.
I discovered that there were 53 graphs that appeared in n8.m15.g6
that did not appear in n8.m15-15.oldgeng.g6
(and vice versa). Since the edge-addition-planarity-suite
behaves the same on the same graphs, the extra OK
(i.e. not containing a K_{3, 3}
) must have occurred on one of these new representative graphs. This meant that I had to look at which of these 53 graphs reported OK
with planarity -t -3
but NONEMBEDDABLE
with planarity -t -p
.
I added some additional code to the testAllGraphs()
function that mirrored what I had done in planarity-backup
to record which graphs reported OK
vs. NONEMBEDDABLE
and output to file, which I then used to determine which graphs were reported to not contain a K_{3, 3}
(i.e. OK
) vs. those that did contain a K_{3, 3}
(i.e. NONEMBEDDABLE
). Of those 53 graphs, there were 34 that reported 'OK'. I then used the same procedure to determine which of these 34 graphs were reported NONEMBEDDABLE
(i.e. nonplanar) when I ran planarity -t -p
. This process of elimination produced 2 graphs:
G?rls{
G?q|t[
So it was one of these two graphs that must have been erroneously reported as K_{3, 3}
-free, since they both were reported to be OK
by the K_{3, 3}
homeomorph search but reported as nonplanar, and since there's one more OK
than there should be in the new .g6
(generated by nauty
's geng
) vs. the old .g6
(generated by planarity-backup
's makeg
).
I transformed the graph G?rls{
to adjacency list using planarity -t -ta
:
N=8
0: 4 5 6 7 -1
1: 4 5 -1
2: 5 6 -1
3: 6 7 -1
4: 0 1 5 6 7 -1
5: 0 1 2 4 7 -1
6: 0 2 3 4 7 -1
7: 0 3 4 5 6 -1
And identified the obstruction to planarity using the specificGraph()
functionality (note the third parameter means that the obstruction found will be output as an adjacency list):
% planarity -s -p n8.m15.noK33.nonplanar.1.g6.AdjList.out.txt n8.m15.noK33.nonplanar.1.g6.AdjList.s.p.out.txt n8.m15.noK33.nonplanar.1.g6.AdjList.obstruction.txt
This produced the K_5
homeomorph:
N=8
0: 4 7 5 6 -1
1: 5 4 -1
2: 6 5 -1
3: 7 6 -1
4: 0 1 7 6 -1
5: 2 7 1 0 -1
6: 3 2 4 0 -1
7: 4 5 3 0 -1
However, after painstakingly removing each of the 13 edges involved in the obstruction from the original graph and re-running planarity -s -p
on each graph-less-one-edge, I was unable to find a K_{3, 3}
homeomorph.
I struck paydirt on the second graph, G?q|t[
, which has adjacency list representation:
N=8
0: 4 5 6 7 -1
1: 4 -1
2: 5 6 7 -1
3: 5 6 -1
4: 0 1 5 6 7 -1
5: 0 2 3 4 7 -1
6: 0 2 3 4 7 -1
7: 0 2 4 5 6 -1
I produced the obstruction:
planarity -s -p n8.m15.noK33.nonplanar.2.g6.AdjList.out.txt n8.m15.noK33.nonplanar.2.g6.AdjList.s.p.out.txt n8.m15.noK33.nonplanar.2.g6.AdjList.obstruction.txt
A K_5
homeomorph:
N=8
0: 4 7 5 6 -1
1: -1
2: -1
3: 6 5 -1
4: 0 5 7 6 -1
5: 3 7 4 0 -1
6: 7 3 4 0 -1
7: 4 5 6 0 -1
After removing the edge (0, 4)
from the original graph (thus "breaking up" the K_5
homeomorph), I was able to produce the following K_{3, 3}
homeomorph:
N=8
0: 5 7 6 -1
1: -1
2: 6 7 5 -1
3: -1
4: 7 6 5 -1
5: 0 2 4 -1
6: 4 2 0 -1
7: 2 4 0 -1
I double-checked, and G?q|t[
is reported as being K_{3, 3}
-free but is nonplanar, and indeed contains this K_{3, 3}
homeomorph.
TL;DR The new tool in #72, g6_generation_and_comparison_driver.py
, allows us to discover discrepancies in the results for planarity
when run on geng
.g6
, geng
canonical .g6
, makeg
.g6
, or makeg
canonical .g6
files. I discovered that for N = 6
, M = 13
, there's an example where the K_{3, 3}
search reports OK
for a graph when it shouldn't. This was not previously discovered because I was only comparing planarity results for geng
.g6
vs. makeg
.g6
files (here).
As an aside, I have performed these tests for N \in [6, 10]
, and it appears that only K_{3, 3}
search suffers from discrepancies in the results for the various .g6
files.
n6.planarity_discrepancies.txt
n7.planarity_discrepancies.txt
n8.planarity_discrepancies.txt
n9.planarity_discrepancies.txt
n10.planarity_discrepancies.txt
The fix for #105 (in PR #106) fixed the problem with both the 6-vertex and the 8-vertex graphs previously identified, so all graphs retest is warranted now to see whether there are any other invalid K_{3,3}
search results that we can find to be invalid either by edge deletion analysis of all graphs or by comparison of number of null results across the different ways of generating the graphs.
Once we get down to zero discrepancies on K_{3,3}
search, then we should retest K_{2,3}
search and K_4
search as well as retesting planarity and outerplanarity (to see any speed differences and to ensure that all the numbers reported haven't changed).
After making changes to test_table_generation_with_numInvalidOK.py
for #109 , I kicked off table regeneration; the PR for that issue will include the updated tables for N=5,10
. However, N=11
table regeneration will have to wait until #108 . The results so far are pretty darned promising, that invalid OKs are no longer being detected for the graph orders processed so far! See wbkboyer/edge-addition-planarity-suite:Issue109-ReAddEDAColumnsToTTG
Comparing results of current code to results from version 2.0 code, there seem to be 100 11-vertex 20-edge graph that are now reported to be
K_{3,3}
-free but didn't used to be. ForK_{3,3}
graphs, the old table reported 3,499,929 but now we report 3,500,029 (the numbers containingK_{3,3}
are similarly adjusted down by 100 in the current code). So, the code used to find aK_{3,3}
and verify the result in those 100 graphs, and now it doesn't.This will involve several steps:
OK
andNONEMBEDDABLE
results as a string of 0 and 1 values for all 11-vertex 20-edge graphs.K_{3,3}
-free) result in the new code that is not an OK in the results string, increment a counter. Also, if there are anyNONEMBEDDABLE
results in the new code that correlate with an OK in the results string, then increment a second counter. See whether the counter differences match the total difference of 100. (The total differences matches but the separate differences betweenOK
counts andNONEMBEDDABLE
counts is much higher than expected becausemakeg
andgeng
produce different graphs).makeg
orgeng
is erroneously producing any duplicate graphs. (Both were found to be generating unique graphs, just some different graphs).g6
files, namely one representing the output ofmakeg
and the other representing the output ofgeng
.makeg
versusgeng
on the smallest orders of graph (N= 6, 7, 8 etc.) to find the smallest order of graphs in which the number of OKs and NONEBMEDDABLES forK_{3,3}
search is different between themakeg
versusgeng
files.K_{3,3}
) to find the minimum M for which the number of OKs and NONEBMEDDABLES forK_{3,3}
search is different between themakeg
versusgeng
files. (That was discovered to be N=8, M=15, which had a difference of one OK versus NONEMBEDDABLE forK_{3,3}
search between themakeg
versusgeng
files).makeg
versusgeng
files for N=8, M=15).K_{3,3}
search indicates have aK_{3,3}
homeomorph (It was determined that this leaves 34 graphs thatK_{3,3}
search indicates areK_{3,3}
-free).K_{3,3}
-free because they are planar. (It was found that only 2 of the graphs that were reportedlyK_{3,3}
-free are also reported to be non-planar).K_5
in both cases).K_{3,3}
once theK_5
was planarized by the removal of an edge incident to one of the 5 degree 4 vertices. (It was determined that one of the graphs reported to beK_{3,3}
-free by theK_{3,3}
search did in fact have a subgraph homeomorphic toK_{3,3}
once a particular edge was removed to break up a subgraph homeomorphic toK_5
in the graph).makeg
versusgeng
, it turns out that most of the graphs generated by canonicalgeng
are different than those ofgeng
, and most of the canonicalmakeg
graphs are different than both thegeng
and canonicalgeng
files. So there are three sources of mostly different graphs for the samen
andm
values, which enables us to search for more error graphs that are potentially smaller than the n=8, m=15 graph already found to produce a problem for theK_{3,3}
search. The following tasks are intended to automate finding the smallest example possible of an error graph.geng
versus canonicalgeng
outputs. First piece of good news: There were no differences of algorithm behavior for any of the algorithms other than theK_{3.3}
search. Furthermore, forK_{3.3}
search, there was an output difference for n=6, m=13, for which there are only two graphs. For canonicalgeng
output, aK_{3.3}
homeomorph is found in both graphs, but in only one of the graphs in the non-canonicalgeng
output. We know that theOK
result on one of the non-canonicalgeng
graphs is in error because it is just an alternative adjacency matrix representation of one of the graphs in the canonicalgeng
output, both of which contain a subgraph homeomorphic toK_{3,3}
. We should be able to easily identify that 6-vertex 13-edge graph and then show aK_{3,3}
in it.K_{3,3}
analysis program to find aK_{3,3}
in the 6-vertex 13-edge graph from thegeng
output that is reported to beK_{3,3}
-free by theK_{3,3}
search implementation. Post a comment indicating the.g6
and adjacency list formats of the graph and the adjacency list formatted version of theK_{3,3}
it contains.