# Understanding of implies

**URL:** <https://discourse.julialang.org/t/understanding-of-implies/61978>\
**Category:** Optimization (Mathematical)\
**Created:** [May 28, 2021, 7:58am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978 "2021-05-28T07:58:52Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 28, 2021, 7:58am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/1 "2021-05-28T07:58:52Z")

</div>

Can someone explain to me how should I read this and which values can variables have?

```julia
model = Model()
@variable(model, x[1:2], Bin)
@constraint(model, x[1] <= x[2])

```

Should I read it like: this constraint will ensure that:  
x1 =1 and x2 = 1  
x1 = 0 and x2 = 1  
x1 = 0 and x2 = 0

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 28, 2021, 8:17am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/2 "2021-05-28T08:17:14Z")

</div>

Assuming 1 is true and 0 is false, you should read it as “if `x[1]` then `x[2]`” or as the contra-positive of this statement “if not `x[2]` then not `x[1]`.” The converse is not true though because `x[1]` being false tells us nothing about `x[2]` and `x[2]` being true tells us nothing about `x[1]`. I hope I didn’t add to the confusion!

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 28, 2021, 9:59am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/3 "2021-05-28T09:59:23Z")

</div>

Thanx. So this constraint will make sure that:

If X1 = 1 then X2 will be 1 too and if X1 = 0 we don’t care about X2 is that?

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 28, 2021, 10:25am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/4 "2021-05-28T10:25:22Z")

</div>

> [@sogrbilja](#):
>
> If X1 = 1 then X2 will be 1 too and if X1 = 0 we don’t care about X2 is that?

Pretty much. But you can also read it starting from x2. If x2 is 0 then x1 is 0, and if x2 is 1 we don’t care about x1.

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 28, 2021, 3:06pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/5 "2021-05-28T15:06:04Z")

</div>

Now, I have an model that I am trying to solve **AND understand.** The problem here is this constraint:

```julia
isCovered[i, j] <=
sum(
    isAntenna[r, c]
    for r in i-1:i+1, c in j-1:j+1
    if 1 <= r <= _ROWS && 1 <= c <= _COLUMNS
) 

```

Here isCovered can be 0 even if sum(isAntenna) \>= 1, but we don’t want that. We want to say if at least one antenna is around us we are covered, and if there is no antenna around us then we are not covered. Above constraint works, don’t get me wrong, I just can’t understand it and that is why I am back with this question again.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 28, 2021, 6:10pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/6 "2021-05-28T18:10:40Z")

</div>

Are you maximizing coverage in the objective or minimizing the number of antennas?

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 28, 2021, 6:19pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/7 "2021-05-28T18:19:40Z")

</div>

minimizing the number of antennas

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 28, 2021, 6:26pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/8 "2021-05-28T18:26:46Z")

</div>

can you post the full problem?

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 28, 2021, 7:05pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/9 "2021-05-28T19:05:47Z")

</div>

Here:

> [@Trying to solve a puzzle](https://discourse.julialang.org/t/trying-to-solve-a-puzzle/61515/16):
>
> The most important, what I failed to understand, is that isCovered is in the function of houses. I was thinking about the grid that one antenna can cover, but I should think about which houses antenna(s) can cover instead. Here is the model: using JuMP, Cbc, XLSX mat = XLSX.readdata("data/input.xlsx", "sheet1", "A1:J10") M = size(mat, 1) N = size(mat, 2) ratio = 0.7 houses = [] for i = 1 : M for j = 1 : N if mat[i,j] == 1 push!(houses, (i,j)) end end end model = Model(Cb…

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [May 28, 2021, 11:59pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/10 "2021-05-28T23:59:36Z")

</div>

Looking at the model, I am fairly confident that isCovered doesn’t mean what you think it means. If isCovered is 1, then the house is covered. If it is 0, then it may or may not be covered. Consider the case where the minimum coverage is 1 and you have 1 antenna covering 2 houses because it happens to be between them. isCovered can be 1 for either or both houses and that won’t affect the feasibility or optimality of the solution. If you want to find whether a house is truly covered or not as a post-processing, re-compute the sum of antennas in the neighborhood.

If you want to ensure the converse is satisfied, you need new constraints `isCovered[(i, j)] >= isAntenna[r, c]` for all `(r, c)` in the neighborhood of `(i, j)`.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [May 29, 2021, 1:42am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/11 "2021-05-29T01:42:09Z")

</div>

I’ll repeat my answer from: [Trying to solve a puzzle - #15 by odow](https://discourse.julialang.org/t/trying-to-solve-a-puzzle/61515/15)

```plaintext
using JuMP, Cbc
function main(; houses::Vector{Tuple{Int,Int}}, ratio::Float64)
    M = maximum(h[1] for h in houses)
    N = maximum(h[2] for h in houses)
    model = Model(Cbc.Optimizer)
    @variable(model, cell_tower[1:M, 1:N], Bin)
    @variable(model, is_covered[houses], Bin)
    @objective(model, Min, sum(cell_tower))
    stencil(i, j) = cell_tower[max(i-1,1):min(i+1,M), max(j-1,1):min(j+1,N)]
    @constraint(model, [h in houses], is_covered[h] <= sum(stencil(h[1], h[2])))
    @constraint(model, sum(is_covered) >= ratio * length(houses))
    optimize!(model)
    return value.(cell_tower)
end
houses = [(1, 9), (3, 2), (4, 4), (5, 6), (8, 9), (9, 1)]
main(houses, ratio = 0.7)

```

If the right-hand side of the `is_covered[h] <= ` constraint is 1, then `is_covered[h]` can be 0 or 1. But the next constraint means that there is a benefit to it taking the value 1. Of course, is the `ratio` constraint isn’t binding in an optimal solution, then there may be some houses `h` that are covered by the cell tower, but still have `is_covered[h] = 0`.

The typical way to fix this is to add a small term to the objective to encourage the “correct” solution

```julia
@objective(model, Min, sum(cell_tower) - 0.001 * sum(is_covered))

```

OR modeling is a large field, and more of an art than a science. There are some good online courses to learn more:

> **[Discrete Optimization](https://www.coursera.org/learn/discrete-optimization)**
>
> Offered by The University of Melbourne. Tired of solving Sudokus by hand? This class teaches you how to solve complex search problems with ... Enroll for free.

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 29, 2021, 6:39am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/12 "2021-05-29T06:39:58Z")

</div>

That was my thinking too, but Marc here said otherwise: [Trying to solve a puzzle - #11 by MarcMush](https://discourse.julialang.org/t/trying-to-solve-a-puzzle/61515/11)

Look, I am OK with this, as I see that there is no better way to do it.

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 29, 2021, 6:44am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/13 "2021-05-29T06:44:15Z")

</div>

Thank you again and I may take this course after all.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [May 29, 2021, 7:57am UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/14 "2021-05-29T07:57:19Z")

</div>

Can that course be done on JuMP? Looks like submissions are on python but it’s possible to call external binaries, does that mean JuliaCall might work?

---

<div class="post-metadata">

**Author:** ![sogrbilja](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sogrbilja/32/17521_2.png) [@sogrbilja](https://discourse.julialang.org/u/sogrbilja)\
**Post date:** [May 31, 2021, 12:41pm UTC](https://discourse.julialang.org/t/understanding-of-implies/61978/15 "2021-05-31T12:41:32Z")

</div>

It is based on Python, BUT you can call your Julia code and grab console results. I’ve started the course already and modify the submission file (submit.py) like this:

```julia
#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
from subprocess import Popen, PIPE

def solve_it(input_data):

    tmp_file_name = 'tmp.data'
    tmp_file = open(tmp_file_name, 'w')
    tmp_file.write(input_data)
    tmp_file.close()

    process = Popen(['julia', 'Solver.jl', tmp_file_name], stdout=PIPE, universal_newlines=True)
    (stdout, stderr) = process.communicate()

    os.remove(tmp_file_name)

    out = stdout.strip()

    arr = out.split("\n")
    while len(arr) > 2:
        arr.pop(0)
    out = "\n".join(arr)

    return out

import sys

if __name__ == ' __main__':
    if len(sys.argv) > 1:
        file_location = sys.argv[1].strip()
        with open(file_location, 'r') as input_data_file:
            input_data = input_data_file.read()
        print(solve_it(input_data))
    else:
        print('This test requires an input file. Please select one from the data directory. (i.e. python solver.py ./data/ks_4_0)')

```
