The following SET and READ statements declare the ARCS index set and then populate it by reading the arc_data
data set:
proc optmodel; set <num,num> ARCS; read data arc_data into ARCS=[i j];
Each arc corresponds to a connection from one NOR gate to another in Figure 12.2, and the following SET statement declares and populates the index set GATES by taking a union over ARCS, as in previous examples:
set GATES = union {<i,j> in ARCS} {i,j}; var UseGate {GATES} binary; min NumGatesUsed = sum {gate in GATES} UseGate[gate]; var AssignAGate {GATES} binary; var AssignBGate {GATES} binary;
The following CON statements declare the constraints that if input or is assigned to a gate, that gate must be used:
con AssignAGate_def {gate in GATES}: AssignAGate[gate] <= UseGate[gate]; con AssignBGate_def {gate in GATES}: AssignBGate[gate] <= UseGate[gate];
The following CON statement declares the constraint that each gate has at most two inputs:
con At_most_two_inputs {gate in GATES}: sum {<pred,(gate)> in ARCS} UseGate[pred] + AssignAGate[gate] + AssignBGate[gate] <= 2;
The following statements declare the ROWS index set and several parameters and read the truth_data
data set that contains the target output:
set ROWS; num inputA {ROWS}; num inputB {ROWS}; num target_output {ROWS}; read data truth_data into ROWS=[_N_] inputA=A inputB=B target_output=output;
The following VAR and FIX statements declare the Output
variable and fix the output of Gate 1 to the desired values specified in target_output:
var Output {GATES, ROWS} binary; for {row in ROWS} fix Output[1,row] = target_output[row];
The following CON statement declares the constraint that if any row has a positive Output
, that gate must be used.
con Output_link {gate in GATES, row in ROWS}: Output[gate,row] <= UseGate[gate];
The following CON statements declare the constraints that define each NOR gate:
/* if inputA[row] = 1 and AssignAGate[gate] = 1, then Output[gate,row] = 0 */ con NOR_def1 {gate in GATES, row in ROWS}: inputA[row] * AssignAGate[gate] <= 1 - Output[gate,row]; /* if inputB[row] = 1 and AssignBGate[gate] = 1, then Output[gate,row] = 0 */ con NOR_def2 {gate in GATES, row in ROWS}: inputB[row] * AssignBGate[gate] <= 1 - Output[gate,row]; /* if Output[pred,row] = 1, then Output[gate,row] = 0 */ con NOR_def3 {<pred,gate> in ARCS, row in ROWS}: Output[pred,row] <= 1 - Output[gate,row]; /* if UseGate[gate] = 1 and Output[gate,row] = 0, then (inputA[row] = 1 and AssignAGate[gate] = 1) or (inputB[row] = 1 and AssignBGate[gate] = 1) or sum {<pred,(gate)> in ARCS} Output[pred,row] >= 1 */ con NOR_def4 {gate in GATES, row in ROWS}: inputA[row] * AssignAGate[gate] + inputB[row] * AssignBGate[gate] + sum {<pred,(gate)> in ARCS} Output[pred,row] >= UseGate[gate] - Output[gate,row]; solve; print UseGate AssignAGate AssignBGate; print Output; create data sol_data1 from [gate] UseGate AssignAGate AssignBGate; create data sol_data2 from [gate row] Output; quit;
Figure 12.3 shows the output from the mixed integer linear programming solver. In this case, five gates are used in the optimal solution.
Figure 12.3: Output from Mixed Integer Linear Programming Solver
Problem Summary | |
---|---|
Objective Sense | Minimization |
Objective Function | NumGatesUsed |
Objective Type | Linear |
Number of Variables | 49 |
Bounded Above | 0 |
Bounded Below | 0 |
Bounded Below and Above | 45 |
Free | 0 |
Fixed | 4 |
Binary | 49 |
Integer | 0 |
Number of Constraints | 157 |
Linear LE (<=) | 129 |
Linear EQ (=) | 0 |
Linear GE (>=) | 28 |
Linear Range | 0 |
Constraint Coefficients | 344 |
Performance Information | |
---|---|
Execution Mode | Single-Machine |
Number of Threads | 1 |
Solution Summary | |
---|---|
Solver | MILP |
Algorithm | Branch and Cut |
Objective Function | NumGatesUsed |
Solution Status | Optimal |
Objective Value | 5 |
Relative Gap | 0 |
Absolute Gap | 0 |
Primal Infeasibility | 0 |
Bound Infeasibility | 0 |
Integer Infeasibility | 0 |
Best Bound | 5 |
Nodes | 1 |
Iterations | 72 |
Presolve Time | 0.00 |
Solution Time | 0.00 |
[1] | UseGate | AssignAGate | AssignBGate |
---|---|---|---|
1 | 1 | 0 | 0 |
2 | 1 | 1 | 1 |
3 | 1 | 0 | 0 |
4 | 0 | 0 | 0 |
5 | 0 | 0 | 0 |
6 | 1 | 0 | 1 |
7 | 1 | 1 | 0 |
Output | ||||
---|---|---|---|---|
1 | 2 | 3 | 4 | |
1 | 0 | 1 | 1 | 0 |
2 | 1 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 1 |
4 | 0 | 0 | 0 | 0 |
5 | 0 | 0 | 0 | 0 |
6 | 1 | 0 | 1 | 0 |
7 | 1 | 1 | 0 | 0 |