如何在Pyomo中创建OR约束?

时间:2020-10-21 22:02:26

标签: python optimization pyomo

我正在尝试在Pyomo中构建MIP模型,并且无法创建Or约束。 OR约束 r = { x1 ,..., xn }表示二进制结果变量<当且仅当任何操作数变量 x1 ,..., xn 等于1时,em> r 才应为1。可以在Pyomo中创建OR约束,所以我使用自己的代码

m = ConcreteModel()
m.r = Var(within=Binary)
m.x1 = Var(within=Binary)
m.x2 = Var(within=Binary)
m.or_constraint = Constraint(expr=m.r==min(sum(m.x1, m.x2), 1)

然后运行代码,并得到错误消息msg,应初始化变量m.x1和m.x2。我用1对其进行了初始化,发现m.or_constraint降级以强制mr等于1。换句话说,m.or_constraint仅使用m.x1和m.x2初始值来构建约束,并且在解决该问题时从未进行更新。 MIP问题。

我尝试在Pyomo中使用不同的表达式来创建此约束,例如在约束定义中调用规则函数。但是,每次我得到相同的结果。

您能指导我在Pyomo中创建OR约束吗?

2 个答案:

答案 0 :(得分:3)

关系

class Company(models.Model):
Online_Merchant = 'merch'
Education = 'edu'
Transportation = 'trans'
Hospitalism = 'hosp'
Healthcare = 'health'
Construction = 'const'
Blog = 'blog'
Finance = 'fin'
Media = 'media'
Government_Agency = 'agency'
Other = 'other'
Manufacturing = 'manufacturing'
sector = [
    (Online_Merchant, 'Online Merchant'),
    (Education, 'Education'),
    (Transportation, 'Transportation'),
    (Hospitalism, 'Hospitalism'),
    (Healthcare, 'Healthcare'),
    (Construction, 'Construction'),
    (Blog, 'Blog'),
    (Finance, 'Finance'),
    (Media, 'Media'),
    (Manufacturing, 'Manufacturing'),
    (Government_Agency, 'Government Agency'),
    (Other, 'Other')
]
Free = 'Free'
Premium = 'Premium'
package = [
    (Free, 'Free'),
    (Premium, 'Premium')
]
Abuja = 'Abuja'
Abia = 'Abia'
Adamawa = 'Adamawa'
Akwa_Ibom = 'Akwa Ibom'
Anambra = 'Anambra'
Bauchi = 'Bauchi'
Bayelsa = 'Bayelsa'
Benue = 'Benue'
Borno = 'Borno'
Cross_River = 'Cross River'
Delta = 'Delta'
Ebonyi = 'Ebonyi'
Edo = 'Edo'
Ekiti = 'Ekiti'
Enugu = 'Enugu'
Gombe = 'Gombe'
Imo = 'Imo'
Jigawa = 'Jigawa'
Kaduna = 'Kaduna'
Kano = 'Kano'
Katsina = 'Katsina'
Kebbi = 'Kebbi'
Kogi = 'Kogi'
Kwara = 'Kwara'
Lagos = 'Lagos'
Nasarawa = 'Nasarawa'
Niger = 'Niger'
Ogun = 'Ogun'
Ondo = 'Ondo'
Osun = 'Osun'
Oyo = 'Ibadan'
Plateau = 'Plateau'
Rivers = 'Rivers'
Sokoto = 'Sokoto'
Taraba = 'Taraba'
Yobe = 'Yobe'
Zamfara = 'Zamfara'

state = [
    (Abuja, 'Abuja'),
    (Abia, 'Abia'), 
    (Adamawa, 'Adamawa'),   
    (Akwa_Ibom, 'Akwa Ibom'),
    (Anambra, 'Anambra'),
    (Bauchi, 'Bauchi'),
    (Bayelsa, 'Bayelsa'),
    (Benue, 'Benue'),
    (Borno, 'Borno'),
    (Cross_River, 'Cross River'),
    (Delta, 'Delta'),
    (Ebonyi, 'Ebonyi'),
    (Edo, 'Edo'),
    (Ekiti, 'Ekiti'),
    (Enugu, 'Enugu'),
    (Gombe, 'Gombe'),
    (Imo, 'Imo'),
    (Jigawa, 'Jigawa'),
    (Kaduna, 'Kaduna'),
    (Kano, 'Kano'),
    (Katsina, 'Katsina'),
    (Kebbi, 'Kebbi'),
    (Kogi, 'Kogi'),
    (Kwara, 'Kwara'),
    (Lagos, 'Lagos'),
    (Nasarawa, 'Nasarawa'),
    (Niger, 'Niger'),
    (Ogun, 'Ogun'),
    (Ondo, 'Ondo'),
    (Osun, 'Osun'),
    (Oyo, 'Ibadan'),
    (Plateau, 'Plateau'),
    (Rivers, 'Rivers'),
    (Sokoto, 'Sokoto'),
    (Taraba, 'Taraba'),
    (Yobe, 'Yobe'),
    (Zamfara, 'Zamfara')
]

user = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='Company User')
company_sector = models.CharField(max_length=30, choices=sector, default=Online_Merchant)
company_name = models.CharField(max_length=100)
company_description = models.TextField()
company_logo = models.ImageField(upload_to='company_logos', blank=True, null=True)
company_state = models.CharField(max_length=30, choices=state, default=Lagos)
company_address = models.TextField(max_length=2000)
average_rating = models.IntegerField(default=0)
total_views = models.IntegerField(default=0)
company_website = models.CharField(max_length=500, blank=True, null=True)
company_email = models.EmailField(max_length=500, blank=True, null=True)
company_phone = models.CharField(max_length=500)
package_chosen = models.CharField(max_length=8, choices=package, default=Free)
featured = models.BooleanField(default=False)
advert = models.BooleanField(default=False)
premium = models.BooleanField(default=False)

def __str__(self):
    return self.company_name

可以表示为一组n + 1个线性不等式

{% extends 'base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% include "nav_bar.html" %}

{% block greeting %}                        
    <li class="nav-item" >
        <a class="nav-link font-weight-bold" href="{% url 'contact' %}"><i class="fas fa-envelope" style="font-size:20px; padding-right: 4px; color:#2196F3"></i>Contact Us</a>
    </li>
{% endblock greeting %}

{% block section %} 


    <section class="mt-2 bg-white mx-2">
        
        <div class="container-fluid border-0 text-justify">
            <div class="row">
                <span class="font-weight-bold px-2 py-1 mx-auto text-danger">...Created with<span class="h3"> &hearts;</span>... Because we understand that behind every review, there is a hearty experience...</span>
            </div>
            <div class="row mx-2">
                <div class="col-md-5 mb-2">
                    <div class="card" style="width: 23rem;">
                        <img src="{{request.user.userprofilecompany.profile_photo.url}}" class="card-img-top" alt="profile picture">
                        <div class="card-body">
                            <h5 class="card-title">Company Name: &nbsp; {{request.user.userprofilecompany.company_name}}</h5>
                            <p class="card-text">Username: {{request.user.username}} </br><span class="font-weight-sm">this is publicly visible</span></p>
                            <p class="card-text">Fullname: &nbsp;{{request.user.last_name}},&nbsp;{{request.user.first_name}}</p>
                            <p class="card-text">Designation: &nbsp; {{request.user.userprofilecompany.designation}}</p>
                            <p class="card-text">Email: &nbsp;{{request.user.email}}</p>
                            <p class="card-text">Phone:&nbsp;{{request.user.userprofilecompany.phone}}</p>
                            <p class="card-text">Location: &nbsp;{{request.user.userprofilecompany.location}}</p>
                            <p class="card-text">Package: &nbsp;{{request.user.userprofilecompany.package}}&nbsp;&nbsp;&nbsp;<a href="#" class="btn btn-primary btn-sm">Upgrade</a></p>

                            
                            <p class="card-text"></p>
                            <a href="{% url 'settings_company' %}" class="btn btn-outline-info">Go to Settings</a></br>
                            <p class="card-text"></p>
                            <a href="{% url 'logoutpage_company' %}" class="btn btn-outline-info">Logout</a></br>
                        </div>
                     </div>

                </div>
                
                {% for company in companies %}
                    {% if company.user == request.user %}
                
                <div class="col-md mb-2">
                    
                    <div class="row">
                        <div class="col-md mb-2">
                            
                            <div class="card text-center  mb-3"> 
                                <div class="card-header text-white bg-info">
                                    <h5 class="card-title">Total Reviews</h5>
                                </div>
                                <div class="card-body">
                                    <h3 class="card-title"></h3>
                                </div>
                                <div class="card-body">
                                    <h3 class="card-title"></h3>
                                </div>
                                <div class="card-body">
                                    <h3 class="card-title">{{ company.review_set.all.count }}</h3>
                                </div>
                                
                                <div class="card-body">
                                    <h3 class="card-title"></h3>
                                </div>
                                
                                <button class="btn btn-info font-weight-bold btn-sm" id="tm-reviews">View Reviews and Responses</button>
                            </div>

                            
                        </div>
                        
                        <div class="col-md mb-2">
                            
                                <div class="card  mb-3" > 
                                    <div class="card-header text-center text-white bg-info">
                                        <h5 class="card-title ">Statistics</h5>
                                    </div>
                                    
                                    <div class="py-2 font-weight-bold px-2">
                                        <p class="card-text">Average Rating:&nbsp; | &nbsp; <i id="tm-average_rating">{{company.average_rating}}</i><i>/5</i> </p>
                                        <p class="card-text">Remarks: &nbsp; | &nbsp;<i id="tm-remarks" class=""></i></p>
                                        <p class="card-text">Total Likes: &nbsp; | &nbsp; like count number</p>
                                        <p class="card-text">Total Dislikes: &nbsp; | &nbsp; dislike count number</p>
                                        <p class="card-text">Average Rating:&nbsp; | &nbsp; 4/5 </p>
                                        <p class="card-text">Remarks: &nbsp; | &nbsp;Satisfactory</p>
                                        <p class="card-text">Total Views: &nbsp; | &nbsp; 10</p>
                                        
                                        <p class="card-text"><h6 class=" font-weight-bold">Claimed Company:&nbsp; <span class= "text-primary"><a class="text-decoration-none" href="{% url 'detail' company.id %}" target="_blank"> {{company.company_name}} </a> </span> </h5></p>
                                        
                                    </div>
                                    
                                    <button class="btn btn-info font-weight-bold btn-sm" id="tm-reviews">Click to Get Noticed</button>
                                    
                                </div>                      

                        </div>
                        
                    </div>
                    
                    <div class="row" id="tm-display-reviews">
                            <div class="col-md mb-2">
                            
                                <div style="font-size: small;" class="card text-center  mb-3"> 
                                    <div class="card-header text-white bg-info">
                                        <h5 class="card-title">Details</h5>
                                    </div>
                                    
                                    <div class="card-body">
                                        {% for review in company.review_set.all %}
                                        <div  class=" py-2">
                                            <p class="card-text ">Name: &nbsp; {{review.user | capfirst }} Rating: {{review.rating}}/5 &nbsp; | &nbsp; Date added: <span class="text-danger"> {{ review.date_added }}</span></p>
                                            <p class="card-text">  Review: &nbsp; {{review.review_text}} </p>
                                        
                                        
                                        <!-- check to see if there is a reponse under this review to know whether
                                         to show the button -->
                                        {% for response in review.response_set.all %} 
                                            {% empty %}                                            
                                        <p class="card-text"><a href="{% url 'response' review.id %}"><button id="tm-respond" class="btn btn-outline-primary font-weight-bold btn-sm">respond to this review</button></a></p>
                                            
                                        {% endfor %}
                                       
                                        {% for response in responses%}
                                        {% if response.review == review %}
                                        <p class="card-text bg-light font-italic">{{response.review.company | capfirst }} responded: {{response}} on: {{response.date_added}}</p>
                                        <hr>
                                        {% endif %}
                                        {% endfor %}
                                        
                                        {% endfor %}
                                        
                                        </div>
                                                                                                                   
                                    
                                    
                                    
                                    </div>
                                </div>
                                
                            </div>
                            
                    
                    </div>
                    
                </div>
                    
                    {% endif %}
                    
                {% endfor %}
               
                
                <div class="col-md mb-2">
                    <!-- The problem is here. It seems to rund the code over and over again-->
                      {% for company in companies %}
                      {% if company.user != request.user%}
                    
                    <div class="row">
                        <div class="col-md mb-2">
                            
                            <div class="card text-center  mb-3"> 
                                <div class="card-header text-white bg-info">
                                    <h5 class="card-title">Total Reviews</h5>
                                </div>
                                <div class="card-body">
                                    <p class="card-text"> You have not claimed a company yet.</p>
                                    <p class="card-text"> You need to claim a company to view its statistis here.</p>
                                    <p class="card-text"> You need to have your company listed to claim it.</p>
                                    <p class="card-text"> If your company is already listed on our site, kindly email us on:</p>
                                    <p class="card-text"> <a href="mailto:info@crediblereviews.ng">info@crediblereviews.ng</a></p>
                                </div>
                                
                                
                                
                                
                               
                            </div>

                            
                        </div>
                        
                        <div class="col-md mb-2">
                            
                                <div class="card  mb-3" > 
                                    <div class="card-header text-center text-white bg-info">
                                        <h5 class="card-title ">Statistics</h5>
                                    </div>
                                    
                                    <div class="py-2 font-weight-bold px-2">
                                        <p class="card-text">Average Rating:&nbsp; | &nbsp; <i id="tm-average_rating">{{infor}}</i> </p>
                                        <p class="card-text">Remarks: &nbsp; | &nbsp;<i id="tm-remarks" class="">{{infor}}</i></p>
                                        <p class="card-text">Total Likes: &nbsp; | &nbsp; {{infor}}</p>
                                        <p class="card-text">Total Dislikes: &nbsp; | &nbsp; {{infor}}</p>
                                        <p class="card-text">Average Rating:&nbsp; | &nbsp; {{infor}} </p>
                                        <p class="card-text">Remarks: &nbsp; | &nbsp;{{infor}}</p>
                                        <p class="card-text">Total Views: &nbsp; | &nbsp; {{infor}}</p>
                                        
                                        <p class="card-text"><h6 class=" text-warning font-weight-bold">{{info}}:&nbsp; <span style="font-size: small;" class= "text-info"> Email us to claim a company </span> </h5></p>
                                        
                                    </div>
                                    
                                    <button class="btn btn-info font-weight-bold btn-sm" id="tm-reviews">Click to Get Noticed</button>
                                    
                                </div>                      

                        </div>
                        
                    </div>
                    {% endif %}
                    {% endfor %}
                    <!---->
                    
                </div>
                
               
               
                
            </div>
        </div>
        
    </section>
    {% endblock section %}
    {% block article %}
    
    {% endblock article %}

也可以将其写为两个约束:

  y = x(1) or x(2) or ... or x(n)   ( same as y = max{x(i)} )
  y, x(i) ∈ {0,1}                   ( all binary variables  )    

但是,第一个版本更加严格。那是我通常使用的那个。

注意:第一个版本太紧,我们甚至可以放松y以使其在0和1之间连续。这是否对求解器有利,还需要进行一些实验。对于第二个版本,要求y为二进制。

答案 1 :(得分:0)

实际上,还有另一种方法通过将Pyomo与Binary一起使用来创建“或”语句(仅用于两个约束)。

Obj: Min(OF)=f(x)
s.t.  x<=A or x<=B

我们可以添加一个二进制数字(Y)来形成此模型。M是一个足够大的数字(100000)。

   Obj: Min(OF)=f(x,y)
   s.t. X<= A+M*y
        X<=B+(1-Y)M
        Y=0,1