布林約束傳播蘊含圖繪製-2024-6-21

海阔凭鱼跃越發表於2024-06-21

1. gml格式蘊含圖格式的獲取

(1)在主函式main的程式碼中增加設定外部輸出檔案通道——開啟、結束前、關閉三個函式的呼叫。

參考所涉及的程式碼:

  1         parseOptions(argc, argv, true);
  2         
  3         SimpSolver  S;
  4         double      initial_time = cpuTime();
  5 
  6         S.parsing = 1;
  7         if (!pre) S.eliminate(true);
  8 
  9         S.verbosity = verb;
 10         
 11         solver = &S;
 12         // Use signal handlers that forcibly quit until the solver will be able to respond to
 13         // interrupts:
 14         sigTerm(SIGINT_exit);
 15 
 16         // Try to set resource limits:
 17         if (cpu_lim != 0) limitTime(cpu_lim);
 18         if (mem_lim != 0) limitMemory(mem_lim);
 19 
 20         if (argc == 1)
 21             printf("c Reading from standard input... Use '--help' for help.\n");
 22 
 23         gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
 24         if (in == NULL)
 25             printf("c ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
 26         
 27         if (S.verbosity > 0){
 28             printf("c ======================[ Problem Statistics ]=======================\n");
 29             printf("c |                                                                  |\n"); }
 30         
 31         char* proofLog = NULL;
 32         if (argc >= 4) proofLog = argv[3]; 
 33         if(proofLog){
 34             printf("c |  ProofLogFile has been ready!\n");
 35             if(!S.openProofLogFile((const char *)proofLog)){
 36                 printf("c ERROR! Could not open proof log file: %s\n", (const char *)proofLog);
 37                 exit(1);
 38             }
 39         }
 40         parse_DIMACS(in, S, (bool)strictp);
 41         gzclose(in);
 42         FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
 43 
 44         if (S.verbosity > 0){
 45             printf("c |  Number of variables:  %12d        |\n", S.nVars());
 46             printf("c |  Number of clauses:    %12d        |\n", S.nClauses()); }
 47         
 48         double parsed_time = cpuTime();
 49         if (S.verbosity > 0)
 50             printf("c |  Parse time:           %12.2f s    |\n", parsed_time - initial_time);
 51 
 52         // Change to signal-handlers that will only notify the solver and allow it to terminate
 53         // voluntarily:
 54         sigTerm(SIGINT_interrupt);
 55 
 56         S.parsing = 0;
 57         S.eliminate(true);
 58         double simplified_time = cpuTime();
 59         if (S.verbosity > 0){
 60             printf("c |  Simplification time:  %12.2f s     |\n", simplified_time - parsed_time);
 61             printf("c |                                     |\n"); }
 62 
 63         if (!S.okay()){
 64             S.finalizeProofLog(true);
 65             if (res != NULL) fprintf(res, "s UNSATISFIABLE\n"), fclose(res);
 66             if (S.verbosity > 0){
 67                 printf("c =================================================================\n");
 68                 printf("c Solved by simplification\n");
 69                 S.printStats();
 70                 printf("c \n"); }
 71             printf("s UNSATISFIABLE\n");
 72             exit(20);
 73         }
 74 
 75         lbool ret = l_Undef;
 76 
 77         if (solve){
 78             vec<Lit> dummy;
 79             ret = S.solveLimited(dummy);
 80         }else if (S.verbosity > 0)
 81             printf("c =====================================================================\n");
 82 
 83         if (dimacs && ret == l_Undef)
 84             S.toDimacs((const char*)dimacs);
 85 
 86         if (S.verbosity > 0){
 87             S.printStats();
 88             printf("c \n"); }
 89         printf(ret == l_True ? "s SATISFIABLE\n" :
ret == l_False ? "s UNSATISFIABLE\n" : "s UNKNOWN\n"); 90 if (ret == l_True && model){ 91 std::stringstream s; 92 for (int i = 0; i < S.nVars(); i++) 93 s << ((S.model[i]==l_True)?i+1:-i-1) << " "; 94 printf("v %s0\n", s.str().c_str()); 95 } 96 97 S.finalizeProofLog(ret == l_False); 98 99 if (res != NULL){ 100 if (ret == l_True){ 101 fprintf(res, "s SATISFIABLE\n"); 102 for (int i = 0; i < S.nVars(); i++) 103 if (S.model[i] != l_Undef) 104 fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1); 105 fprintf(res, " 0\n"); 106 }else if (ret == l_False) 107 fprintf(res, "s UNSATISFIABLE\n"); 108 else 109 fprintf(res, "s UNKNOWN\n"); 110 fclose(res); 111 }

//紅色為原有程式碼,對應求解結果檔案;紫紅色對應第四個引數輸入檔案(如可輸入為:logNetworkx.gml).

 1 //Solver.cc
 2 
 3 bool Solver::openProofLogFile(const char *path)
 4 {
 5     if(proofLogFile) return false;
 6 
 7     proofLogFile = fopen(path, "wb");
 8     if(proofLogFile == 0) return false;
 9 
10     return true;
11 }
12 
13 bool Solver::finalizeProofLog(const bool addEmpty)
14 {
15     if(!proofLogFile) return true;
16 
17     //if(addEmpty) fprintf(proofLogFile, "0\n");
18 
19     if(fclose(proofLogFile) != 0) return false;
20     return true;
21 }
22 
23 
24 inline void   Solver::extendRestartNetworkxLog() 
25 {    
26     if(!proofLogFile) return;
27     int curClauseId = 0;
28 
29     std::stringstream s;
30 
31     s << "graph [";
32     s << "\n  directed " << 1;
33     s << "\n  name \"period_" << starts <<"\"";
34     s << "\n  restart " << starts;
35 
36     //目前trail序列中的文字
37     double coefLen = 1.0;
38     for (int i = 0; i < int(coefLen*trail.size()); i++)
39     {
40         assert (assigns[var(i)] != l_Undef);
41     Lit lit = trail[i];
42     Var v = var(lit);
43     int cur_v = (v + 1);
44     int cur_positive = sign(lit)?0:1;
45     int cur_negative = sign(lit)?1:0;
46     int cur_level = level(v);
47 
48     s << "\n  node [";
49         s << "\n   id " << cur_v;
50         s << "\n   label \"$x_" << cur_v <<"$\"";
51     s << "\n   color \"green\"";
52         s << "\n   positive " << cur_positive;
53     s << "\n   negative " << cur_negative;
54     s << "\n   level " << cur_level;
55     s << "\n  ]\n";    
56 
57     if ( reason(v) != CRef_Undef)
58     {
59         curClauseId ++;
60         Clause& c = ca[reason(v)];
61         for (int j = 0; j < c.size(); j++)
62         {
63             if (c[j] == lit) 
64                 continue;
65         int cur_source = var(c[j]) + 1;
66         int cur_target = cur_v;
67 
68         s << "\n  edge [";        
69         s << "\n   source " << cur_source;
70         s << "\n   target " << cur_target;
71         s << "\n   weight " << 1;
72         s << "\n   clause \"$c_" << curClauseId <<"$\"";
73         s << "\n  ]\n";
74         }
75     }
76         
77     }
78     s << "]\n";
79    
80     fprintf(proofLogFile, "%s\n", s.str().c_str());
81 }

2. 可能會用到的轉換

引用自CSDN網站中博主“兔子愛讀書”的博文。 網址:https://bluebird.blog.csdn.net/article/details/103570320

在此非常感謝原作者。

3. 在python中執行自定義的程式,其中包含讀入logNetworkx.gml檔案的語句。示例:

1 import networkx as nx
2 import matplotlib.pyplot as plt
3 
4 #讀入外部檔案
5 #--------------------------------------------------------------
6 H2 = nx.read_gml(".\data_networkxBCP\logNetworkx.gml")
7 
8 nx.draw(H2, with_labels=True)
9 plt.show()

執行結果:有向圖節點排列布局需要自行設定。此處預設佈局不能體現蘊含關係。

//另一個例子

 1 import networkx as nx
 2 import matplotlib.pyplot as plt
 3 
 4 #讀入外部檔案
 5 #--------------------------------------------------------------
 6 H2 = nx.read_gml(".\data_networkxBCP\logNetworkx.gml")
 7 
 8 #nx.draw(H2, with_labels=True)
 9 #plt.show()
10 
11 ##nx.draw(H2, with_labels=True, node_color='skyblue',
12 ##        edge_color='black', node_size=800, font_size=20)
13 ##plt.show()
14 
15 
16 pos = nx.spring_layout(H2) # 節點的佈局為spring型
17 plt.figure(figsize = (12, 6)) # 圖片大小
18 
19 nodes = list(H2.nodes())
20 vn = len(nodes)
21 nodes1 = [nodes[i] for i in range(0, (int)(vn / 2))]
22 nodes2 = [nodes[i] for i in range((int)(vn / 2), vn)]
23 nx.draw_networkx_nodes(H2, pos = pos, nodelist=nodes1, node_color='r', node_size=140, label='True')
24 nx.draw_networkx_nodes(H2, pos = pos, nodelist=nodes2, node_color='y', node_size=80)
25 
26 edges = list(H2.edges())
27 en = len(edges)
28 edges1 = [edges[i] for i in range(0, (int)(en / 2))]
29 edges2 = [edges[i] for i in range((int)(vn / 2), en)]
30 nx.draw_networkx_edges(H2, pos = pos, edgelist=edges1, style='dashed', edge_color='g', width=1.0 , alpha=0.6)
31 nx.draw_networkx_edges(H2, pos = pos, edgelist=edges2, style='dashed', edge_color='b', width=1.0 )
32 
33 plt.show()

執行結果:

4. 自定義設定pos,設定節點的顯示位置

示例:

import networkx as nx
import matplotlib.pyplot as plt

G = nx.DiGraph([(0, 3), (1, 3), (2, 4), (3, 5), (3, 6), (4, 6), (5, 6)])

# group nodes by column
left_nodes = [0, 1, 2]
middle_nodes = [3, 4]
right_nodes = [5, 6]

# set the position according to column (x-coord)
pos = {n: (0, i) for i, n in enumerate(left_nodes)}
pos.update({n: (1, i + 0.5) for i, n in enumerate(middle_nodes)})
pos.update({n: (2, i + 0.5) for i, n in enumerate(right_nodes)})

options = {
    "font_size": 36,
    "node_size": 3000,
    "node_color": "white",
    "edgecolors": "black",
    "linewidths": 5,
    "width": 5,
}

nx.draw_networkx(G, pos, **options)

# Set margins for the axes so that nodes aren't clipped
ax = plt.gca()

執行結果:

相關文章